summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/isakmpd/exchange.c628
1 files changed, 331 insertions, 297 deletions
diff --git a/sbin/isakmpd/exchange.c b/sbin/isakmpd/exchange.c
index 999a9b67777..ff7b00806e0 100644
--- a/sbin/isakmpd/exchange.c
+++ b/sbin/isakmpd/exchange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exchange.c,v 1.93 2004/05/03 21:23:51 hshoexer Exp $ */
+/* $OpenBSD: exchange.c,v 1.94 2004/05/06 10:40:34 ho Exp $ */
/* $EOM: exchange.c,v 1.143 2000/12/04 00:02:25 angelos Exp $ */
/*
@@ -75,12 +75,12 @@
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);
#endif
+static struct exchange *exchange_lookup_active(char *, int);
-static
+static
LIST_HEAD(exchange_list, exchange) *exchange_tab;
/* Works both as a maximum index and a mask. */
@@ -91,77 +91,77 @@ static int bucket_mask;
* 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
- };
+ 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
@@ -188,8 +188,8 @@ exchange_script(struct exchange *exchange)
return script_transaction;
#endif
default:
- if (exchange->type >= ISAKMP_EXCH_DOI_MIN
- && exchange->type <= ISAKMP_EXCH_DOI_MAX)
+ if (exchange->type >= ISAKMP_EXCH_DOI_MIN &&
+ exchange->type <= ISAKMP_EXCH_DOI_MAX)
return exchange->doi->exchange_script(exchange->type);
}
return 0;
@@ -204,7 +204,7 @@ static int
exchange_validate(struct message * msg)
{
struct exchange *exchange = msg->exchange;
- int16_t *pc = exchange->exch_pc;
+ int16_t *pc = exchange->exch_pc;
while (*pc != EXCHANGE_SCRIPT_END && *pc != EXCHANGE_SCRIPT_SWITCH) {
LOG_DBG((LOG_EXCHANGE, 90,
@@ -240,6 +240,32 @@ exchange_validate(struct message * msg)
return 0;
}
+/* Feed unhandled payloads to the DOI for handling. Help for exchange_run(). */
+static void
+exchange_handle_leftover_payloads(struct message *msg)
+{
+ struct exchange *exchange = msg->exchange;
+ struct doi *doi = exchange->doi;
+ struct payload *p;
+ int i;
+
+ for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++) {
+ if (i == ISAKMP_PAYLOAD_PROPOSAL ||
+ i == ISAKMP_PAYLOAD_TRANSFORM)
+ continue;
+ for (p = TAILQ_FIRST(&msg->payload[i]); p;
+ p = TAILQ_NEXT(p, link)) {
+ if (p->flags & PL_MARK)
+ continue;
+ if (!doi->handle_leftover_payload ||
+ doi->handle_leftover_payload(msg, i, p))
+ LOG_DBG((LOG_EXCHANGE, 10,
+ "exchange_run: unexpected payload %s",
+ constant_name(isakmp_payload_cst, i)));
+ }
+ }
+}
+
/*
* Run the exchange script from a point given by the "program counter"
* upto either the script's end or a transmittal of a message. If we are
@@ -250,12 +276,11 @@ exchange_validate(struct message * msg)
void
exchange_run(struct message *msg)
{
- int i, done = 0;
struct exchange *exchange = msg->exchange;
- struct doi *doi = exchange->doi;
+ struct doi *doi = exchange->doi;
int (*handler)(struct message *) = exchange->initiator ?
- doi->initiator : doi->responder;
- struct payload *payload;
+ doi->initiator : doi->responder;
+ int done = 0;
while (!done) {
/*
@@ -307,7 +332,8 @@ exchange_run(struct message *msg)
* 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);
+ message_register_post_send(msg,
+ exchange_finalize);
/* Fallthrough. */
@@ -317,7 +343,8 @@ exchange_run(struct message *msg)
break;
default:
- log_print("exchange_run: exchange_validate failed, DOI error");
+ log_print("exchange_run: exchange_validate "
+ "failed, DOI error");
exchange_free(exchange);
message_free(msg);
return;
@@ -341,23 +368,7 @@ exchange_run(struct message *msg)
* 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)));
- }
- }
- }
- }
- }
+ exchange_handle_leftover_payloads(msg);
/*
* We have advanced the state. If we have
@@ -378,12 +389,14 @@ exchange_run(struct message *msg)
break;
case -1:
- log_print("exchange_run: exchange_validate failed");
+ 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);
+ message_drop(msg,
+ ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
return;
}
}
@@ -402,16 +415,15 @@ exchange_run(struct message *msg)
void
exchange_init()
{
- int i;
+ int i;
bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
- exchange_tab = malloc((bucket_mask + 1) * sizeof(struct exchange_list));
+ 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++) {
+ for (i = 0; i <= bucket_mask; i++)
LIST_INIT(&exchange_tab[i]);
- }
-
}
#if 0
@@ -419,16 +431,16 @@ exchange_init()
static void
exchange_resize(void)
{
- int new_mask = (bucket_mask + 1) * 2 - 1;
- int i;
struct exchange_list *new_tab;
+ int new_mask = (bucket_mask + 1) * 2 - 1;
+ int i;
- new_tab = realloc(exchange_tab, (new_mask + 1) * sizeof(struct exchange_list));
+ 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++) {
+ for (i = bucket_mask + 1; i <= new_mask; i++)
LIST_INIT(&new_tab[i]);
- }
bucket_mask = new_mask;
/* XXX Rehash existing entries. */
}
@@ -438,15 +450,15 @@ exchange_resize(void)
struct exchange *
exchange_lookup_from_icookie(u_int8_t * cookie)
{
- int i;
struct exchange *exchange;
+ int i;
for (i = 0; i <= bucket_mask; i++)
for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
- exchange = LIST_NEXT(exchange, link))
+ exchange = LIST_NEXT(exchange, link))
if (memcmp(exchange->cookies, cookie,
- ISAKMP_HDR_ICOOKIE_LEN) == 0
- && exchange->phase == 1)
+ ISAKMP_HDR_ICOOKIE_LEN) == 0 &&
+ exchange->phase == 1)
return exchange;
return 0;
}
@@ -455,8 +467,8 @@ exchange_lookup_from_icookie(u_int8_t * cookie)
struct exchange *
exchange_lookup_by_name(char *name, int phase)
{
- int i;
struct exchange *exchange;
+ int i;
/* If we search for nothing, we will find nothing. */
if (!name)
@@ -474,10 +486,11 @@ exchange_lookup_by_name(char *name, int 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))
+ 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;
@@ -487,8 +500,8 @@ exchange_lookup_by_name(char *name, int phase)
static struct exchange *
exchange_lookup_active(char *name, int phase)
{
- int i;
struct exchange *exchange;
+ int i;
/* XXX Almost identical to exchange_lookup_by_name. */
@@ -502,14 +515,16 @@ exchange_lookup_active(char *name, int phase)
"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->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));
+ "exchange_lookup_active: avoided "
+ "early (pre-step 1) exchange %p",
+ exchange));
}
}
return 0;
@@ -518,9 +533,9 @@ exchange_lookup_active(char *name, int phase)
static void
exchange_enter(struct exchange *exchange)
{
- u_int16_t bucket = 0;
- int i;
+ u_int16_t bucket = 0;
u_int8_t *cp;
+ int i;
/* XXX We might resize if we are crossing a certain threshold */
@@ -545,17 +560,17 @@ exchange_enter(struct exchange *exchange)
struct exchange *
exchange_lookup(u_int8_t *msg, int phase2)
{
- u_int16_t bucket = 0;
- int i;
struct exchange *exchange;
+ u_int16_t bucket = 0;
u_int8_t *cp;
+ int i;
/*
- * 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.
+ * 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;
@@ -570,13 +585,13 @@ exchange_lookup(u_int8_t *msg, int phase2)
}
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))
+ 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;
@@ -593,8 +608,8 @@ static struct exchange *
exchange_create(int phase, int initiator, int doi, int type)
{
struct exchange *exchange;
- struct timeval expiration;
- int delta;
+ struct timeval expiration;
+ int delta;
/*
* We want the exchange zeroed for exchange_free to be able to find
@@ -630,10 +645,11 @@ exchange_create(int phase, int initiator, int doi, int type)
}
}
gettimeofday(&expiration, 0);
- delta = conf_get_num("General", "Exchange-max-time", EXCHANGE_MAX_TIME);
+ 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);
+ 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);
@@ -643,10 +659,10 @@ exchange_create(int phase, int initiator, int doi, int type)
}
struct exchange_finalization_node {
- void (*first)(struct exchange *, void *, int);
- void *first_arg;
- void (*second)(struct exchange *, void *, int);
- void *second_arg;
+ void (*first)(struct exchange *, void *, int);
+ void *first_arg;
+ void (*second)(struct exchange *, void *, int);
+ void *second_arg;
};
/* Run the finalization functions of ARG. */
@@ -716,14 +732,14 @@ 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;
+ char *tag = 0;
+ char *str;
if (name) {
/* If no exchange type given, fetch from the configuration. */
@@ -746,8 +762,8 @@ exchange_establish_p1(struct transport *t, u_int8_t type, u_int32_t doi,
else if (strcasecmp(str, "ISAKMP") == 0)
doi = ISAKMP_DOI_ISAKMP;
else {
- log_print("exchange_establish_p1: DOI \"%s\" unsupported",
- str);
+ log_print("exchange_establish_p1: "
+ "DOI \"%s\" unsupported", str);
return;
}
@@ -761,8 +777,8 @@ exchange_establish_p1(struct transport *t, u_int8_t type, u_int32_t doi,
}
type = constant_value(isakmp_exch_cst, str);
if (!type) {
- log_print("exchange_setup_p1: unknown exchange type %s",
- str);
+ log_print("exchange_setup_p1: "
+ "unknown exchange type %s", str);
return;
}
}
@@ -775,7 +791,8 @@ exchange_establish_p1(struct transport *t, u_int8_t type, u_int32_t doi,
if (name) {
exchange->name = strdup(name);
if (!exchange->name) {
- log_error("exchange_establish_p1: strdup (\"%s\") failed", name);
+ log_error("exchange_establish_p1: "
+ "strdup (\"%s\") failed", name);
exchange_free(exchange);
return;
}
@@ -785,35 +802,33 @@ exchange_establish_p1(struct transport *t, u_int8_t type, u_int32_t doi,
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;
+ if (name && (flags = conf_get_list(name, "Flags")) != NULL) {
+ 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;
}
- conf_free_list(flags);
- }
+ /*
+ * 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 */
@@ -861,11 +876,11 @@ 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;
+ struct message *msg;
+ u_int32_t doi = ISAKMP_DOI_ISAKMP;
+ u_int32_t seq = 0;
+ int i;
+ char *tag, *str;
if (isakmp_sa)
doi = isakmp_sa->doi->id;
@@ -874,8 +889,8 @@ exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *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);
+ log_print("exchange_establish_p2: "
+ "no configuration for peer \"%s\"", name);
return;
}
seq = (u_int32_t)conf_get_num(name, "Acquire-ID", 0);
@@ -887,7 +902,8 @@ exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *name,
else if (strcasecmp(str, "ISAKMP") == 0)
doi = ISAKMP_DOI_ISAKMP;
else {
- log_print("exchange_establish_p2: DOI \"%s\" unsupported", str);
+ log_print("exchange_establish_p2: "
+ "DOI \"%s\" unsupported", str);
return;
}
@@ -917,7 +933,8 @@ exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *name,
if (name) {
exchange->name = strdup(name);
if (!exchange->name) {
- log_error("exchange_establish_p2: strdup (\"%s\") failed", name);
+ log_error("exchange_establish_p2: "
+ "strdup (\"%s\") failed", name);
exchange_free(exchange);
return;
}
@@ -953,7 +970,7 @@ exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *name,
msg->extra = args;
- /* This needs to be done late or else get_keystate won't work right. */
+ /* This needs to be done late or else get_keystate won't work right. */
msg->exchange = exchange;
exchange_run(msg);
@@ -963,16 +980,16 @@ exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *name,
struct exchange *
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;
+ 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? */
@@ -1019,7 +1036,8 @@ exchange_setup_p1(struct message *msg, u_int32_t doi)
else if (strcasecmp(str, "ISAKMP") == 0)
want_doi = ISAKMP_DOI_ISAKMP;
else {
- log_print("exchange_setup_p1: DOI \"%s\" unsupported", str);
+ log_print("exchange_setup_p1: "
+ "DOI \"%s\" unsupported", str);
return 0;
}
if (want_doi != doi) {
@@ -1036,14 +1054,15 @@ exchange_setup_p1(struct message *msg, u_int32_t doi)
}
type = constant_value(isakmp_exch_cst, str);
if (!type) {
- log_print("exchange_setup_p1: unknown exchange type %s",
- str);
+ 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)));
+ 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;
}
}
@@ -1060,34 +1079,32 @@ exchange_setup_p1(struct message *msg, u_int32_t doi)
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);
+ if (name && (flags = conf_get_list(name, "Flags")) != NULL) {
+ 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;
}
- conf_free_list(flags);
- }
+ /*
+ * 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
@@ -1106,13 +1123,14 @@ struct exchange *
exchange_setup_p2(struct message *msg, u_int8_t doi)
{
struct exchange *exchange;
- u_int8_t *buf = msg->iov[0].iov_base;
+ 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_RCOOKIE(buf,
+ exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
GET_ISAKMP_HDR_MESSAGE_ID(buf, exchange->message_id);
exchange_enter(exchange);
#ifdef USE_DEBUG
@@ -1126,10 +1144,10 @@ static void
exchange_dump_real(char *header, struct exchange *exchange, int class,
int level)
{
- char buf[LOG_SIZE];
+ 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;
+ size_t bufsize_max = LOG_SIZE - strlen(header) - 32;
LOG_DBG((class, level,
"%s: %p %s %s policy %s phase %d doi %d exchange %d step %d",
@@ -1146,7 +1164,8 @@ exchange_dump_real(char *header, struct exchange *exchange, int class,
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);
+ snprintf(buf + strlen(buf), bufsize_max - strlen(buf),
+ "%p ", sa);
if (sa)
strlcat(buf, "...", bufsize_max);
} else
@@ -1165,13 +1184,14 @@ exchange_dump(char *header, struct exchange *exchange)
void
exchange_report(void)
{
- int i;
- struct exchange *exchange;
+ struct exchange *exchange;
+ int i;
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);
+ exchange_dump_real("exchange_report", exchange,
+ LOG_REPORT, 0);
}
/*
@@ -1182,9 +1202,9 @@ exchange_report(void)
static void
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",
exchange));
@@ -1193,7 +1213,8 @@ exchange_free_aux(void *v_exch)
message_free(exchange->last_received);
if (exchange->last_sent)
message_free(exchange->last_sent);
- if (exchange->in_transit && exchange->in_transit != 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);
@@ -1279,8 +1300,8 @@ exchange_upgrade_p1(struct message *msg)
static int
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))
@@ -1311,14 +1332,14 @@ exchange_check_old_sa(struct sa *sa, void *v_arg)
void
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);
@@ -1327,10 +1348,12 @@ exchange_finalize(struct message *msg)
/* 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);
+ 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);
@@ -1345,7 +1368,8 @@ exchange_finalize(struct message *msg)
* 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)) {
+ 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;
@@ -1384,7 +1408,8 @@ exchange_finalize(struct message *msg)
* stay alive.
*/
if (exchange->phase == 2 && msg->isakmp_sa)
- msg->isakmp_sa->flags |= SA_FLAG_STAYALIVE;
+ msg->isakmp_sa->flags |=
+ SA_FLAG_STAYALIVE;
}
}
sa->seq = exchange->seq;
@@ -1434,12 +1459,14 @@ exchange_finalize(struct message *msg)
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);
+ 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));
+ "exchange_finalize: phase 1 done: %s, %s", id_doi,
+ id_trp));
log_verbose("isakmpd: phase 1 done: %s, %s", id_doi, id_trp);
}
@@ -1458,10 +1485,10 @@ exchange_finalize(struct message *msg)
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);
+ 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);
@@ -1477,13 +1504,14 @@ static int
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;
+ int initiator = exchange->initiator ^ peer;
char header[32];
nonce = initiator ? &exchange->nonce_i : &exchange->nonce_r;
- nonce_len = initiator ? &exchange->nonce_i_len : &exchange->nonce_r_len;
+ nonce_len =
+ initiator ? &exchange->nonce_i_len : &exchange->nonce_r_len;
*nonce_len = nonce_sz;
*nonce = malloc(nonce_sz);
if (!*nonce) {
@@ -1503,7 +1531,7 @@ int
exchange_gen_nonce(struct message *msg, size_t nonce_sz)
{
struct exchange *exchange = msg->exchange;
- u_int8_t *buf;
+ u_int8_t *buf;
buf = malloc(ISAKMP_NONCE_SZ + nonce_sz);
if (!buf) {
@@ -1517,14 +1545,15 @@ exchange_gen_nonce(struct message *msg, size_t nonce_sz)
free(buf);
return -1;
}
- return exchange_nonce(exchange, 0, nonce_sz, buf + ISAKMP_NONCE_DATA_OFF);
+ return exchange_nonce(exchange, 0, nonce_sz,
+ buf + ISAKMP_NONCE_DATA_OFF);
}
/* Save the peer's NONCE. */
int
exchange_save_nonce(struct message *msg)
{
- struct payload *noncep;
+ struct payload *noncep;
struct exchange *exchange = msg->exchange;
noncep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NONCE]);
@@ -1537,8 +1566,9 @@ exchange_save_nonce(struct message *msg)
int
exchange_save_certreq(struct message *msg)
{
- struct payload *cp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_CERT_REQ]);
- struct exchange *exchange = msg->exchange;
+ 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)) {
@@ -1589,15 +1619,17 @@ exchange_add_certs(struct message * msg)
* 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).
+ * with some IPsec clients that send CERTREQs early (such as
+ * the 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)) {
+ /* 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)
@@ -1606,8 +1638,8 @@ exchange_add_certs(struct message * msg)
}
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);
+ log_error("exchange_add_certs: realloc (%p, %d) "
+ "failed", cert, ISAKMP_CERT_SZ + certlen);
if (cert)
free(cert);
return -1;
@@ -1631,7 +1663,7 @@ exchange_add_certs(struct message * msg)
static void
exchange_establish_finalize(struct exchange *exchange, void *arg, int fail)
{
- char *name = arg;
+ char *name = arg;
LOG_DBG((LOG_EXCHANGE, 20, "exchange_establish_finalize: "
"finalizing exchange %p with arg %p (%s) & fail = %d",
@@ -1650,12 +1682,12 @@ void
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;
+ struct transport *transport;
+ struct sa *isakmp_sa;
+ struct exchange *exchange;
+ int phase;
+ char *trpt, *peer;
+
phase = conf_get_num(name, "Phase", 0);
/*
@@ -1665,8 +1697,8 @@ exchange_establish(char *name, void (*finalize)(struct exchange *, void *,
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_establish: %s exchange already exists as %p",
+ name, exchange));
exchange_add_finalization(exchange, finalize, arg);
return;
}
@@ -1679,9 +1711,8 @@ exchange_establish(char *name, void (*finalize)(struct exchange *, void *,
}
transport = transport_create(trpt, name);
if (!transport) {
- log_print("exchange_establish: "
- "transport \"%s\" for peer \"%s\" could not be created",
- trpt, name);
+ 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);
@@ -1690,16 +1721,16 @@ exchange_establish(char *name, void (*finalize)(struct exchange *, void *,
case 2:
peer = conf_get_str(name, "ISAKMP-peer");
if (!peer) {
- log_print("exchange_establish: No ISAKMP-peer given for \"%s\"",
- name);
+ 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);
+ log_error("exchange_establish: "
+ "strdup (\"%s\") failed", name);
return;
}
if (conf_get_num(peer, "Phase", 0) != 1) {
@@ -1716,7 +1747,8 @@ exchange_establish(char *name, void (*finalize)(struct exchange *, void *,
* 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_establish(peer, exchange_establish_finalize,
+ name);
exchange = exchange_lookup_by_name(peer, 1);
/*
* If the exchange was correctly initialized, add the
@@ -1724,12 +1756,14 @@ exchange_establish(char *name, void (*finalize)(struct exchange *, void *,
* directly.
*/
if (exchange)
- exchange_add_finalization(exchange, finalize, arg);
+ 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);
+ exchange_establish_p2(isakmp_sa, 0, name, 0, finalize,
+ arg);
break;
default: