summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2004-05-03 21:23:52 +0000
committerHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2004-05-03 21:23:52 +0000
commit7832e7eeac24915539309de4de18cfc0978b764b (patch)
treeba2730e5eee33452ac32d8f65bae74e36ef9631f
parent4ec19db8d4512cc7fd5723f3d281ce48af66c974 (diff)
KNF. ok ho@
-rw-r--r--sbin/isakmpd/exchange.c2813
-rw-r--r--sbin/isakmpd/exchange.h58
2 files changed, 1376 insertions, 1495 deletions
diff --git a/sbin/isakmpd/exchange.c b/sbin/isakmpd/exchange.c
index a68bb3fbd84..999a9b67777 100644
--- a/sbin/isakmpd/exchange.c
+++ b/sbin/isakmpd/exchange.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: exchange.c,v 1.92 2004/03/31 10:54:46 ho Exp $ */
-/* $EOM: exchange.c,v 1.143 2000/12/04 00:02:25 angelos Exp $ */
+/* $OpenBSD: exchange.c,v 1.93 2004/05/03 21:23:51 hshoexer Exp $ */
+/* $EOM: exchange.c,v 1.143 2000/12/04 00:02:25 angelos Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
@@ -73,126 +73,126 @@
*/
#define MAX_BUCKET_BITS 16
-static void exchange_dump (char *, struct exchange *);
-static void exchange_free_aux (void *);
-static struct exchange *exchange_lookup_active (char *, int);
+static void exchange_dump(char *, struct exchange *);
+static void exchange_free_aux(void *);
+static struct exchange *exchange_lookup_active(char *, int);
#if 0
-static void exchange_resize (void);
+static void exchange_resize(void);
#endif
-static LIST_HEAD (exchange_list, exchange) *exchange_tab;
+static
+LIST_HEAD(exchange_list, exchange) *exchange_tab;
/* Works both as a maximum index and a mask. */
-static int bucket_mask;
+static int bucket_mask;
/*
* Validation scripts used to test messages for correct content of
* payloads depending on the exchange type.
*/
int16_t script_base[] = {
- ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
- ISAKMP_PAYLOAD_NONCE,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
- ISAKMP_PAYLOAD_NONCE,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_KEY_EXCH, /* Initiator -> responder. */
- ISAKMP_PAYLOAD_ID,
- EXCHANGE_SCRIPT_AUTH,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_KEY_EXCH, /* Responder -> initiator. */
- ISAKMP_PAYLOAD_ID,
- EXCHANGE_SCRIPT_AUTH,
- EXCHANGE_SCRIPT_END
-};
+ ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
+ ISAKMP_PAYLOAD_NONCE,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
+ ISAKMP_PAYLOAD_NONCE,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_KEY_EXCH, /* Initiator -> responder. */
+ ISAKMP_PAYLOAD_ID,
+ EXCHANGE_SCRIPT_AUTH,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_KEY_EXCH, /* Responder -> initiator. */
+ ISAKMP_PAYLOAD_ID,
+ EXCHANGE_SCRIPT_AUTH,
+ EXCHANGE_SCRIPT_END
+ };
int16_t script_identity_protection[] = {
- ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_KEY_EXCH, /* Initiator -> responder. */
- ISAKMP_PAYLOAD_NONCE,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_KEY_EXCH, /* Responder -> initiator. */
- ISAKMP_PAYLOAD_NONCE,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_ID, /* Initiator -> responder. */
- EXCHANGE_SCRIPT_AUTH,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_ID, /* Responder -> initiator. */
- EXCHANGE_SCRIPT_AUTH,
- EXCHANGE_SCRIPT_END
-};
+ ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_KEY_EXCH, /* Initiator -> responder. */
+ ISAKMP_PAYLOAD_NONCE,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_KEY_EXCH, /* Responder -> initiator. */
+ ISAKMP_PAYLOAD_NONCE,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_ID, /* Initiator -> responder. */
+ EXCHANGE_SCRIPT_AUTH,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_ID, /* Responder -> initiator. */
+ EXCHANGE_SCRIPT_AUTH,
+ EXCHANGE_SCRIPT_END
+ };
int16_t script_authentication_only[] = {
- ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
- ISAKMP_PAYLOAD_NONCE,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
- ISAKMP_PAYLOAD_NONCE,
- ISAKMP_PAYLOAD_ID,
- EXCHANGE_SCRIPT_AUTH,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_ID, /* Initiator -> responder. */
- EXCHANGE_SCRIPT_AUTH,
- EXCHANGE_SCRIPT_END
-};
+ ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
+ ISAKMP_PAYLOAD_NONCE,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
+ ISAKMP_PAYLOAD_NONCE,
+ ISAKMP_PAYLOAD_ID,
+ EXCHANGE_SCRIPT_AUTH,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_ID, /* Initiator -> responder. */
+ EXCHANGE_SCRIPT_AUTH,
+ EXCHANGE_SCRIPT_END
+ };
#ifdef USE_AGGRESSIVE
int16_t script_aggressive[] = {
- ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
- ISAKMP_PAYLOAD_KEY_EXCH,
- ISAKMP_PAYLOAD_NONCE,
- ISAKMP_PAYLOAD_ID,
- EXCHANGE_SCRIPT_SWITCH,
- ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
- ISAKMP_PAYLOAD_KEY_EXCH,
- ISAKMP_PAYLOAD_NONCE,
- ISAKMP_PAYLOAD_ID,
- EXCHANGE_SCRIPT_AUTH,
- EXCHANGE_SCRIPT_SWITCH,
- EXCHANGE_SCRIPT_AUTH, /* Initiator -> responder. */
- EXCHANGE_SCRIPT_END
-};
-#endif /* USE_AGGRESSIVE */
+ ISAKMP_PAYLOAD_SA, /* Initiator -> responder. */
+ ISAKMP_PAYLOAD_KEY_EXCH,
+ ISAKMP_PAYLOAD_NONCE,
+ ISAKMP_PAYLOAD_ID,
+ EXCHANGE_SCRIPT_SWITCH,
+ ISAKMP_PAYLOAD_SA, /* Responder -> initiator. */
+ ISAKMP_PAYLOAD_KEY_EXCH,
+ ISAKMP_PAYLOAD_NONCE,
+ ISAKMP_PAYLOAD_ID,
+ EXCHANGE_SCRIPT_AUTH,
+ EXCHANGE_SCRIPT_SWITCH,
+ EXCHANGE_SCRIPT_AUTH, /* Initiator -> responder. */
+ EXCHANGE_SCRIPT_END
+ };
+#endif /* USE_AGGRESSIVE */
int16_t script_informational[] = {
- EXCHANGE_SCRIPT_INFO, /* Initiator -> responder. */
- EXCHANGE_SCRIPT_END
-};
+ EXCHANGE_SCRIPT_INFO, /* Initiator -> responder. */
+ EXCHANGE_SCRIPT_END
+ };
/*
* Check what exchange SA is negotiated with and return a suitable validation
* script.
*/
int16_t *
-exchange_script (struct exchange *exchange)
+exchange_script(struct exchange *exchange)
{
- switch (exchange->type)
- {
- case ISAKMP_EXCH_BASE:
- return script_base;
- case ISAKMP_EXCH_ID_PROT:
- return script_identity_protection;
- case ISAKMP_EXCH_AUTH_ONLY:
- return script_authentication_only;
+ switch (exchange->type) {
+ case ISAKMP_EXCH_BASE:
+ return script_base;
+ case ISAKMP_EXCH_ID_PROT:
+ return script_identity_protection;
+ case ISAKMP_EXCH_AUTH_ONLY:
+ return script_authentication_only;
#ifdef USE_AGGRESSIVE
- case ISAKMP_EXCH_AGGRESSIVE:
- return script_aggressive;
+ case ISAKMP_EXCH_AGGRESSIVE:
+ return script_aggressive;
#endif
- case ISAKMP_EXCH_INFO:
- return script_informational;
+ case ISAKMP_EXCH_INFO:
+ return script_informational;
#ifdef USE_ISAKMP_CFG
- case ISAKMP_EXCH_TRANSACTION:
- return script_transaction;
+ case ISAKMP_EXCH_TRANSACTION:
+ return script_transaction;
#endif
- default:
- if (exchange->type >= ISAKMP_EXCH_DOI_MIN
- && exchange->type <= ISAKMP_EXCH_DOI_MAX)
- return exchange->doi->exchange_script (exchange->type);
- }
- return 0;
+ default:
+ if (exchange->type >= ISAKMP_EXCH_DOI_MIN
+ && exchange->type <= ISAKMP_EXCH_DOI_MAX)
+ return exchange->doi->exchange_script(exchange->type);
+ }
+ return 0;
}
/*
@@ -201,45 +201,43 @@ exchange_script (struct exchange *exchange)
* 0 if it succeeds and the script is not finished and 1 if it's ready.
*/
static int
-exchange_validate (struct message *msg)
+exchange_validate(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- int16_t *pc = exchange->exch_pc;
-
- while (*pc != EXCHANGE_SCRIPT_END && *pc != EXCHANGE_SCRIPT_SWITCH)
- {
- LOG_DBG ((LOG_EXCHANGE, 90,
- "exchange_validate: checking for required %s",
- *pc >= ISAKMP_PAYLOAD_NONE
- ? constant_name (isakmp_payload_cst, *pc)
- : constant_name (exchange_script_cst, *pc)));
-
- /* Check for existence of the required payloads. */
- if ((*pc > 0 && !TAILQ_FIRST (&msg->payload[*pc]))
- || (*pc == EXCHANGE_SCRIPT_AUTH
- && !TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH])
- && !TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SIG]))
- || (*pc == EXCHANGE_SCRIPT_INFO
- && ((!TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_NOTIFY])
- && !TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_DELETE]))
- || (TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_DELETE])
- && !TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH])))))
- {
- /* Missing payload. */
- LOG_DBG ((LOG_MESSAGE, 70,
- "exchange_validate: msg %p requires missing %s", msg,
+ struct exchange *exchange = msg->exchange;
+ int16_t *pc = exchange->exch_pc;
+
+ while (*pc != EXCHANGE_SCRIPT_END && *pc != EXCHANGE_SCRIPT_SWITCH) {
+ LOG_DBG((LOG_EXCHANGE, 90,
+ "exchange_validate: checking for required %s",
*pc >= ISAKMP_PAYLOAD_NONE
- ? constant_name (isakmp_payload_cst, *pc)
- : constant_name (exchange_script_cst, *pc)));
- return -1;
+ ? constant_name(isakmp_payload_cst, *pc)
+ : constant_name(exchange_script_cst, *pc)));
+
+ /* Check for existence of the required payloads. */
+ if ((*pc > 0 && !TAILQ_FIRST(&msg->payload[*pc]))
+ || (*pc == EXCHANGE_SCRIPT_AUTH
+ && !TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH])
+ && !TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SIG]))
+ || (*pc == EXCHANGE_SCRIPT_INFO
+ && ((!TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NOTIFY])
+ && !TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_DELETE]))
+ || (TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_DELETE])
+ && !TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]))))) {
+ /* Missing payload. */
+ LOG_DBG((LOG_MESSAGE, 70,
+ "exchange_validate: msg %p requires missing %s",
+ msg, *pc >= ISAKMP_PAYLOAD_NONE
+ ? constant_name(isakmp_payload_cst, *pc)
+ : constant_name(exchange_script_cst, *pc)));
+ return -1;
+ }
+ pc++;
}
- pc++;
- }
- if (*pc == EXCHANGE_SCRIPT_END)
- /* Cleanup. */
- return 1;
+ if (*pc == EXCHANGE_SCRIPT_END)
+ /* Cleanup. */
+ return 1;
- return 0;
+ return 0;
}
/*
@@ -250,297 +248,294 @@ exchange_validate (struct message *msg)
* expect MSG to be a half-cooked message without payloads.
*/
void
-exchange_run (struct message *msg)
+exchange_run(struct message *msg)
{
- int i, done = 0;
- struct exchange *exchange = msg->exchange;
- struct doi *doi = exchange->doi;
- int (*handler) (struct message *)
- = exchange->initiator ? doi->initiator : doi->responder;
- struct payload *payload;
-
- while (!done)
- {
- /*
- * It's our turn if we're either the initiator on an even step,
- * or the responder on an odd step of the dialogue.
- */
- if (exchange->initiator ^ (exchange->step % 2))
- {
- done = 1;
- if (exchange->step)
- msg = message_alloc_reply (msg);
- message_setup_header (msg, exchange->type, 0, exchange->message_id);
- if (handler (msg))
- {
- /*
- * This can happen when transient starvation of memory occurs.
- * XXX The peer's retransmit ought to kick-start this exchange
- * again. If he's stopped retransmitting he's likely dropped
- * the SA at his side so we need to do that too, i.e.
- * implement automatic SA teardown after a certain amount
- * of inactivity.
- */
- log_print ("exchange_run: doi->%s (%p) failed",
- exchange->initiator ? "initiator" : "responder", msg);
- message_free (msg);
- return;
- }
-
- switch (exchange_validate (msg))
- {
- case 1:
- /*
- * The last message of a multi-message exchange should
- * not be retransmitted other than "on-demand", i.e. if we
- * see retransmits of the last message of the peer
- * later.
- */
- msg->flags |= MSG_LAST;
- if (exchange->step > 0)
- {
- if (exchange->last_sent)
- message_free (exchange->last_sent);
- exchange->last_sent = msg;
- }
-
- /*
- * After we physically have sent our last message we need to
- * do SA-specific finalization, like telling our application
- * the SA is ready to be used, or issuing a CONNECTED notify
- * if we set the COMMIT bit.
- */
- message_register_post_send (msg, exchange_finalize);
-
- /* Fallthrough. */
-
- case 0:
- /* XXX error handling. */
- message_send (msg);
- break;
-
- default:
- log_print ("exchange_run: exchange_validate failed, DOI error");
- exchange_free (exchange);
- message_free (msg);
- return;
- }
- }
- else
- {
- done = exchange_validate (msg);
- switch (done)
- {
- case 0:
- case 1:
- /* Feed the message to the DOI. */
- if (handler (msg))
- {
- /*
- * Trust the peer to retransmit.
- * XXX We have to implement SA aging with automatic teardown.
- */
- message_free (msg);
- return;
+ int i, done = 0;
+ struct exchange *exchange = msg->exchange;
+ struct doi *doi = exchange->doi;
+ int (*handler)(struct message *) = exchange->initiator ?
+ doi->initiator : doi->responder;
+ struct payload *payload;
+
+ while (!done) {
+ /*
+ * It's our turn if we're either the initiator on an even step,
+ * or the responder on an odd step of the dialogue.
+ */
+ if (exchange->initiator ^ (exchange->step % 2)) {
+ done = 1;
+ if (exchange->step)
+ msg = message_alloc_reply(msg);
+ message_setup_header(msg, exchange->type, 0,
+ exchange->message_id);
+ if (handler(msg)) {
+ /*
+ * This can happen when transient starvation
+ * of memory occurs.
+ * XXX The peer's retransmit ought to
+ * kick-start this exchange again. If he's
+ * stopped retransmitting he's likely dropped
+ * the SA at his side so we need to do that
+ * too, i.e. implement automatic SA teardown
+ * after a certain amount of inactivity.
+ */
+ log_print("exchange_run: doi->%s (%p) failed",
+ exchange->initiator ? "initiator" :
+ "responder", msg);
+ message_free(msg);
+ return;
+ }
+ switch (exchange_validate(msg)) {
+ case 1:
+ /*
+ * The last message of a multi-message
+ * exchange should not be retransmitted other
+ * than "on-demand", i.e. if we see
+ * retransmits of the last message of the peer
+ * later.
+ */
+ msg->flags |= MSG_LAST;
+ if (exchange->step > 0) {
+ if (exchange->last_sent)
+ message_free(exchange->last_sent);
+ exchange->last_sent = msg;
+ }
+ /*
+ * After we physically have sent our last
+ * message we need to do SA-specific
+ * finalization, like telling our application
+ * the SA is ready to be used, or issuing a
+ * CONNECTED notify if we set the COMMIT bit.
+ */
+ message_register_post_send(msg, exchange_finalize);
+
+ /* Fallthrough. */
+
+ case 0:
+ /* XXX error handling. */
+ message_send(msg);
+ break;
+
+ default:
+ log_print("exchange_run: exchange_validate failed, DOI error");
+ exchange_free(exchange);
+ message_free(msg);
+ return;
+ }
+ } else {
+ done = exchange_validate(msg);
+ switch (done) {
+ case 0:
+ case 1:
+ /* Feed the message to the DOI. */
+ if (handler(msg)) {
+ /*
+ * Trust the peer to retransmit.
+ * XXX We have to implement SA aging
+ * with automatic teardown.
+ */
+ message_free(msg);
+ return;
+ }
+ /*
+ * Go over the yet unhandled payloads and feed
+ * them to DOI for handling.
+ */
+ for (i = ISAKMP_PAYLOAD_SA; i <
+ ISAKMP_PAYLOAD_RESERVED_MIN; i++) {
+ if (i != ISAKMP_PAYLOAD_PROPOSAL
+ && i != ISAKMP_PAYLOAD_TRANSFORM) {
+ for (payload = TAILQ_FIRST(&msg->payload[i]); payload;
+ payload = TAILQ_NEXT(payload, link)) {
+ if ((payload->flags & PL_MARK) == 0) {
+ if (!doi->handle_leftover_payload
+ || doi->handle_leftover_payload(msg, i, payload)) {
+ LOG_DBG((LOG_EXCHANGE, 10,
+ "exchange_run: unexpected payload %s",
+ constant_name(isakmp_payload_cst, i)));
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * We have advanced the state. If we have
+ * been processing an incoming message, record
+ * that message as the one to do duplication
+ * tests against.
+ */
+ if (exchange->last_received)
+ message_free(exchange->last_received);
+ exchange->last_received = msg;
+ if (exchange->flags & EXCHANGE_FLAG_ENCRYPT)
+ crypto_update_iv(exchange->keystate);
+
+ if (done) {
+ exchange_finalize(msg);
+ return;
+ }
+ break;
+
+ case -1:
+ log_print("exchange_run: exchange_validate failed");
+ /*
+ * XXX Is this the best error notification
+ * type?
+ */
+ message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
+ return;
+ }
}
- /*
- * Go over the yet unhandled payloads and feed them to DOI
- * for handling.
- */
- for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++)
- if (i != ISAKMP_PAYLOAD_PROPOSAL
- && i != ISAKMP_PAYLOAD_TRANSFORM)
- for (payload = TAILQ_FIRST (&msg->payload[i]); payload;
- payload = TAILQ_NEXT (payload, link))
- if ((payload->flags & PL_MARK) == 0)
- if (!doi->handle_leftover_payload
- || doi->handle_leftover_payload (msg, i, payload))
- LOG_DBG ((LOG_EXCHANGE, 10,
- "exchange_run: unexpected payload %s",
- constant_name (isakmp_payload_cst, i)));
-
- /*
- * We have advanced the state. If we have been processing an
- * incoming message, record that message as the one to do
- * duplication tests against.
- */
- if (exchange->last_received)
- message_free (exchange->last_received);
- exchange->last_received = msg;
- if (exchange->flags & EXCHANGE_FLAG_ENCRYPT)
- crypto_update_iv (exchange->keystate);
-
- if (done)
- {
- exchange_finalize (msg);
- return;
- }
- break;
-
- case -1:
- log_print ("exchange_run: exchange_validate failed");
- /* XXX Is this the best error notification type? */
- message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
- return;
- }
+ LOG_DBG((LOG_EXCHANGE, 40,
+ "exchange_run: exchange %p finished step %d, advancing...",
+ exchange, exchange->step));
+ exchange->step++;
+ while (*exchange->exch_pc != EXCHANGE_SCRIPT_SWITCH
+ && *exchange->exch_pc != EXCHANGE_SCRIPT_END)
+ exchange->exch_pc++;
+ exchange->exch_pc++;
}
-
- LOG_DBG ((LOG_EXCHANGE, 40,
- "exchange_run: exchange %p finished step %d, advancing...",
- exchange, exchange->step));
- exchange->step++;
- while (*exchange->exch_pc != EXCHANGE_SCRIPT_SWITCH
- && *exchange->exch_pc != EXCHANGE_SCRIPT_END)
- exchange->exch_pc++;
- exchange->exch_pc++;
- }
}
void
-exchange_init ()
+exchange_init()
{
- int i;
-
- bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
- exchange_tab = malloc ((bucket_mask + 1) * sizeof (struct exchange_list));
- if (!exchange_tab)
- log_fatal ("exchange_init: out of memory");
- for (i = 0; i <= bucket_mask; i++)
- {
- LIST_INIT (&exchange_tab[i]);
- }
+ int i;
+
+ bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
+ exchange_tab = malloc((bucket_mask + 1) * sizeof(struct exchange_list));
+ if (!exchange_tab)
+ log_fatal("exchange_init: out of memory");
+ for (i = 0; i <= bucket_mask; i++) {
+ LIST_INIT(&exchange_tab[i]);
+ }
}
#if 0
/* XXX Currently unused. */
static void
-exchange_resize (void)
+exchange_resize(void)
{
- int new_mask = (bucket_mask + 1) * 2 - 1;
- int i;
- struct exchange_list *new_tab;
-
- new_tab
- = realloc (exchange_tab, (new_mask + 1) * sizeof (struct exchange_list));
- if (!new_tab)
- return;
- for (i = bucket_mask + 1; i <= new_mask; i++)
- {
- LIST_INIT (&new_tab[i]);
- }
- bucket_mask = new_mask;
- /* XXX Rehash existing entries. */
+ int new_mask = (bucket_mask + 1) * 2 - 1;
+ int i;
+ struct exchange_list *new_tab;
+
+ new_tab = realloc(exchange_tab, (new_mask + 1) * sizeof(struct exchange_list));
+ if (!new_tab)
+ return;
+ for (i = bucket_mask + 1; i <= new_mask; i++) {
+ LIST_INIT(&new_tab[i]);
+ }
+ bucket_mask = new_mask;
+ /* XXX Rehash existing entries. */
}
#endif
/* Lookup a phase 1 exchange out of just the initiator cookie. */
struct exchange *
-exchange_lookup_from_icookie (u_int8_t *cookie)
+exchange_lookup_from_icookie(u_int8_t * cookie)
{
- int i;
- struct exchange *exchange;
-
- for (i = 0; i <= bucket_mask; i++)
- for (exchange = LIST_FIRST (&exchange_tab[i]); exchange;
- exchange = LIST_NEXT (exchange, link))
- if (memcmp (exchange->cookies, cookie, ISAKMP_HDR_ICOOKIE_LEN) == 0
- && exchange->phase == 1)
- return exchange;
- return 0;
+ int i;
+ struct exchange *exchange;
+
+ for (i = 0; i <= bucket_mask; i++)
+ for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
+ exchange = LIST_NEXT(exchange, link))
+ if (memcmp(exchange->cookies, cookie,
+ ISAKMP_HDR_ICOOKIE_LEN) == 0
+ && exchange->phase == 1)
+ return exchange;
+ return 0;
}
/* Lookup an exchange out of the name and phase. */
struct exchange *
-exchange_lookup_by_name (char *name, int phase)
+exchange_lookup_by_name(char *name, int phase)
{
- int i;
- struct exchange *exchange;
-
- /* If we search for nothing, we will find nothing. */
- if (!name)
- return 0;
-
- for (i = 0; i <= bucket_mask; i++)
- for (exchange = LIST_FIRST (&exchange_tab[i]); exchange;
- exchange = LIST_NEXT (exchange, link))
- {
- LOG_DBG ((LOG_EXCHANGE, 90,
- "exchange_lookup_by_name: %s == %s && %d == %d?", name,
- exchange->name ? exchange->name : "<unnamed>", phase,
- exchange->phase));
-
- /*
- * Match by name, but don't select finished exchanges, i.e
- * where MSG_LAST are set in last_sent msg.
- */
- if (exchange->name && strcasecmp (exchange->name, name) == 0
- && exchange->phase == phase
- && (!exchange->last_sent
- || (exchange->last_sent->flags & MSG_LAST) == 0))
- return exchange;
- }
- return 0;
+ int i;
+ struct exchange *exchange;
+
+ /* If we search for nothing, we will find nothing. */
+ if (!name)
+ return 0;
+
+ for (i = 0; i <= bucket_mask; i++)
+ for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
+ exchange = LIST_NEXT(exchange, link)) {
+ LOG_DBG((LOG_EXCHANGE, 90,
+ "exchange_lookup_by_name: %s == %s && %d == %d?",
+ name, exchange->name ? exchange->name :
+ "<unnamed>", phase, exchange->phase));
+
+ /*
+ * Match by name, but don't select finished exchanges,
+ * i.e where MSG_LAST are set in last_sent msg.
+ */
+ if (exchange->name && strcasecmp(exchange->name, name) == 0
+ && exchange->phase == phase
+ && (!exchange->last_sent
+ || (exchange->last_sent->flags & MSG_LAST) == 0))
+ return exchange;
+ }
+ return 0;
}
/* Lookup an exchange out of the name, phase and step > 1. */
static struct exchange *
-exchange_lookup_active (char *name, int phase)
+exchange_lookup_active(char *name, int phase)
{
- int i;
- struct exchange *exchange;
-
- /* XXX Almost identical to exchange_lookup_by_name. */
-
- if (!name)
- return 0;
-
- for (i = 0; i <= bucket_mask; i++)
- for (exchange = LIST_FIRST (&exchange_tab[i]); exchange;
- exchange = LIST_NEXT (exchange, link))
- {
- LOG_DBG ((LOG_EXCHANGE, 90,
- "exchange_lookup_active: %s == %s && %d == %d?",
- name, exchange->name ? exchange->name : "<unnamed>", phase,
- exchange->phase));
- if (exchange->name && strcasecmp (exchange->name, name) == 0
- && exchange->phase == phase)
- {
- if (exchange->step > 1)
- return exchange;
- else
- LOG_DBG ((LOG_EXCHANGE, 80,
- "exchange_lookup_active: avoided early (pre-step 1) "
- "exchange %p", exchange));
- }
- }
- return 0;
+ int i;
+ struct exchange *exchange;
+
+ /* XXX Almost identical to exchange_lookup_by_name. */
+
+ if (!name)
+ return 0;
+
+ for (i = 0; i <= bucket_mask; i++)
+ for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
+ exchange = LIST_NEXT(exchange, link)) {
+ LOG_DBG((LOG_EXCHANGE, 90,
+ "exchange_lookup_active: %s == %s && %d == %d?",
+ name, exchange->name ? exchange->name :
+ "<unnamed>", phase, exchange->phase));
+ if (exchange->name && strcasecmp(exchange->name, name) == 0
+ && exchange->phase == phase) {
+ if (exchange->step > 1)
+ return exchange;
+ else
+ LOG_DBG((LOG_EXCHANGE, 80,
+ "exchange_lookup_active: avoided early (pre-step 1) "
+ "exchange %p", exchange));
+ }
+ }
+ return 0;
}
static void
-exchange_enter (struct exchange *exchange)
+exchange_enter(struct exchange *exchange)
{
- u_int16_t bucket = 0;
- int i;
- u_int8_t *cp;
-
- /* XXX We might resize if we are crossing a certain threshold */
-
- for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2)
- {
- cp = exchange->cookies + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2)
- {
- cp = exchange->message_id + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- bucket &= bucket_mask;
- LIST_INSERT_HEAD (&exchange_tab[bucket], exchange, link);
+ u_int16_t bucket = 0;
+ int i;
+ u_int8_t *cp;
+
+ /* XXX We might resize if we are crossing a certain threshold */
+
+ for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) {
+ cp = exchange->cookies + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) {
+ cp = exchange->message_id + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ bucket &= bucket_mask;
+ LIST_INSERT_HEAD(&exchange_tab[bucket], exchange, link);
}
/*
@@ -548,46 +543,43 @@ exchange_enter (struct exchange *exchange)
* looking for phase 1 exchanges and true otherwise.
*/
struct exchange *
-exchange_lookup (u_int8_t *msg, int phase2)
+exchange_lookup(u_int8_t *msg, int phase2)
{
- u_int16_t bucket = 0;
- int i;
- struct exchange *exchange;
- u_int8_t *cp;
-
- /*
- * We use the cookies to get bits to use as an index into exchange_tab, as at
- * least one (our cookie) is a good hash, xoring all the bits, 16 at a
- * time, and then masking, should do. Doing it this way means we can
- * validate cookies very fast thus delimiting the effects of "Denial of
- * service"-attacks using packet flooding.
- */
- for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2)
- {
- cp = msg + ISAKMP_HDR_COOKIES_OFF + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- if (phase2)
- for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2)
- {
- cp = msg + ISAKMP_HDR_MESSAGE_ID_OFF + i;
- /* Doing it this way avoids alignment problems. */
- bucket ^= cp[0] | cp[1] << 8;
- }
- bucket &= bucket_mask;
- for (exchange = LIST_FIRST (&exchange_tab[bucket]);
- exchange && (memcmp (msg + ISAKMP_HDR_COOKIES_OFF, exchange->cookies,
- ISAKMP_HDR_COOKIES_LEN) != 0
- || (phase2 && memcmp (msg + ISAKMP_HDR_MESSAGE_ID_OFF,
- exchange->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN) != 0)
- || (!phase2 && !zero_test (msg + ISAKMP_HDR_MESSAGE_ID_OFF,
- ISAKMP_HDR_MESSAGE_ID_LEN)));
- exchange = LIST_NEXT (exchange, link))
- ;
-
- return exchange;
+ u_int16_t bucket = 0;
+ int i;
+ struct exchange *exchange;
+ u_int8_t *cp;
+
+ /*
+ * We use the cookies to get bits to use as an index into exchange_tab, as at
+ * least one (our cookie) is a good hash, xoring all the bits, 16 at a
+ * time, and then masking, should do. Doing it this way means we can
+ * validate cookies very fast thus delimiting the effects of "Denial of
+ * service"-attacks using packet flooding.
+ */
+ for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) {
+ cp = msg + ISAKMP_HDR_COOKIES_OFF + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ if (phase2)
+ for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) {
+ cp = msg + ISAKMP_HDR_MESSAGE_ID_OFF + i;
+ /* Doing it this way avoids alignment problems. */
+ bucket ^= cp[0] | cp[1] << 8;
+ }
+ bucket &= bucket_mask;
+ for (exchange = LIST_FIRST(&exchange_tab[bucket]);
+ exchange && (memcmp(msg + ISAKMP_HDR_COOKIES_OFF, exchange->cookies,
+ ISAKMP_HDR_COOKIES_LEN) != 0
+ || (phase2 && memcmp(msg + ISAKMP_HDR_MESSAGE_ID_OFF,
+ exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN) != 0)
+ || (!phase2 && !zero_test(msg + ISAKMP_HDR_MESSAGE_ID_OFF,
+ ISAKMP_HDR_MESSAGE_ID_LEN)));
+ exchange = LIST_NEXT(exchange, link))
+ ;
+
+ return exchange;
}
/*
@@ -598,81 +590,74 @@ exchange_lookup (u_int8_t *msg, int phase2)
* when we have the responder role.
*/
static struct exchange *
-exchange_create (int phase, int initiator, int doi, int type)
+exchange_create(int phase, int initiator, int doi, int type)
{
- struct exchange *exchange;
- struct timeval expiration;
- int delta;
-
- /*
- * We want the exchange zeroed for exchange_free to be able to find
- * out what fields have been filled-in.
- */
- exchange = calloc (1, sizeof *exchange);
- if (!exchange)
- {
- log_error ("exchange_create: calloc (1, %lu) failed",
- (unsigned long)sizeof *exchange);
- return 0;
- }
- exchange->phase = phase;
- exchange->step = 0;
- exchange->initiator = initiator;
- memset (exchange->cookies, 0, ISAKMP_HDR_COOKIES_LEN);
- memset (exchange->message_id, 0, ISAKMP_HDR_MESSAGE_ID_LEN);
- exchange->doi = doi_lookup (doi);
- exchange->type = type;
- exchange->policy_id = -1;
- exchange->exch_pc = exchange_script (exchange);
- exchange->last_sent = exchange->last_received = 0;
- TAILQ_INIT (&exchange->sa_list);
- TAILQ_INIT (&exchange->aca_list);
-
- /* Allocate the DOI-specific structure and initialize it to zeroes. */
- if (exchange->doi->exchange_size)
- {
- exchange->data = calloc (1, exchange->doi->exchange_size);
- if (!exchange->data)
- {
- log_error ("exchange_create: calloc (1, %lu) failed",
- (unsigned long)exchange->doi->exchange_size);
- exchange_free (exchange);
- return 0;
+ struct exchange *exchange;
+ struct timeval expiration;
+ int delta;
+
+ /*
+ * We want the exchange zeroed for exchange_free to be able to find
+ * out what fields have been filled-in.
+ */
+ exchange = calloc(1, sizeof *exchange);
+ if (!exchange) {
+ log_error("exchange_create: calloc (1, %lu) failed",
+ (unsigned long)sizeof *exchange);
+ return 0;
}
- }
-
- gettimeofday (&expiration, 0);
- delta = conf_get_num ("General", "Exchange-max-time", EXCHANGE_MAX_TIME);
- expiration.tv_sec += delta;
- exchange->death = timer_add_event ("exchange_free_aux", exchange_free_aux,
- exchange, &expiration);
- if (!exchange->death)
- {
- /* If we don't give up we might start leaking... */
- exchange_free_aux (exchange);
- return 0;
- }
-
- return exchange;
+ exchange->phase = phase;
+ exchange->step = 0;
+ exchange->initiator = initiator;
+ memset(exchange->cookies, 0, ISAKMP_HDR_COOKIES_LEN);
+ memset(exchange->message_id, 0, ISAKMP_HDR_MESSAGE_ID_LEN);
+ exchange->doi = doi_lookup(doi);
+ exchange->type = type;
+ exchange->policy_id = -1;
+ exchange->exch_pc = exchange_script(exchange);
+ exchange->last_sent = exchange->last_received = 0;
+ TAILQ_INIT(&exchange->sa_list);
+ TAILQ_INIT(&exchange->aca_list);
+
+ /* Allocate the DOI-specific structure and initialize it to zeroes. */
+ if (exchange->doi->exchange_size) {
+ exchange->data = calloc(1, exchange->doi->exchange_size);
+ if (!exchange->data) {
+ log_error("exchange_create: calloc (1, %lu) failed",
+ (unsigned long)exchange->doi->exchange_size);
+ exchange_free(exchange);
+ return 0;
+ }
+ }
+ gettimeofday(&expiration, 0);
+ delta = conf_get_num("General", "Exchange-max-time", EXCHANGE_MAX_TIME);
+ expiration.tv_sec += delta;
+ exchange->death = timer_add_event("exchange_free_aux", exchange_free_aux,
+ exchange, &expiration);
+ if (!exchange->death) {
+ /* If we don't give up we might start leaking... */
+ exchange_free_aux(exchange);
+ return 0;
+ }
+ return exchange;
}
-struct exchange_finalization_node
-{
- void (*first) (struct exchange *, void *, int);
- void *first_arg;
- void (*second) (struct exchange *, void *, int);
- void *second_arg;
+struct exchange_finalization_node {
+ void (*first)(struct exchange *, void *, int);
+ void *first_arg;
+ void (*second)(struct exchange *, void *, int);
+ void *second_arg;
};
/* Run the finalization functions of ARG. */
static void
-exchange_run_finalizations (struct exchange *exchange, void *arg, int fail)
+exchange_run_finalizations(struct exchange *exchange, void *arg, int fail)
{
- struct exchange_finalization_node *node = arg;
+ struct exchange_finalization_node *node = arg;
- node->first (exchange, node->first_arg, fail);
- node->second (exchange, node->second_arg, fail);
- free (node);
+ node->first(exchange, node->first_arg, fail);
+ node->second(exchange, node->second_arg, fail);
+ free(node);
}
/*
@@ -680,568 +665,513 @@ exchange_run_finalizations (struct exchange *exchange, void *arg, int fail)
* of the finalization function list of EXCHANGE.
*/
static void
-exchange_add_finalization (struct exchange *exchange,
- void (*finalize) (struct exchange *, void *, int),
- void *arg)
+exchange_add_finalization(struct exchange *exchange,
+ void (*finalize)(struct exchange *, void *, int), void *arg)
{
- struct exchange_finalization_node *node;
-
- if (!finalize)
- return;
-
- if (!exchange->finalize)
- {
- exchange->finalize = finalize;
- exchange->finalize_arg = arg;
- return;
- }
-
- node = malloc (sizeof *node);
- if (!node)
- {
- log_error ("exchange_add_finalization: malloc (%lu) failed",
- (unsigned long)sizeof *node);
- free (arg);
- return;
- }
- node->first = exchange->finalize;
- node->first_arg = exchange->finalize_arg;
- node->second = finalize;
- node->second_arg = arg;
- exchange->finalize = exchange_run_finalizations;
- exchange->finalize_arg = node;
+ struct exchange_finalization_node *node;
+
+ if (!finalize)
+ return;
+
+ if (!exchange->finalize) {
+ exchange->finalize = finalize;
+ exchange->finalize_arg = arg;
+ return;
+ }
+ node = malloc(sizeof *node);
+ if (!node) {
+ log_error("exchange_add_finalization: malloc (%lu) failed",
+ (unsigned long)sizeof *node);
+ free(arg);
+ return;
+ }
+ node->first = exchange->finalize;
+ node->first_arg = exchange->finalize_arg;
+ node->second = finalize;
+ node->second_arg = arg;
+ exchange->finalize = exchange_run_finalizations;
+ exchange->finalize_arg = node;
}
#ifdef USE_ISAKMP_CFG
static void
-exchange_establish_transaction (struct exchange *exchange, void *arg, int fail)
+exchange_establish_transaction(struct exchange *exchange, void *arg, int fail)
{
- /* Establish a TRANSACTION exchange. */
- struct exchange_finalization_node *node
- = (struct exchange_finalization_node *)arg;
- struct sa *isakmp_sa = sa_lookup_by_name ((char *)node->second_arg, 1);
+ /* Establish a TRANSACTION exchange. */
+ struct exchange_finalization_node *node =
+ (struct exchange_finalization_node *)arg;
+ struct sa *isakmp_sa = sa_lookup_by_name((char *) node->second_arg, 1);
- if (isakmp_sa && !fail)
- exchange_establish_p2 (isakmp_sa, ISAKMP_EXCH_TRANSACTION, 0, 0,
- node->first, node->first_arg);
+ if (isakmp_sa && !fail)
+ exchange_establish_p2(isakmp_sa, ISAKMP_EXCH_TRANSACTION, 0, 0,
+ node->first, node->first_arg);
- free (node);
+ free(node);
}
-#endif /* USE_ISAKMP_CFG */
+#endif /* USE_ISAKMP_CFG */
/* Establish a phase 1 exchange. */
void
-exchange_establish_p1 (struct transport *t, u_int8_t type, u_int32_t doi,
- char *name, void *args,
- void (*finalize) (struct exchange *, void *, int),
- void *arg)
+exchange_establish_p1(struct transport *t, u_int8_t type, u_int32_t doi,
+ char *name, void *args, void (*finalize)(struct exchange *, void *, int),
+ void *arg)
{
- struct exchange *exchange;
- struct message *msg;
+ struct exchange *exchange;
+ struct message *msg;
#ifdef USE_ISAKMP_CFG
- struct conf_list *flags;
- struct conf_list_node *flag;
+ struct conf_list *flags;
+ struct conf_list_node *flag;
#endif
- char *tag = 0;
- char *str;
-
- if (name)
- {
- /* If no exchange type given, fetch from the configuration. */
- if (type == 0)
- {
- /* XXX Similar code can be found in exchange_setup_p1. Share? */
-
- /* Find out our phase 1 mode. */
- tag = conf_get_str (name, "Configuration");
- if (!tag)
- {
- /* Use default setting. */
- tag = CONF_DFLT_TAG_PHASE1_CONFIG;
- }
-
- /* Figure out the DOI. XXX Factor out? */
- str = conf_get_str (tag, "DOI");
- if (!str || strcasecmp (str, "IPSEC") == 0)
- doi = IPSEC_DOI_IPSEC;
- else if (strcasecmp (str, "ISAKMP") == 0)
- doi = ISAKMP_DOI_ISAKMP;
- else
- {
- log_print ("exchange_establish_p1: DOI \"%s\" unsupported", str);
- return;
- }
-
- /* What exchange type do we want? */
- str = conf_get_str (tag, "EXCHANGE_TYPE");
- if (!str)
- {
- log_print ("exchange_establish_p1: "
- "no \"EXCHANGE_TYPE\" tag in [%s] section", tag);
- return;
- }
- type = constant_value (isakmp_exch_cst, str);
- if (!type)
- {
- log_print ("exchange_setup_p1: unknown exchange type %s",
- str);
- return;
- }
+ char *tag = 0;
+ char *str;
+
+ if (name) {
+ /* If no exchange type given, fetch from the configuration. */
+ if (type == 0) {
+ /*
+ * XXX Similar code can be found in
+ * exchange_setup_p1. Share?
+ */
+
+ /* Find out our phase 1 mode. */
+ tag = conf_get_str(name, "Configuration");
+ if (!tag) {
+ /* Use default setting. */
+ tag = CONF_DFLT_TAG_PHASE1_CONFIG;
+ }
+ /* Figure out the DOI. XXX Factor out? */
+ str = conf_get_str(tag, "DOI");
+ if (!str || strcasecmp(str, "IPSEC") == 0)
+ doi = IPSEC_DOI_IPSEC;
+ else if (strcasecmp(str, "ISAKMP") == 0)
+ doi = ISAKMP_DOI_ISAKMP;
+ else {
+ log_print("exchange_establish_p1: DOI \"%s\" unsupported",
+ str);
+ return;
+ }
+
+ /* What exchange type do we want? */
+ str = conf_get_str(tag, "EXCHANGE_TYPE");
+ if (!str) {
+ log_print("exchange_establish_p1: "
+ "no \"EXCHANGE_TYPE\" tag in [%s] section",
+ tag);
+ return;
+ }
+ type = constant_value(isakmp_exch_cst, str);
+ if (!type) {
+ log_print("exchange_setup_p1: unknown exchange type %s",
+ str);
+ return;
+ }
+ }
}
- }
-
- exchange = exchange_create (1, 1, doi, type);
- if (!exchange)
- {
- /* XXX Do something here? */
- return;
- }
-
- if (name)
- {
- exchange->name = strdup (name);
- if (!exchange->name)
- {
- log_error ("exchange_establish_p1: strdup (\"%s\") failed", name);
- exchange_free (exchange);
- return;
+ exchange = exchange_create(1, 1, doi, type);
+ if (!exchange) {
+ /* XXX Do something here? */
+ return;
}
- }
-
- exchange->policy = name ? conf_get_str (name, "Configuration") : 0;
- if (!exchange->policy && name)
- exchange->policy = CONF_DFLT_TAG_PHASE1_CONFIG;
+ if (name) {
+ exchange->name = strdup(name);
+ if (!exchange->name) {
+ log_error("exchange_establish_p1: strdup (\"%s\") failed", name);
+ exchange_free(exchange);
+ return;
+ }
+ }
+ exchange->policy = name ? conf_get_str(name, "Configuration") : 0;
+ if (!exchange->policy && name)
+ exchange->policy = CONF_DFLT_TAG_PHASE1_CONFIG;
#ifdef USE_ISAKMP_CFG
- if (name)
- {
- flags = conf_get_list (name, "Flags");
- if (flags)
- {
- for (flag = TAILQ_FIRST (&flags->fields); flag;
- flag = TAILQ_NEXT (flag, link))
- if (strcasecmp (flag->field, "ikecfg") == 0)
- {
- struct exchange_finalization_node *node;
-
- node = calloc (1, (unsigned long)sizeof *node);
- if (!node)
- {
- log_print ("exchange_establish_p1: calloc (1, %lu) failed",
- (unsigned long)sizeof (*node));
- exchange_free (exchange);
- return;
- }
-
- /* Insert this finalization inbetween the original. */
- node->first = finalize;
- node->first_arg = arg;
- node->second_arg = name;
- exchange_add_finalization (exchange,
- exchange_establish_transaction,
- node);
- finalize = 0;
- }
- conf_free_list (flags);
+ if (name) {
+ flags = conf_get_list(name, "Flags");
+ if (flags) {
+ for (flag = TAILQ_FIRST(&flags->fields); flag;
+ flag = TAILQ_NEXT(flag, link))
+ if (strcasecmp(flag->field, "ikecfg") == 0) {
+ struct exchange_finalization_node *node;
+
+ node = calloc(1, (unsigned long)sizeof *node);
+ if (!node) {
+ log_print("exchange_establish_p1: calloc (1, %lu) failed",
+ (unsigned long)sizeof(*node));
+ exchange_free(exchange);
+ return;
+ }
+ /*
+ * Insert this finalization inbetween
+ * the original.
+ */
+ node->first = finalize;
+ node->first_arg = arg;
+ node->second_arg = name;
+ exchange_add_finalization(exchange,
+ exchange_establish_transaction,
+ node);
+ finalize = 0;
+ }
+ conf_free_list(flags);
+ }
}
- }
-#endif /* USE_ISAKMP_CFG */
+#endif /* USE_ISAKMP_CFG */
- exchange_add_finalization (exchange, finalize, arg);
- cookie_gen (t, exchange, exchange->cookies, ISAKMP_HDR_ICOOKIE_LEN);
- exchange_enter (exchange);
+ exchange_add_finalization(exchange, finalize, arg);
+ cookie_gen(t, exchange, exchange->cookies, ISAKMP_HDR_ICOOKIE_LEN);
+ exchange_enter(exchange);
#ifdef USE_DEBUG
- exchange_dump ("exchange_establish_p1", exchange);
+ exchange_dump("exchange_establish_p1", exchange);
#endif
- msg = message_alloc (t, 0, ISAKMP_HDR_SZ);
- if (!msg)
- {
- log_print ("exchange_establish_p1: message_alloc () failed");
- exchange_free (exchange);
- return;
- }
- msg->exchange = exchange;
-
- /* Do not create SA for an information or transaction exchange. */
- if (exchange->type != ISAKMP_EXCH_INFO
- && exchange->type != ISAKMP_EXCH_TRANSACTION)
- {
- /*
- * Don't install a transport into this SA as it will be an INADDR_ANY
- * address in the local end, which is not good at all. Let the reply
- * packet install the transport instead.
- */
- sa_create (exchange, 0);
- msg->isakmp_sa = TAILQ_FIRST (&exchange->sa_list);
- if (!msg->isakmp_sa)
- {
- /* XXX Do something more here? */
- message_free (msg);
- exchange_free (exchange);
- return;
+ msg = message_alloc(t, 0, ISAKMP_HDR_SZ);
+ if (!msg) {
+ log_print("exchange_establish_p1: message_alloc () failed");
+ exchange_free(exchange);
+ return;
}
- sa_reference (msg->isakmp_sa);
- }
-
- msg->extra = args;
+ msg->exchange = exchange;
+
+ /* Do not create SA for an information or transaction exchange. */
+ if (exchange->type != ISAKMP_EXCH_INFO
+ && exchange->type != ISAKMP_EXCH_TRANSACTION) {
+ /*
+ * Don't install a transport into this SA as it will be an
+ * INADDR_ANY address in the local end, which is not good at
+ * all. Let the reply packet install the transport instead.
+ */
+ sa_create(exchange, 0);
+ msg->isakmp_sa = TAILQ_FIRST(&exchange->sa_list);
+ if (!msg->isakmp_sa) {
+ /* XXX Do something more here? */
+ message_free(msg);
+ exchange_free(exchange);
+ return;
+ }
+ sa_reference(msg->isakmp_sa);
+ }
+ msg->extra = args;
- exchange_run (msg);
+ exchange_run(msg);
}
/* Establish a phase 2 exchange. XXX With just one SA for now. */
void
-exchange_establish_p2 (struct sa *isakmp_sa, u_int8_t type, char *name,
- void *args,
- void (*finalize) (struct exchange *, void *, int),
- void *arg)
+exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *name,
+ void *args, void (*finalize)(struct exchange *, void *, int), void *arg)
{
- struct exchange *exchange;
- struct message *msg;
- int i;
- char *tag, *str;
- u_int32_t doi = ISAKMP_DOI_ISAKMP;
- u_int32_t seq = 0;
-
- if (isakmp_sa)
- doi = isakmp_sa->doi->id;
-
- if (name)
- {
- /* Find out our phase 2 modes. */
- tag = conf_get_str (name, "Configuration");
- if (!tag)
- {
- log_print ("exchange_establish_p2: no configuration for peer \"%s\"",
- name);
- return;
- }
+ struct exchange *exchange;
+ struct message *msg;
+ int i;
+ char *tag, *str;
+ u_int32_t doi = ISAKMP_DOI_ISAKMP;
+ u_int32_t seq = 0;
+
+ if (isakmp_sa)
+ doi = isakmp_sa->doi->id;
+
+ if (name) {
+ /* Find out our phase 2 modes. */
+ tag = conf_get_str(name, "Configuration");
+ if (!tag) {
+ log_print("exchange_establish_p2: no configuration for peer \"%s\"",
+ name);
+ return;
+ }
+ seq = (u_int32_t)conf_get_num(name, "Acquire-ID", 0);
+
+ /* Figure out the DOI. */
+ str = conf_get_str(tag, "DOI");
+ if (!str || strcasecmp(str, "IPSEC") == 0)
+ doi = IPSEC_DOI_IPSEC;
+ else if (strcasecmp(str, "ISAKMP") == 0)
+ doi = ISAKMP_DOI_ISAKMP;
+ else {
+ log_print("exchange_establish_p2: DOI \"%s\" unsupported", str);
+ return;
+ }
- seq = (u_int32_t) conf_get_num (name, "Acquire-ID", 0);
-
- /* Figure out the DOI. */
- str = conf_get_str (tag, "DOI");
- if (!str || strcasecmp (str, "IPSEC") == 0)
- doi = IPSEC_DOI_IPSEC;
- else if (strcasecmp (str, "ISAKMP") == 0)
- doi = ISAKMP_DOI_ISAKMP;
- else
- {
- log_print ("exchange_establish_p2: DOI \"%s\" unsupported", str);
- return;
+ /* What exchange type do we want? */
+ if (!type) {
+ str = conf_get_str(tag, "EXCHANGE_TYPE");
+ if (!str) {
+ log_print("exchange_establish_p2: "
+ "no \"EXCHANGE_TYPE\" tag in [%s] section",
+ tag);
+ return;
+ }
+ /* XXX IKE dependent. */
+ type = constant_value(ike_exch_cst, str);
+ if (!type) {
+ log_print("exchange_establish_p2: unknown "
+ "exchange type %s", str);
+ return;
+ }
+ }
}
-
- /* What exchange type do we want? */
- if (!type)
- {
- str = conf_get_str (tag, "EXCHANGE_TYPE");
- if (!str)
- {
- log_print ("exchange_establish_p2: "
- "no \"EXCHANGE_TYPE\" tag in [%s] section", tag);
- return;
- }
- /* XXX IKE dependent. */
- type = constant_value (ike_exch_cst, str);
- if (!type)
- {
- log_print ("exchange_establish_p2: unknown exchange type %s",
- str);
- return;
- }
+ exchange = exchange_create(2, 1, doi, type);
+ if (!exchange) {
+ /* XXX Do something here? */
+ return;
}
- }
-
- exchange = exchange_create (2, 1, doi, type);
- if (!exchange)
- {
- /* XXX Do something here? */
- return;
- }
-
- if (name)
- {
- exchange->name = strdup (name);
- if (!exchange->name)
- {
- log_error ("exchange_establish_p2: strdup (\"%s\") failed", name);
- exchange_free (exchange);
- return;
+ if (name) {
+ exchange->name = strdup(name);
+ if (!exchange->name) {
+ log_error("exchange_establish_p2: strdup (\"%s\") failed", name);
+ exchange_free(exchange);
+ return;
+ }
}
- }
- exchange->policy = name ? conf_get_str (name, "Configuration") : 0;
- exchange->finalize = finalize;
- exchange->finalize_arg = arg;
- exchange->seq = seq;
- memcpy (exchange->cookies, isakmp_sa->cookies, ISAKMP_HDR_COOKIES_LEN);
- getrandom (exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
- exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
- exchange_enter (exchange);
+ exchange->policy = name ? conf_get_str(name, "Configuration") : 0;
+ exchange->finalize = finalize;
+ exchange->finalize_arg = arg;
+ exchange->seq = seq;
+ memcpy(exchange->cookies, isakmp_sa->cookies, ISAKMP_HDR_COOKIES_LEN);
+ getrandom(exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
+ exchange_enter(exchange);
#ifdef USE_DEBUG
- exchange_dump ("exchange_establish_p2", exchange);
+ exchange_dump("exchange_establish_p2", exchange);
#endif
- /*
- * Do not create SA's for informational exchanges.
- * XXX How to handle new group mode?
- */
- if (exchange->type != ISAKMP_EXCH_INFO
- && exchange->type != ISAKMP_EXCH_TRANSACTION)
- {
- /* XXX Number of SAs should come from the args structure. */
- for (i = 0; i < 1; i++)
- if (sa_create (exchange, isakmp_sa->transport))
- {
- exchange_free (exchange);
- return;
- }
- }
-
- msg = message_alloc (isakmp_sa->transport, 0, ISAKMP_HDR_SZ);
- msg->isakmp_sa = isakmp_sa;
- sa_reference (isakmp_sa);
-
- msg->extra = args;
-
- /* This needs to be done late or else get_keystate won't work right. */
- msg->exchange = exchange;
-
- exchange_run (msg);
+ /*
+ * Do not create SA's for informational exchanges.
+ * XXX How to handle new group mode?
+ */
+ if (exchange->type != ISAKMP_EXCH_INFO
+ && exchange->type != ISAKMP_EXCH_TRANSACTION) {
+ /* XXX Number of SAs should come from the args structure. */
+ for (i = 0; i < 1; i++)
+ if (sa_create(exchange, isakmp_sa->transport)) {
+ exchange_free(exchange);
+ return;
+ }
+ }
+ msg = message_alloc(isakmp_sa->transport, 0, ISAKMP_HDR_SZ);
+ msg->isakmp_sa = isakmp_sa;
+ sa_reference(isakmp_sa);
+
+ msg->extra = args;
+
+ /* This needs to be done late or else get_keystate won't work right. */
+ msg->exchange = exchange;
+
+ exchange_run(msg);
}
/* Out of an incoming phase 1 message, setup an exchange. */
struct exchange *
-exchange_setup_p1 (struct message *msg, u_int32_t doi)
+exchange_setup_p1(struct message *msg, u_int32_t doi)
{
- struct transport *t = msg->transport;
- struct exchange *exchange;
- struct sockaddr *dst;
+ struct transport *t = msg->transport;
+ struct exchange *exchange;
+ struct sockaddr *dst;
#ifdef USE_ISAKMP_CFG
- struct conf_list *flags;
- struct conf_list_node *flag;
+ struct conf_list *flags;
+ struct conf_list_node *flag;
#endif
- char *name = 0, *policy = 0, *str;
- u_int32_t want_doi;
- u_int8_t type;
-
- /* XXX Similar code can be found in exchange_establish_p1. Share? */
-
- /*
- * Unless this is an informational exchange, look up our policy for this
- * peer.
- */
- type = GET_ISAKMP_HDR_EXCH_TYPE (msg->iov[0].iov_base);
- if (type != ISAKMP_EXCH_INFO)
- {
- /*
- * Find out our inbound phase 1 mode.
- */
- t->vtbl->get_dst (t, &dst);
- if (sockaddr2text (dst, &str, 0) == -1)
- return 0;
- name = conf_get_str ("Phase 1", str);
- free (str);
- if (name)
- {
- /*
- * If another phase 1 exchange is ongoing don't bother returning the
- * call. However, we will need to continue responding if our phase 1
- * exchange is still waiting for step 1 (i.e still half-open).
- */
- if (exchange_lookup_active (name, 1))
- return 0;
- }
- else
- {
- name = conf_get_str ("Phase 1", "Default");
- if (!name)
- {
- log_print ("exchange_setup_p1: "
- "no \"Default\" tag in [Phase 1] section");
- return 0;
- }
- }
+ char *name = 0, *policy = 0, *str;
+ u_int32_t want_doi;
+ u_int8_t type;
- policy = conf_get_str (name, "Configuration");
- if (!policy)
- policy = CONF_DFLT_TAG_PHASE1_CONFIG;
-
- /* Figure out the DOI. */
- str = conf_get_str (policy, "DOI");
- if (!str || strcasecmp (str, "IPSEC") == 0)
- want_doi = IPSEC_DOI_IPSEC;
- else if (strcasecmp (str, "ISAKMP") == 0)
- want_doi = ISAKMP_DOI_ISAKMP;
- else
- {
- log_print ("exchange_setup_p1: DOI \"%s\" unsupported", str);
- return 0;
- }
- if (want_doi != doi)
- {
- /* XXX Should I tell what DOI I got? */
- log_print ("exchange_setup_p1: expected %s DOI", str);
- return 0;
- }
+ /* XXX Similar code can be found in exchange_establish_p1. Share? */
- /* What exchange type do we want? */
- str = conf_get_str (policy, "EXCHANGE_TYPE");
- if (!str)
- {
- log_print ("exchange_setup_p1: "
- "no \"EXCHANGE_TYPE\" tag in [%s] section", policy);
- return 0;
- }
- type = constant_value (isakmp_exch_cst, str);
- if (!type)
- {
- log_print ("exchange_setup_p1: unknown exchange type %s", str);
- return 0;
+ /*
+ * Unless this is an informational exchange, look up our policy for
+ * this peer.
+ */
+ type = GET_ISAKMP_HDR_EXCH_TYPE(msg->iov[0].iov_base);
+ if (type != ISAKMP_EXCH_INFO) {
+ /*
+ * Find out our inbound phase 1 mode.
+ */
+ t->vtbl->get_dst(t, &dst);
+ if (sockaddr2text(dst, &str, 0) == -1)
+ return 0;
+ name = conf_get_str("Phase 1", str);
+ free(str);
+ if (name) {
+ /*
+ * If another phase 1 exchange is ongoing don't bother
+ * returning the call. However, we will need to
+ * continue responding if our phase 1 exchange is
+ * still waiting for step 1 (i.e still half-open).
+ */
+ if (exchange_lookup_active(name, 1))
+ return 0;
+ } else {
+ name = conf_get_str("Phase 1", "Default");
+ if (!name) {
+ log_print("exchange_setup_p1: no \"Default\" "
+ "tag in [Phase 1] section");
+ return 0;
+ }
+ }
+
+ policy = conf_get_str(name, "Configuration");
+ if (!policy)
+ policy = CONF_DFLT_TAG_PHASE1_CONFIG;
+
+ /* Figure out the DOI. */
+ str = conf_get_str(policy, "DOI");
+ if (!str || strcasecmp(str, "IPSEC") == 0)
+ want_doi = IPSEC_DOI_IPSEC;
+ else if (strcasecmp(str, "ISAKMP") == 0)
+ want_doi = ISAKMP_DOI_ISAKMP;
+ else {
+ log_print("exchange_setup_p1: DOI \"%s\" unsupported", str);
+ return 0;
+ }
+ if (want_doi != doi) {
+ /* XXX Should I tell what DOI I got? */
+ log_print("exchange_setup_p1: expected %s DOI", str);
+ return 0;
+ }
+ /* What exchange type do we want? */
+ str = conf_get_str(policy, "EXCHANGE_TYPE");
+ if (!str) {
+ log_print("exchange_setup_p1: no \"EXCHANGE_TYPE\" "
+ "tag in [%s] section", policy);
+ return 0;
+ }
+ type = constant_value(isakmp_exch_cst, str);
+ if (!type) {
+ log_print("exchange_setup_p1: unknown exchange type %s",
+ str);
+ return 0;
+ }
+ if (type != GET_ISAKMP_HDR_EXCH_TYPE(msg->iov[0].iov_base)) {
+ log_print("exchange_setup_p1: expected exchange type %s got %s",
+ str, constant_name(isakmp_exch_cst,
+ GET_ISAKMP_HDR_EXCH_TYPE(msg->iov[0].iov_base)));
+ return 0;
+ }
}
- if (type != GET_ISAKMP_HDR_EXCH_TYPE (msg->iov[0].iov_base))
- {
- log_print ("exchange_setup_p1: expected exchange type %s got %s",
- str,
- constant_name (isakmp_exch_cst,
- GET_ISAKMP_HDR_EXCH_TYPE (msg->iov[0]
- .iov_base)));
- return 0;
+ exchange = exchange_create(1, 0, doi, type);
+ if (!exchange)
+ return 0;
+
+ exchange->name = name ? strdup(name) : 0;
+ if (name && !exchange->name) {
+ log_error("exchange_setup_p1: strdup (\"%s\") failed", name);
+ exchange_free(exchange);
+ return 0;
}
- }
-
- exchange = exchange_create (1, 0, doi, type);
- if (!exchange)
- return 0;
-
- exchange->name = name ? strdup (name) : 0;
- if (name && !exchange->name)
- {
- log_error ("exchange_setup_p1: strdup (\"%s\") failed", name);
- exchange_free (exchange);
- return 0;
- }
- exchange->policy = policy;
+ exchange->policy = policy;
#ifdef USE_ISAKMP_CFG
- if (name)
- {
- flags = conf_get_list (name, "Flags");
- if (flags)
- {
- for (flag = TAILQ_FIRST (&flags->fields); flag;
- flag = TAILQ_NEXT (flag, link))
- if (strcasecmp (flag->field, "ikecfg") == 0)
- {
- struct exchange_finalization_node *node;
-
- node = calloc (1, (unsigned long)sizeof *node);
- if (!node)
- {
- log_print ("exchange_establish_p1: calloc (1, %lu) failed",
- (unsigned long)sizeof (*node));
- exchange_free (exchange);
- return 0;
- }
-
- /* Insert this finalization inbetween the original. */
- node->first = 0;
- node->first_arg = 0;
- node->second_arg = name;
- exchange_add_finalization (exchange,
- exchange_establish_transaction,
- node);
- }
- conf_free_list (flags);
+ if (name) {
+ flags = conf_get_list(name, "Flags");
+ if (flags) {
+ for (flag = TAILQ_FIRST(&flags->fields); flag;
+ flag = TAILQ_NEXT(flag, link))
+ if (strcasecmp(flag->field, "ikecfg") == 0) {
+ struct exchange_finalization_node *node;
+
+ node = calloc(1, (unsigned long)sizeof *node);
+ if (!node) {
+ log_print("exchange_establish_p1: calloc (1, %lu) failed",
+ (unsigned long)sizeof(*node));
+ exchange_free(exchange);
+ return 0;
+ }
+ /*
+ * Insert this finalization inbetween
+ * the original.
+ */
+ node->first = 0;
+ node->first_arg = 0;
+ node->second_arg = name;
+ exchange_add_finalization(exchange,
+ exchange_establish_transaction,
+ node);
+ }
+ conf_free_list(flags);
+ }
}
- }
#endif
- cookie_gen (msg->transport, exchange,
- exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN,
- ISAKMP_HDR_RCOOKIE_LEN);
- GET_ISAKMP_HDR_ICOOKIE (msg->iov[0].iov_base, exchange->cookies);
- exchange_enter (exchange);
+ cookie_gen(msg->transport, exchange, exchange->cookies +
+ ISAKMP_HDR_ICOOKIE_LEN, ISAKMP_HDR_RCOOKIE_LEN);
+ GET_ISAKMP_HDR_ICOOKIE(msg->iov[0].iov_base, exchange->cookies);
+ exchange_enter(exchange);
#ifdef USE_DEBUG
- exchange_dump ("exchange_setup_p1", exchange);
+ exchange_dump("exchange_setup_p1", exchange);
#endif
- return exchange;
+ return exchange;
}
/* Out of an incoming phase 2 message, setup an exchange. */
struct exchange *
-exchange_setup_p2 (struct message *msg, u_int8_t doi)
+exchange_setup_p2(struct message *msg, u_int8_t doi)
{
- struct exchange *exchange;
- u_int8_t *buf = msg->iov[0].iov_base;
-
- exchange = exchange_create (2, 0, doi, GET_ISAKMP_HDR_EXCH_TYPE (buf));
- if (!exchange)
- return 0;
- GET_ISAKMP_HDR_ICOOKIE (buf, exchange->cookies);
- GET_ISAKMP_HDR_RCOOKIE (buf, exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
- GET_ISAKMP_HDR_MESSAGE_ID (buf, exchange->message_id);
- exchange_enter (exchange);
+ struct exchange *exchange;
+ u_int8_t *buf = msg->iov[0].iov_base;
+
+ exchange = exchange_create(2, 0, doi, GET_ISAKMP_HDR_EXCH_TYPE(buf));
+ if (!exchange)
+ return 0;
+ GET_ISAKMP_HDR_ICOOKIE(buf, exchange->cookies);
+ GET_ISAKMP_HDR_RCOOKIE(buf, exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
+ GET_ISAKMP_HDR_MESSAGE_ID(buf, exchange->message_id);
+ exchange_enter(exchange);
#ifdef USE_DEBUG
- exchange_dump ("exchange_setup_p2", exchange);
+ exchange_dump("exchange_setup_p2", exchange);
#endif
- return exchange;
+ return exchange;
}
/* Dump interesting data about an exchange. */
static void
-exchange_dump_real (char *header, struct exchange *exchange, int class,
- int level)
+exchange_dump_real(char *header, struct exchange *exchange, int class,
+ int level)
{
- char buf[LOG_SIZE];
- /* Don't risk overflowing the final log buffer. */
- size_t bufsize_max = LOG_SIZE - strlen (header) - 32;
- struct sa *sa;
+ char buf[LOG_SIZE];
+ /* Don't risk overflowing the final log buffer. */
+ size_t bufsize_max = LOG_SIZE - strlen(header) - 32;
+ struct sa *sa;
- LOG_DBG ((class, level,
+ LOG_DBG((class, level,
"%s: %p %s %s policy %s phase %d doi %d exchange %d step %d",
header, exchange, exchange->name ? exchange->name : "<unnamed>",
exchange->policy ? exchange->policy : "<no policy>",
exchange->initiator ? "initiator" : "responder", exchange->phase,
exchange->doi->id, exchange->type, exchange->step));
- LOG_DBG ((class, level,
- "%s: icookie %08x%08x rcookie %08x%08x", header,
- decode_32 (exchange->cookies), decode_32 (exchange->cookies + 4),
- decode_32 (exchange->cookies + 8),
- decode_32 (exchange->cookies + 12)));
-
- /* Include phase 2 SA list for this exchange */
- if (exchange->phase == 2)
- {
- snprintf (buf, bufsize_max, "sa_list ");
- for (sa = TAILQ_FIRST (&exchange->sa_list);
- sa && strlen (buf) < bufsize_max; sa = TAILQ_NEXT (sa, next))
- snprintf (buf + strlen (buf), bufsize_max - strlen (buf), "%p ", sa);
- if (sa)
- strlcat (buf, "...", bufsize_max);
- }
- else
- buf[0] = '\0';
-
- LOG_DBG ((class, level, "%s: msgid %08x %s", header,
- decode_32 (exchange->message_id), buf));
+ LOG_DBG((class, level, "%s: icookie %08x%08x rcookie %08x%08x", header,
+ decode_32(exchange->cookies), decode_32(exchange->cookies + 4),
+ decode_32(exchange->cookies + 8), decode_32(exchange->cookies + 12)));
+
+ /* Include phase 2 SA list for this exchange */
+ if (exchange->phase == 2) {
+ snprintf(buf, bufsize_max, "sa_list ");
+ for (sa = TAILQ_FIRST(&exchange->sa_list);
+ sa && strlen(buf) < bufsize_max; sa = TAILQ_NEXT(sa, next))
+ snprintf(buf + strlen(buf), bufsize_max - strlen(buf), "%p ", sa);
+ if (sa)
+ strlcat(buf, "...", bufsize_max);
+ } else
+ buf[0] = '\0';
+
+ LOG_DBG((class, level, "%s: msgid %08x %s", header,
+ decode_32(exchange->message_id), buf));
}
static void
-exchange_dump (char *header, struct exchange *exchange)
+exchange_dump(char *header, struct exchange *exchange)
{
- exchange_dump_real (header, exchange, LOG_EXCHANGE, 10);
+ exchange_dump_real(header, exchange, LOG_EXCHANGE, 10);
}
void
-exchange_report (void)
+exchange_report(void)
{
- int i;
- struct exchange *exchange;
+ int i;
+ struct exchange *exchange;
- for (i = 0; i <= bucket_mask; i++)
- for (exchange = LIST_FIRST (&exchange_tab[i]); exchange;
- exchange = LIST_NEXT (exchange, link))
- exchange_dump_real ("exchange_report", exchange, LOG_REPORT, 0);
+ for (i = 0; i <= bucket_mask; i++)
+ for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
+ exchange = LIST_NEXT(exchange, link))
+ exchange_dump_real("exchange_report", exchange, LOG_REPORT, 0);
}
/*
@@ -1250,87 +1180,84 @@ exchange_report (void)
* will be dealt with therein instead.
*/
static void
-exchange_free_aux (void *v_exch)
+exchange_free_aux(void *v_exch)
{
- struct exchange *exchange = v_exch;
- struct sa *sa, *next_sa;
- struct cert_handler *handler;
+ struct exchange *exchange = v_exch;
+ struct sa *sa, *next_sa;
+ struct cert_handler *handler;
- LOG_DBG ((LOG_EXCHANGE, 80, "exchange_free_aux: freeing exchange %p",
+ LOG_DBG((LOG_EXCHANGE, 80, "exchange_free_aux: freeing exchange %p",
exchange));
- if (exchange->last_received)
- message_free (exchange->last_received);
- if (exchange->last_sent)
- message_free (exchange->last_sent);
- if (exchange->in_transit && exchange->in_transit != exchange->last_sent)
- message_free (exchange->in_transit);
- if (exchange->nonce_i)
- free (exchange->nonce_i);
- if (exchange->nonce_r)
- free (exchange->nonce_r);
- if (exchange->id_i)
- free (exchange->id_i);
- if (exchange->id_r)
- free (exchange->id_r);
- if (exchange->keystate)
- free (exchange->keystate);
- if (exchange->doi && exchange->doi->free_exchange_data)
- exchange->doi->free_exchange_data (exchange->data);
- if (exchange->data)
- free (exchange->data);
- if (exchange->name)
- free (exchange->name);
- if (exchange->recv_cert)
- {
- handler = cert_get (exchange->recv_certtype);
- if (handler)
- handler->cert_free (exchange->recv_cert);
- }
- if (exchange->sent_cert)
- {
- handler = cert_get (exchange->sent_certtype);
- if (handler)
- handler->cert_free (exchange->sent_cert);
- }
- if (exchange->recv_key)
- key_free (exchange->recv_keytype, ISAKMP_KEYTYPE_PUBLIC,
- exchange->recv_key);
- if (exchange->keynote_key)
- free (exchange->keynote_key); /* This is just a string */
+ if (exchange->last_received)
+ message_free(exchange->last_received);
+ if (exchange->last_sent)
+ message_free(exchange->last_sent);
+ if (exchange->in_transit && exchange->in_transit != exchange->last_sent)
+ message_free(exchange->in_transit);
+ if (exchange->nonce_i)
+ free(exchange->nonce_i);
+ if (exchange->nonce_r)
+ free(exchange->nonce_r);
+ if (exchange->id_i)
+ free(exchange->id_i);
+ if (exchange->id_r)
+ free(exchange->id_r);
+ if (exchange->keystate)
+ free(exchange->keystate);
+ if (exchange->doi && exchange->doi->free_exchange_data)
+ exchange->doi->free_exchange_data(exchange->data);
+ if (exchange->data)
+ free(exchange->data);
+ if (exchange->name)
+ free(exchange->name);
+ if (exchange->recv_cert) {
+ handler = cert_get(exchange->recv_certtype);
+ if (handler)
+ handler->cert_free(exchange->recv_cert);
+ }
+ if (exchange->sent_cert) {
+ handler = cert_get(exchange->sent_certtype);
+ if (handler)
+ handler->cert_free(exchange->sent_cert);
+ }
+ if (exchange->recv_key)
+ key_free(exchange->recv_keytype, ISAKMP_KEYTYPE_PUBLIC,
+ exchange->recv_key);
+ if (exchange->keynote_key)
+ free(exchange->keynote_key); /* This is just a string */
#if defined (POLICY) || defined (KEYNOTE)
- if (exchange->policy_id != -1)
- kn_close (exchange->policy_id);
+ if (exchange->policy_id != -1)
+ kn_close(exchange->policy_id);
#endif
- exchange_free_aca_list (exchange);
- LIST_REMOVE (exchange, link);
+ exchange_free_aca_list(exchange);
+ LIST_REMOVE(exchange, link);
- /* Tell potential finalize routine we never got there. */
- if (exchange->finalize)
- exchange->finalize (exchange, exchange->finalize_arg, 1);
+ /* Tell potential finalize routine we never got there. */
+ if (exchange->finalize)
+ exchange->finalize(exchange, exchange->finalize_arg, 1);
- /* Remove any SAs that have not been disassociated from us. */
- for (sa = TAILQ_FIRST (&exchange->sa_list); sa; sa = next_sa)
- {
- next_sa = TAILQ_NEXT (sa, next);
- /* One for the reference in exchange->sa_list. */
- sa_release (sa);
- /* And two more for the expiration and SA linked list. */
- sa_free (sa);
- }
+ /* Remove any SAs that have not been disassociated from us. */
+ for (sa = TAILQ_FIRST(&exchange->sa_list); sa; sa = next_sa) {
+ next_sa = TAILQ_NEXT(sa, next);
+ /* One for the reference in exchange->sa_list. */
+ sa_release(sa);
+ /* And two more for the expiration and SA linked list. */
+ sa_free(sa);
+ }
- free (exchange);
+ free(exchange);
}
/* Release all resources this exchange is using. */
void
-exchange_free (struct exchange *exchange)
+exchange_free(struct exchange *exchange)
{
- if (exchange->death)
- timer_remove_event (exchange->death);
- exchange_free_aux (exchange);
+ if (exchange->death)
+ timer_remove_event(exchange->death);
+ exchange_free_aux(exchange);
}
/*
@@ -1338,411 +1265,381 @@ exchange_free (struct exchange *exchange)
* peer (found in his recently sent message MSG).
*/
void
-exchange_upgrade_p1 (struct message *msg)
+exchange_upgrade_p1(struct message *msg)
{
- struct exchange *exchange = msg->exchange;
+ struct exchange *exchange = msg->exchange;
- LIST_REMOVE (exchange, link);
- GET_ISAKMP_HDR_RCOOKIE (msg->iov[0].iov_base,
- exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
- exchange_enter (exchange);
- sa_isakmp_upgrade (msg);
+ LIST_REMOVE(exchange, link);
+ GET_ISAKMP_HDR_RCOOKIE(msg->iov[0].iov_base, exchange->cookies +
+ ISAKMP_HDR_ICOOKIE_LEN);
+ exchange_enter(exchange);
+ sa_isakmp_upgrade(msg);
}
static int
-exchange_check_old_sa (struct sa *sa, void *v_arg)
+exchange_check_old_sa(struct sa *sa, void *v_arg)
{
- struct sa *new_sa = v_arg;
- char res1[1024];
+ struct sa *new_sa = v_arg;
+ char res1[1024];
- if (sa == new_sa || !sa->name || !(sa->flags & SA_FLAG_READY)
- || (sa->flags & SA_FLAG_REPLACED))
- return 0;
+ if (sa == new_sa || !sa->name || !(sa->flags & SA_FLAG_READY) ||
+ (sa->flags & SA_FLAG_REPLACED))
+ return 0;
- if (sa->phase != new_sa->phase || new_sa->name == 0
- || strcasecmp (sa->name, new_sa->name))
- return 0;
+ if (sa->phase != new_sa->phase || new_sa->name == 0 ||
+ strcasecmp(sa->name, new_sa->name))
+ return 0;
- if (sa->initiator)
- strlcpy (res1, ipsec_decode_ids ("%s %s", sa->id_i, sa->id_i_len, sa->id_r,
- sa->id_r_len, 0), sizeof res1);
- else
- strlcpy (res1, ipsec_decode_ids ("%s %s", sa->id_r, sa->id_r_len, sa->id_i,
- sa->id_i_len, 0), sizeof res1);
+ if (sa->initiator)
+ strlcpy(res1, ipsec_decode_ids("%s %s", sa->id_i, sa->id_i_len,
+ sa->id_r, sa->id_r_len, 0), sizeof res1);
+ else
+ strlcpy(res1, ipsec_decode_ids("%s %s", sa->id_r, sa->id_r_len,
+ sa->id_i, sa->id_i_len, 0), sizeof res1);
- LOG_DBG ((LOG_EXCHANGE, 30,
+ LOG_DBG((LOG_EXCHANGE, 30,
"checking whether new SA replaces existing SA with IDs %s", res1));
- if (new_sa->initiator)
- return strcasecmp (res1, ipsec_decode_ids ("%s %s", new_sa->id_i,
- new_sa->id_i_len, new_sa->id_r,
- new_sa->id_r_len, 0)) == 0;
- else
- return strcasecmp (res1, ipsec_decode_ids ("%s %s", new_sa->id_r,
- new_sa->id_r_len, new_sa->id_i,
- new_sa->id_i_len, 0)) == 0;
+ if (new_sa->initiator)
+ return strcasecmp(res1, ipsec_decode_ids("%s %s", new_sa->id_i,
+ new_sa->id_i_len, new_sa->id_r, new_sa->id_r_len, 0)) == 0;
+ else
+ return strcasecmp(res1, ipsec_decode_ids("%s %s", new_sa->id_r,
+ new_sa->id_r_len, new_sa->id_i, new_sa->id_i_len, 0)) == 0;
}
void
-exchange_finalize (struct message *msg)
+exchange_finalize(struct message *msg)
{
- struct exchange *exchange = msg->exchange;
- struct sa *sa, *old_sa;
- struct proto *proto;
- struct conf_list *attrs;
- struct conf_list_node *attr;
- struct cert_handler *handler;
- int i;
- char *id_doi, *id_trp;
+ struct exchange *exchange = msg->exchange;
+ struct sa *sa, *old_sa;
+ struct proto *proto;
+ struct conf_list *attrs;
+ struct conf_list_node *attr;
+ struct cert_handler *handler;
+ int i;
+ char *id_doi, *id_trp;
#ifdef USE_DEBUG
- exchange_dump ("exchange_finalize", exchange);
+ exchange_dump("exchange_finalize", exchange);
#endif
- /* Copy the ID from phase 1 to exchange or phase 2 SA. */
- if (msg->isakmp_sa)
- {
- if (exchange->id_i && exchange->id_r)
- {
- ipsec_clone_id (&msg->isakmp_sa->id_i, &msg->isakmp_sa->id_i_len,
- exchange->id_i, exchange->id_i_len);
- ipsec_clone_id (&msg->isakmp_sa->id_r, &msg->isakmp_sa->id_r_len,
- exchange->id_r, exchange->id_r_len);
- }
- else if (msg->isakmp_sa->id_i && msg->isakmp_sa->id_r)
- {
- ipsec_clone_id (&exchange->id_i, &exchange->id_i_len,
- msg->isakmp_sa->id_i, msg->isakmp_sa->id_i_len);
- ipsec_clone_id (&exchange->id_r, &exchange->id_r_len,
- msg->isakmp_sa->id_r, msg->isakmp_sa->id_r_len);
- }
- }
-
- /*
- * Walk over all the SAs and noting them as ready. If we set the
- * COMMIT bit, tell the peer each SA is connected.
- *
- * XXX The decision should really be based on if a SA was installed
- * successfully.
- */
- for (sa = TAILQ_FIRST (&exchange->sa_list); sa; sa = TAILQ_NEXT (sa, next))
- {
- /* Move over the name to the SA. */
- sa->name = exchange->name ? strdup (exchange->name) : 0;
-
- if (exchange->flags & EXCHANGE_FLAG_I_COMMITTED)
- {
- for (proto = TAILQ_FIRST (&sa->protos); proto;
- proto = TAILQ_NEXT (proto, link))
- for (i = 0; i < 2; i++)
- message_send_notification (exchange->last_received,
- msg->isakmp_sa,
- ISAKMP_NOTIFY_STATUS_CONNECTED, proto,
- i);
- }
-
- /* Locate any old SAs and mark them replaced (SA_FLAG_REPLACED). */
- while ((old_sa = sa_find (exchange_check_old_sa, sa)) != 0)
- sa_mark_replaced (old_sa);
-
- /* Setup the SA flags. */
- sa->flags |= SA_FLAG_READY;
- if (exchange->name)
- {
- attrs = conf_get_list (exchange->name, "Flags");
- if (attrs)
- {
- for (attr = TAILQ_FIRST (&attrs->fields); attr;
- attr = TAILQ_NEXT (attr, link))
- sa->flags |= sa_flag (attr->field);
- conf_free_list (attrs);
- }
- /* 'Connections' should stay alive. */
- if (connection_exist (exchange->name))
- {
- sa->flags |= SA_FLAG_STAYALIVE;
-
- /* ISAKMP SA of this connection should also stay alive. */
- if (exchange->phase == 2 && msg->isakmp_sa)
- msg->isakmp_sa->flags |= SA_FLAG_STAYALIVE;
- }
+ /* Copy the ID from phase 1 to exchange or phase 2 SA. */
+ if (msg->isakmp_sa) {
+ if (exchange->id_i && exchange->id_r) {
+ ipsec_clone_id(&msg->isakmp_sa->id_i, &msg->isakmp_sa->id_i_len,
+ exchange->id_i, exchange->id_i_len);
+ ipsec_clone_id(&msg->isakmp_sa->id_r, &msg->isakmp_sa->id_r_len,
+ exchange->id_r, exchange->id_r_len);
+ } else if (msg->isakmp_sa->id_i && msg->isakmp_sa->id_r) {
+ ipsec_clone_id(&exchange->id_i, &exchange->id_i_len,
+ msg->isakmp_sa->id_i, msg->isakmp_sa->id_i_len);
+ ipsec_clone_id(&exchange->id_r, &exchange->id_r_len,
+ msg->isakmp_sa->id_r, msg->isakmp_sa->id_r_len);
+ }
}
-
- sa->seq = exchange->seq;
- sa->exch_type = exchange->type;
- }
-
- /*
- * If this was an phase 1 SA negotiation, save the keystate in the ISAKMP SA
- * structure for future initialization of phase 2 exchanges' keystates.
- * Also save the Phase 1 ID and authentication information.
- */
- if (exchange->phase == 1 && msg->isakmp_sa)
- {
- msg->isakmp_sa->keystate = exchange->keystate;
- exchange->keystate = 0;
-
- msg->isakmp_sa->recv_certtype = exchange->recv_certtype;
- msg->isakmp_sa->sent_certtype = exchange->sent_certtype;
- msg->isakmp_sa->recv_keytype = exchange->recv_keytype;
- msg->isakmp_sa->recv_key = exchange->recv_key;
- msg->isakmp_sa->keynote_key = exchange->keynote_key;
- /* Reset. */
- exchange->recv_key = 0;
- exchange->keynote_key = 0;
- msg->isakmp_sa->policy_id = exchange->policy_id;
- exchange->policy_id = -1;
- msg->isakmp_sa->initiator = exchange->initiator;
-
- if (exchange->recv_certtype && exchange->recv_cert)
- {
- handler = cert_get (exchange->recv_certtype);
- if (handler)
- msg->isakmp_sa->recv_cert
- = handler->cert_dup (exchange->recv_cert);
+ /*
+ * Walk over all the SAs and noting them as ready. If we set the
+ * COMMIT bit, tell the peer each SA is connected.
+ *
+ * XXX The decision should really be based on if a SA was installed
+ * successfully.
+ */
+ for (sa = TAILQ_FIRST(&exchange->sa_list); sa; sa = TAILQ_NEXT(sa, next)) {
+ /* Move over the name to the SA. */
+ sa->name = exchange->name ? strdup(exchange->name) : 0;
+
+ if (exchange->flags & EXCHANGE_FLAG_I_COMMITTED) {
+ for (proto = TAILQ_FIRST(&sa->protos); proto;
+ proto = TAILQ_NEXT(proto, link))
+ for (i = 0; i < 2; i++)
+ message_send_notification(exchange->last_received,
+ msg->isakmp_sa,
+ ISAKMP_NOTIFY_STATUS_CONNECTED,
+ proto, i);
+ }
+ /*
+ * Locate any old SAs and mark them replaced
+ * (SA_FLAG_REPLACED).
+ */
+ while ((old_sa = sa_find(exchange_check_old_sa, sa)) != 0)
+ sa_mark_replaced(old_sa);
+
+ /* Setup the SA flags. */
+ sa->flags |= SA_FLAG_READY;
+ if (exchange->name) {
+ attrs = conf_get_list(exchange->name, "Flags");
+ if (attrs) {
+ for (attr = TAILQ_FIRST(&attrs->fields); attr;
+ attr = TAILQ_NEXT(attr, link))
+ sa->flags |= sa_flag(attr->field);
+ conf_free_list(attrs);
+ }
+ /* 'Connections' should stay alive. */
+ if (connection_exist(exchange->name)) {
+ sa->flags |= SA_FLAG_STAYALIVE;
+
+ /*
+ * ISAKMP SA of this connection should also
+ * stay alive.
+ */
+ if (exchange->phase == 2 && msg->isakmp_sa)
+ msg->isakmp_sa->flags |= SA_FLAG_STAYALIVE;
+ }
+ }
+ sa->seq = exchange->seq;
+ sa->exch_type = exchange->type;
}
- if (exchange->sent_certtype)
- {
- handler = cert_get (exchange->sent_certtype);
- if (handler)
- msg->isakmp_sa->sent_cert
- = handler->cert_dup (exchange->sent_cert);
+ /*
+ * If this was an phase 1 SA negotiation, save the keystate in the
+ * ISAKMP SA structure for future initialization of phase 2 exchanges'
+ * keystates. Also save the Phase 1 ID and authentication
+ * information.
+ */
+ if (exchange->phase == 1 && msg->isakmp_sa) {
+ msg->isakmp_sa->keystate = exchange->keystate;
+ exchange->keystate = 0;
+
+ msg->isakmp_sa->recv_certtype = exchange->recv_certtype;
+ msg->isakmp_sa->sent_certtype = exchange->sent_certtype;
+ msg->isakmp_sa->recv_keytype = exchange->recv_keytype;
+ msg->isakmp_sa->recv_key = exchange->recv_key;
+ msg->isakmp_sa->keynote_key = exchange->keynote_key;
+ /* Reset. */
+ exchange->recv_key = 0;
+ exchange->keynote_key = 0;
+ msg->isakmp_sa->policy_id = exchange->policy_id;
+ exchange->policy_id = -1;
+ msg->isakmp_sa->initiator = exchange->initiator;
+
+ if (exchange->recv_certtype && exchange->recv_cert) {
+ handler = cert_get(exchange->recv_certtype);
+ if (handler)
+ msg->isakmp_sa->recv_cert =
+ handler->cert_dup(exchange->recv_cert);
+ }
+ if (exchange->sent_certtype) {
+ handler = cert_get(exchange->sent_certtype);
+ if (handler)
+ msg->isakmp_sa->sent_cert =
+ handler->cert_dup(exchange->sent_cert);
+ }
+ if (exchange->doi)
+ id_doi = exchange->doi->decode_ids(
+ "initiator id %s, responder id %s",
+ exchange->id_i, exchange->id_i_len,
+ exchange->id_r, exchange->id_r_len, 0);
+ else
+ id_doi = "<no doi>";
+
+ if (msg->isakmp_sa && msg->isakmp_sa->transport)
+ id_trp = msg->isakmp_sa->transport->vtbl->decode_ids(msg->isakmp_sa->transport);
+ else
+ id_trp = "<no transport>";
+
+ LOG_DBG((LOG_EXCHANGE, 10,
+ "exchange_finalize: phase 1 done: %s, %s", id_doi, id_trp));
+
+ log_verbose("isakmpd: phase 1 done: %s, %s", id_doi, id_trp);
}
+ exchange->doi->finalize_exchange(msg);
+ if (exchange->finalize)
+ exchange->finalize(exchange, exchange->finalize_arg, 0);
+ exchange->finalize = 0;
- if (exchange->doi)
- id_doi = exchange->doi->decode_ids ("initiator id %s, responder id %s",
- exchange->id_i, exchange->id_i_len,
- exchange->id_r, exchange->id_r_len,
- 0);
- else
- id_doi = "<no doi>";
-
- if (msg->isakmp_sa && msg->isakmp_sa->transport)
- id_trp = msg->isakmp_sa->transport->vtbl->decode_ids
- (msg->isakmp_sa->transport);
- else
- id_trp = "<no transport>";
-
- LOG_DBG ((LOG_EXCHANGE, 10, "exchange_finalize: phase 1 done: %s, %s",
- id_doi, id_trp));
-
- log_verbose ("isakmpd: phase 1 done: %s, %s", id_doi, id_trp);
- }
-
- exchange->doi->finalize_exchange (msg);
- if (exchange->finalize)
- exchange->finalize (exchange, exchange->finalize_arg, 0);
- exchange->finalize = 0;
-
- /*
- * There is no reason to keep the SAs connected to us anymore, in fact
- * it can hurt us if we have short lifetimes on the SAs and we try
- * to call exchange_report, where the SA list will be walked and
- * references to freed SAs can occur.
- */
- while (TAILQ_FIRST (&exchange->sa_list))
- {
- sa = TAILQ_FIRST (&exchange->sa_list);
-
- if (exchange->id_i && exchange->id_r)
- {
- ipsec_clone_id (&sa->id_i, &sa->id_i_len, exchange->id_i,
- exchange->id_i_len);
- ipsec_clone_id (&sa->id_r, &sa->id_r_len, exchange->id_r,
- exchange->id_r_len);
+ /*
+ * There is no reason to keep the SAs connected to us anymore, in fact
+ * it can hurt us if we have short lifetimes on the SAs and we try
+ * to call exchange_report, where the SA list will be walked and
+ * references to freed SAs can occur.
+ */
+ while (TAILQ_FIRST(&exchange->sa_list)) {
+ sa = TAILQ_FIRST(&exchange->sa_list);
+
+ if (exchange->id_i && exchange->id_r) {
+ ipsec_clone_id(&sa->id_i, &sa->id_i_len, exchange->id_i,
+ exchange->id_i_len);
+ ipsec_clone_id(&sa->id_r, &sa->id_r_len, exchange->id_r,
+ exchange->id_r_len);
+ }
+ TAILQ_REMOVE(&exchange->sa_list, sa, next);
+ sa_release(sa);
}
- TAILQ_REMOVE (&exchange->sa_list, sa, next);
- sa_release (sa);
- }
-
- /* If we have nothing to retransmit we can safely remove ourselves. */
- if (!exchange->last_sent)
- exchange_free (exchange);
+ /* If we have nothing to retransmit we can safely remove ourselves. */
+ if (!exchange->last_sent)
+ exchange_free(exchange);
}
/* Stash a nonce into the exchange data. */
static int
-exchange_nonce (struct exchange *exchange, int peer, size_t nonce_sz,
- u_int8_t *buf)
+exchange_nonce(struct exchange *exchange, int peer, size_t nonce_sz,
+ u_int8_t *buf)
{
- int initiator = exchange->initiator ^ peer;
- u_int8_t **nonce;
- size_t *nonce_len;
- char header[32];
-
- nonce = initiator ? &exchange->nonce_i : &exchange->nonce_r;
- nonce_len = initiator ? &exchange->nonce_i_len : &exchange->nonce_r_len;
- *nonce_len = nonce_sz;
- *nonce = malloc (nonce_sz);
- if (!*nonce)
- {
- log_error ("exchange_nonce: malloc (%lu) failed", (unsigned long)nonce_sz);
- return -1;
- }
- memcpy (*nonce, buf, nonce_sz);
- snprintf (header, sizeof header, "exchange_nonce: NONCE_%c",
+ int initiator = exchange->initiator ^ peer;
+ u_int8_t **nonce;
+ size_t *nonce_len;
+ char header[32];
+
+ nonce = initiator ? &exchange->nonce_i : &exchange->nonce_r;
+ nonce_len = initiator ? &exchange->nonce_i_len : &exchange->nonce_r_len;
+ *nonce_len = nonce_sz;
+ *nonce = malloc(nonce_sz);
+ if (!*nonce) {
+ log_error("exchange_nonce: malloc (%lu) failed",
+ (unsigned long)nonce_sz);
+ return -1;
+ }
+ memcpy(*nonce, buf, nonce_sz);
+ snprintf(header, sizeof header, "exchange_nonce: NONCE_%c",
initiator ? 'i' : 'r');
- LOG_DBG_BUF ((LOG_EXCHANGE, 80, header, *nonce, nonce_sz));
- return 0;
+ LOG_DBG_BUF((LOG_EXCHANGE, 80, header, *nonce, nonce_sz));
+ return 0;
}
/* Generate our NONCE. */
int
-exchange_gen_nonce (struct message *msg, size_t nonce_sz)
+exchange_gen_nonce(struct message *msg, size_t nonce_sz)
{
- struct exchange *exchange = msg->exchange;
- u_int8_t *buf;
-
- buf = malloc (ISAKMP_NONCE_SZ + nonce_sz);
- if (!buf)
- {
- log_error ("exchange_gen_nonce: malloc (%lu) failed",
- ISAKMP_NONCE_SZ + (unsigned long)nonce_sz);
- return -1;
- }
- getrandom (buf + ISAKMP_NONCE_DATA_OFF, nonce_sz);
- if (message_add_payload (msg, ISAKMP_PAYLOAD_NONCE, buf,
- ISAKMP_NONCE_SZ + nonce_sz, 1))
- {
- free (buf);
- return -1;
- }
- return exchange_nonce (exchange, 0, nonce_sz, buf + ISAKMP_NONCE_DATA_OFF);
+ struct exchange *exchange = msg->exchange;
+ u_int8_t *buf;
+
+ buf = malloc(ISAKMP_NONCE_SZ + nonce_sz);
+ if (!buf) {
+ log_error("exchange_gen_nonce: malloc (%lu) failed",
+ ISAKMP_NONCE_SZ + (unsigned long)nonce_sz);
+ return -1;
+ }
+ getrandom(buf + ISAKMP_NONCE_DATA_OFF, nonce_sz);
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_NONCE, buf,
+ ISAKMP_NONCE_SZ + nonce_sz, 1)) {
+ free(buf);
+ return -1;
+ }
+ return exchange_nonce(exchange, 0, nonce_sz, buf + ISAKMP_NONCE_DATA_OFF);
}
/* Save the peer's NONCE. */
int
-exchange_save_nonce (struct message *msg)
+exchange_save_nonce(struct message *msg)
{
- struct payload *noncep;
- struct exchange *exchange = msg->exchange;
-
- noncep = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_NONCE]);
- noncep->flags |= PL_MARK;
- return exchange_nonce (exchange, 1,
- GET_ISAKMP_GEN_LENGTH (noncep->p)
- - ISAKMP_NONCE_DATA_OFF,
- noncep->p + ISAKMP_NONCE_DATA_OFF);
+ struct payload *noncep;
+ struct exchange *exchange = msg->exchange;
+
+ noncep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NONCE]);
+ noncep->flags |= PL_MARK;
+ return exchange_nonce(exchange, 1, GET_ISAKMP_GEN_LENGTH(noncep->p) -
+ ISAKMP_NONCE_DATA_OFF, noncep->p + ISAKMP_NONCE_DATA_OFF);
}
/* Save the peer's CERT REQuests. */
int
-exchange_save_certreq (struct message *msg)
+exchange_save_certreq(struct message *msg)
{
- struct payload *cp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_CERT_REQ]);
- struct exchange *exchange = msg->exchange;
- struct certreq_aca *aca;
-
- for ( ; cp; cp = TAILQ_NEXT (cp, link))
- {
- cp->flags |= PL_MARK;
- aca = certreq_decode (GET_ISAKMP_CERTREQ_TYPE (cp->p),
- cp->p + ISAKMP_CERTREQ_AUTHORITY_OFF,
- GET_ISAKMP_GEN_LENGTH (cp->p) -
- ISAKMP_CERTREQ_AUTHORITY_OFF);
- if (aca)
- TAILQ_INSERT_TAIL (&exchange->aca_list, aca, link);
- }
-
- return 0;
+ struct payload *cp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_CERT_REQ]);
+ struct exchange *exchange = msg->exchange;
+ struct certreq_aca *aca;
+
+ for (; cp; cp = TAILQ_NEXT(cp, link)) {
+ cp->flags |= PL_MARK;
+ aca = certreq_decode(GET_ISAKMP_CERTREQ_TYPE(cp->p), cp->p +
+ ISAKMP_CERTREQ_AUTHORITY_OFF, GET_ISAKMP_GEN_LENGTH(cp->p)
+ - ISAKMP_CERTREQ_AUTHORITY_OFF);
+ if (aca)
+ TAILQ_INSERT_TAIL(&exchange->aca_list, aca, link);
+ }
+
+ return 0;
}
/* Free the list of pending CERTREQs. */
void
-exchange_free_aca_list (struct exchange *exchange)
+exchange_free_aca_list(struct exchange *exchange)
{
- struct certreq_aca *aca;
-
- for (aca = TAILQ_FIRST (&exchange->aca_list); aca;
- aca = TAILQ_FIRST (&exchange->aca_list))
- {
- if (aca->data)
- {
- if (aca->handler)
- aca->handler->free_aca (aca->data);
- free (aca->data);
+ struct certreq_aca *aca;
+
+ for (aca = TAILQ_FIRST(&exchange->aca_list); aca;
+ aca = TAILQ_FIRST(&exchange->aca_list)) {
+ if (aca->data) {
+ if (aca->handler)
+ aca->handler->free_aca(aca->data);
+ free(aca->data);
+ }
+ TAILQ_REMOVE(&exchange->aca_list, aca, link);
+ free(aca);
}
- TAILQ_REMOVE (&exchange->aca_list, aca, link);
- free (aca);
- }
}
/* Obtain certificates from acceptable certification authority. */
int
-exchange_add_certs (struct message *msg)
+exchange_add_certs(struct message * msg)
{
- struct exchange *exchange = msg->exchange;
- struct certreq_aca *aca;
- u_int8_t *cert = 0, *new_cert = 0;
- u_int32_t certlen;
- u_int8_t *id;
- size_t id_len;
-
- id = exchange->initiator ? exchange->id_r : exchange->id_i;
- id_len = exchange->initiator ? exchange->id_r_len : exchange->id_i_len;
-
- /*
- * Without IDs we cannot handle this yet. Keep the aca_list around for
- * a later step/retry to see if we got the ID by then.
- * Note: A 'return -1' breaks X509-auth interop in the responder case
- * with some IPsec clients that send CERTREQs early (ex SSH Sentinel).
- */
- if (!id)
- return 0;
-
- for (aca = TAILQ_FIRST (&exchange->aca_list); aca;
- aca = TAILQ_NEXT (aca, link))
- {
- /* XXX? If we can not satisfy a CERTREQ we drop the message. */
- if (!aca->handler->cert_obtain (id, id_len, aca->data, &cert, &certlen))
- {
- log_print ("exchange_add_certs: could not obtain cert for a type %d "
- "cert request", aca->id);
- if (cert)
- free (cert);
- return -1;
- }
- new_cert = realloc (cert, ISAKMP_CERT_SZ + certlen);
- if (!new_cert)
- {
- log_error ("exchange_add_certs: realloc (%p, %d) failed", cert,
- ISAKMP_CERT_SZ + certlen);
- if (cert)
- free (cert);
- return -1;
- }
- cert = new_cert;
- memmove (cert + ISAKMP_CERT_DATA_OFF, cert, certlen);
- SET_ISAKMP_CERT_ENCODING (cert, aca->id);
- if (message_add_payload (msg, ISAKMP_PAYLOAD_CERT, cert,
- ISAKMP_CERT_SZ + certlen, 1))
- {
- free (cert);
- return -1;
+ struct exchange *exchange = msg->exchange;
+ struct certreq_aca *aca;
+ u_int8_t *cert = 0, *new_cert = 0;
+ u_int32_t certlen;
+ u_int8_t *id;
+ size_t id_len;
+
+ id = exchange->initiator ? exchange->id_r : exchange->id_i;
+ id_len = exchange->initiator ? exchange->id_r_len : exchange->id_i_len;
+
+ /*
+ * Without IDs we cannot handle this yet. Keep the aca_list around for
+ * a later step/retry to see if we got the ID by then.
+ * Note: A 'return -1' breaks X509-auth interop in the responder case
+ * with some IPsec clients that send CERTREQs early (ex SSH Sentinel).
+ */
+ if (!id)
+ return 0;
+
+ for (aca = TAILQ_FIRST(&exchange->aca_list); aca;
+ aca = TAILQ_NEXT(aca, link)) {
+ /* XXX? If we can not satisfy a CERTREQ we drop the message. */
+ if (!aca->handler->cert_obtain(id, id_len, aca->data, &cert, &certlen)) {
+ log_print("exchange_add_certs: could not obtain cert "
+ "for a type %d cert request", aca->id);
+ if (cert)
+ free(cert);
+ return -1;
+ }
+ new_cert = realloc(cert, ISAKMP_CERT_SZ + certlen);
+ if (!new_cert) {
+ log_error("exchange_add_certs: realloc (%p, %d) failed",
+ cert, ISAKMP_CERT_SZ + certlen);
+ if (cert)
+ free(cert);
+ return -1;
+ }
+ cert = new_cert;
+ memmove(cert + ISAKMP_CERT_DATA_OFF, cert, certlen);
+ SET_ISAKMP_CERT_ENCODING(cert, aca->id);
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_CERT, cert,
+ ISAKMP_CERT_SZ + certlen, 1)) {
+ free(cert);
+ return -1;
+ }
}
- }
- /* We dont need the CERT REQs any more, they are answered. */
- exchange_free_aca_list (exchange);
+ /* We dont need the CERT REQs any more, they are answered. */
+ exchange_free_aca_list(exchange);
- return 0;
+ return 0;
}
static void
-exchange_establish_finalize (struct exchange *exchange, void *arg, int fail)
+exchange_establish_finalize(struct exchange *exchange, void *arg, int fail)
{
- char *name = arg;
+ char *name = arg;
- LOG_DBG ((LOG_EXCHANGE, 20,
- "exchange_establish_finalize: "
+ LOG_DBG((LOG_EXCHANGE, 20, "exchange_establish_finalize: "
"finalizing exchange %p with arg %p (%s) & fail = %d",
exchange, arg, name ? name : "<unnamed>", fail));
- if (!fail)
- exchange_establish (name, 0, 0);
- free (name);
+ if (!fail)
+ exchange_establish(name, 0, 0);
+ free(name);
}
/*
@@ -1750,107 +1647,95 @@ exchange_establish_finalize (struct exchange *exchange, void *arg, int fail)
* taking ARG as an argument to be run after the exchange is ready.
*/
void
-exchange_establish (char *name,
- void (*finalize) (struct exchange *, void *, int),
- void *arg)
+exchange_establish(char *name, void (*finalize)(struct exchange *, void *,
+ int), void *arg)
{
- int phase;
- char *trpt;
- struct transport *transport;
- char *peer;
- struct sa *isakmp_sa;
- struct exchange *exchange;
- phase = conf_get_num (name, "Phase", 0);
-
- /*
- * First of all, never try to establish anything if another exchange of the
- * same kind is running.
- */
- exchange = exchange_lookup_by_name (name, phase);
- if (exchange)
- {
- LOG_DBG ((LOG_EXCHANGE, 40,
- "exchange_establish: %s exchange already exists as %p", name,
- exchange));
- exchange_add_finalization (exchange, finalize, arg);
- return;
- }
-
- switch (phase)
- {
- case 1:
- trpt = conf_get_str (name, "Transport");
- if (!trpt)
- {
- /* Phase 1 transport defaults to "udp". */
- trpt = ISAKMP_DEFAULT_TRANSPORT;
- }
-
- transport = transport_create (trpt, name);
- if (!transport)
- {
- log_print ("exchange_establish: "
- "transport \"%s\" for peer \"%s\" could not be created",
- trpt, name);
- return;
- }
-
- exchange_establish_p1 (transport, 0, 0, name, 0, finalize, arg);
- break;
+ int phase;
+ char *trpt;
+ struct transport *transport;
+ char *peer;
+ struct sa *isakmp_sa;
+ struct exchange *exchange;
+ phase = conf_get_num(name, "Phase", 0);
- case 2:
- peer = conf_get_str (name, "ISAKMP-peer");
- if (!peer)
- {
- log_print ("exchange_establish: No ISAKMP-peer given for \"%s\"",
- name);
- return;
+ /*
+ * First of all, never try to establish anything if another exchange
+ * of the same kind is running.
+ */
+ exchange = exchange_lookup_by_name(name, phase);
+ if (exchange) {
+ LOG_DBG((LOG_EXCHANGE, 40,
+ "exchange_establish: %s exchange already exists as %p", name,
+ exchange));
+ exchange_add_finalization(exchange, finalize, arg);
+ return;
}
-
- isakmp_sa = sa_lookup_by_name (peer, 1);
- if (!isakmp_sa)
- {
- name = strdup (name);
- if (!name)
- {
- log_error ("exchange_establish: strdup (\"%s\") failed", name);
- return;
- }
-
- if (conf_get_num (peer, "Phase", 0) != 1)
- {
- log_print ("exchange_establish: "
- "[%s]:ISAKMP-peer's (%s) phase is not 1", name, peer);
- return;
- }
-
- /*
- * XXX We're losing information here (what the original finalize
- * routine was. As a result, if an exchange does not manage to
- * get through, there may be application-specific information
- * that won't get cleaned up, since no error signalling will be
- * done. This is the case with dynamic SAs and PFKEY.
- */
- exchange_establish (peer, exchange_establish_finalize, name);
- exchange = exchange_lookup_by_name (peer, 1);
- /*
- * If the exchange was correctly initialized, add the original
- * finalization routine; otherwise, call it directly.
- */
- if (exchange)
- exchange_add_finalization (exchange, finalize, arg);
- else
- finalize (0, arg, 1); /* Indicate failure */
- return;
+ switch (phase) {
+ case 1:
+ trpt = conf_get_str(name, "Transport");
+ if (!trpt) {
+ /* Phase 1 transport defaults to "udp". */
+ trpt = ISAKMP_DEFAULT_TRANSPORT;
+ }
+ transport = transport_create(trpt, name);
+ if (!transport) {
+ log_print("exchange_establish: "
+ "transport \"%s\" for peer \"%s\" could not be created",
+ trpt, name);
+ return;
+ }
+ exchange_establish_p1(transport, 0, 0, name, 0, finalize, arg);
+ break;
+
+ case 2:
+ peer = conf_get_str(name, "ISAKMP-peer");
+ if (!peer) {
+ log_print("exchange_establish: No ISAKMP-peer given for \"%s\"",
+ name);
+ return;
+ }
+ isakmp_sa = sa_lookup_by_name(peer, 1);
+ if (!isakmp_sa) {
+ name = strdup(name);
+ if (!name) {
+ log_error("exchange_establish: strdup (\"%s\") failed",
+ name);
+ return;
+ }
+ if (conf_get_num(peer, "Phase", 0) != 1) {
+ log_print("exchange_establish: "
+ "[%s]:ISAKMP-peer's (%s) phase is not 1",
+ name, peer);
+ return;
+ }
+ /*
+ * XXX We're losing information here (what the
+ * original finalize routine was. As a result, if an
+ * exchange does not manage to get through, there may
+ * be application-specific information that won't get
+ * cleaned up, since no error signalling will be done.
+ * This is the case with dynamic SAs and PFKEY.
+ */
+ exchange_establish(peer, exchange_establish_finalize, name);
+ exchange = exchange_lookup_by_name(peer, 1);
+ /*
+ * If the exchange was correctly initialized, add the
+ * original finalization routine; otherwise, call it
+ * directly.
+ */
+ if (exchange)
+ exchange_add_finalization(exchange, finalize, arg);
+ else
+ finalize(0, arg, 1); /* Indicate failure */
+ return;
+ } else
+ exchange_establish_p2(isakmp_sa, 0, name, 0, finalize, arg);
+ break;
+
+ default:
+ log_print("exchange_establish: "
+ "peer \"%s\" does not have a correct phase (%d)",
+ name, phase);
+ break;
}
- else
- exchange_establish_p2 (isakmp_sa, 0, name, 0, finalize, arg);
- break;
-
- default:
- log_print ("exchange_establish: "
- "peer \"%s\" does not have a correct phase (%d)",
- name, phase);
- break;
- }
}
diff --git a/sbin/isakmpd/exchange.h b/sbin/isakmpd/exchange.h
index d4cd76dd9c6..96d71e796bc 100644
--- a/sbin/isakmpd/exchange.h
+++ b/sbin/isakmpd/exchange.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: exchange.h,v 1.25 2004/04/15 18:39:25 deraadt Exp $ */
+/* $OpenBSD: exchange.h,v 1.26 2004/05/03 21:23:51 hshoexer Exp $ */
/* $EOM: exchange.h,v 1.28 2000/09/28 12:54:28 niklas Exp $ */
/*
@@ -71,7 +71,7 @@ struct exchange {
* if the finalization hook is called due to the exchange not running
* to its end normally.
*/
- void (*finalize) (struct exchange *, void *, int);
+ void (*finalize)(struct exchange *, void *, int);
void *finalize_arg;
/* When several SA's are being negotiated we keep them here. */
@@ -111,8 +111,8 @@ struct exchange {
struct doi *doi;
/*
- * A "program counter" into the script that validate message contents for
- * this exchange.
+ * A "program counter" into the script that validate message contents
+ * for this exchange.
*/
int16_t *exch_pc;
@@ -123,8 +123,8 @@ struct exchange {
struct message *last_sent;
/*
- * If some message is queued up for sending, we want to be able to remove
- * it from the queue, when the exchange is deleted.
+ * If some message is queued up for sending, we want to be able to
+ * remove it from the queue, when the exchange is deleted.
*/
struct message *in_transit;
@@ -205,7 +205,7 @@ struct exchange {
/* XXX This is no longer necessary, it is covered by policy. */
/* Acceptable authorities for cert requests. */
- TAILQ_HEAD(aca_head, certreq_aca) aca_list;
+ TAILQ_HEAD(aca_head, certreq_aca) aca_list;
/* DOI-specific opaque data. */
void *data;
@@ -222,29 +222,25 @@ extern int exchange_add_certs(struct message *);
extern void exchange_finalize(struct message *);
extern void exchange_free(struct exchange *);
extern void exchange_free_aca_list(struct exchange *);
-extern void
-exchange_establish(char *name,
- void (*) (struct exchange *, void *, int),
- void *);
- extern void exchange_establish_p1(struct transport *, u_int8_t, u_int32_t,
- char *, void *,
- void (*) (struct exchange *, void *, int),
- void *);
- extern void exchange_establish_p2(struct sa *, u_int8_t, char *, void *,
- void (*) (struct exchange *, void *, int),
- void *);
- extern int exchange_gen_nonce(struct message *, size_t);
- extern void exchange_init(void);
- extern struct exchange *exchange_lookup(u_int8_t *, int);
- extern struct exchange *exchange_lookup_by_name(char *, int);
- extern struct exchange *exchange_lookup_from_icookie(u_int8_t *);
- extern void exchange_report(void);
- extern void exchange_run(struct message *);
- extern int exchange_save_nonce(struct message *);
- extern int exchange_save_certreq(struct message *);
- extern int16_t *exchange_script(struct exchange *);
- extern struct exchange *exchange_setup_p1(struct message *, u_int32_t);
- extern struct exchange *exchange_setup_p2(struct message *, u_int8_t);
- extern void exchange_upgrade_p1(struct message *);
+extern void exchange_establish(char *name, void (*)(struct exchange *,
+ void *, int), void *);
+extern void exchange_establish_p1(struct transport *, u_int8_t, u_int32_t,
+ char *, void *, void (*)(struct exchange *, void *, int),
+ void *);
+extern void exchange_establish_p2(struct sa *, u_int8_t, char *, void *,
+ void (*)(struct exchange *, void *, int), void *);
+extern int exchange_gen_nonce(struct message *, size_t);
+extern void exchange_init(void);
+extern struct exchange *exchange_lookup(u_int8_t *, int);
+extern struct exchange *exchange_lookup_by_name(char *, int);
+extern struct exchange *exchange_lookup_from_icookie(u_int8_t *);
+extern void exchange_report(void);
+extern void exchange_run(struct message *);
+extern int exchange_save_nonce(struct message *);
+extern int exchange_save_certreq(struct message *);
+extern int16_t *exchange_script(struct exchange *);
+extern struct exchange *exchange_setup_p1(struct message *, u_int32_t);
+extern struct exchange *exchange_setup_p2(struct message *, u_int8_t);
+extern void exchange_upgrade_p1(struct message *);
#endif /* _EXCHANGE_H_ */