diff options
author | Hakan Olsson <ho@cvs.openbsd.org> | 2004-06-20 17:17:36 +0000 |
---|---|---|
committer | Hakan Olsson <ho@cvs.openbsd.org> | 2004-06-20 17:17:36 +0000 |
commit | daefe33e51f796ec859b8a5545e90394afe00af9 (patch) | |
tree | 7bab3c8a8dab66dd6b9c16ef2f66b3f3e81acfa9 /sbin | |
parent | 7dbb36820e270a6f9f37634264b8474a613d0247 (diff) |
Make the payload array in struct message dynamic, since we need to handle
payloads in the private range, such as the pre-RFC NAT-D/NAT-OA.
Replace TAILQ_FIRST(&msg->payload[i]) instances with function calls.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/isakmpd/dpd.c | 8 | ||||
-rw-r--r-- | sbin/isakmpd/exchange.c | 25 | ||||
-rw-r--r-- | sbin/isakmpd/ike_auth.c | 10 | ||||
-rw-r--r-- | sbin/isakmpd/ike_phase_1.c | 24 | ||||
-rw-r--r-- | sbin/isakmpd/ike_quick_mode.c | 22 | ||||
-rw-r--r-- | sbin/isakmpd/init.c | 3 | ||||
-rw-r--r-- | sbin/isakmpd/ipsec.c | 10 | ||||
-rw-r--r-- | sbin/isakmpd/isakmp_cfg.c | 11 | ||||
-rw-r--r-- | sbin/isakmpd/isakmp_doi.c | 8 | ||||
-rw-r--r-- | sbin/isakmpd/message.c | 120 | ||||
-rw-r--r-- | sbin/isakmpd/message.h | 12 | ||||
-rw-r--r-- | sbin/isakmpd/nat_traversal.c | 4 |
12 files changed, 161 insertions, 96 deletions
diff --git a/sbin/isakmpd/dpd.c b/sbin/isakmpd/dpd.c index 6cc52ac17e7..9621fa1b23b 100644 --- a/sbin/isakmpd/dpd.c +++ b/sbin/isakmpd/dpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dpd.c,v 1.1 2004/06/20 15:20:06 ho Exp $ */ +/* $OpenBSD: dpd.c,v 1.2 2004/06/20 17:17:34 ho Exp $ */ /* * Copyright (c) 2004 Håkan Olsson. All rights reserved. @@ -198,8 +198,7 @@ dpd_initiator_send_notify(struct message *msg) static int dpd_initiator_recv_ack(struct message *msg) { - struct payload *p = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); + struct payload *p = payload_first(msg, ISAKMP_PAYLOAD_NOTIFY); struct sa *isakmp_sa = msg->isakmp_sa; struct timeval tv; u_int32_t rseq; @@ -259,8 +258,7 @@ dpd_initiator_recv_ack(struct message *msg) static int dpd_responder_recv_notify(struct message *msg) { - struct payload *p = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); + struct payload *p = payload_first(msg, ISAKMP_PAYLOAD_NOTIFY); struct sa *isakmp_sa = msg->isakmp_sa; struct timeval tv; u_int32_t rseq; diff --git a/sbin/isakmpd/exchange.c b/sbin/isakmpd/exchange.c index 3e37e670f73..28f48df08e7 100644 --- a/sbin/isakmpd/exchange.c +++ b/sbin/isakmpd/exchange.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exchange.c,v 1.97 2004/06/20 15:20:06 ho Exp $ */ +/* $OpenBSD: exchange.c,v 1.98 2004/06/20 17:17:34 ho Exp $ */ /* $EOM: exchange.c,v 1.143 2000/12/04 00:02:25 angelos Exp $ */ /* @@ -221,15 +221,15 @@ exchange_validate(struct message *msg) : constant_name(exchange_script_cst, *pc))); /* Check for existence of the required payloads. */ - if ((*pc > 0 && !TAILQ_FIRST(&msg->payload[*pc])) + if ((*pc > 0 && !payload_first(msg, *pc)) || (*pc == EXCHANGE_SCRIPT_AUTH - && !TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]) - && !TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SIG])) + && !payload_first(msg, ISAKMP_PAYLOAD_HASH) + && !payload_first(msg, 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]))))) { + && ((!payload_first(msg, ISAKMP_PAYLOAD_NOTIFY) + && !payload_first(msg, ISAKMP_PAYLOAD_DELETE)) + || (payload_first(msg, ISAKMP_PAYLOAD_DELETE) + && !payload_first(msg, ISAKMP_PAYLOAD_HASH))))) { /* Missing payload. */ LOG_DBG((LOG_MESSAGE, 70, "exchange_validate: msg %p requires missing %s", @@ -256,11 +256,11 @@ exchange_handle_leftover_payloads(struct message *msg) struct payload *p; int i; - for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++) { + for (i = ISAKMP_PAYLOAD_SA; i < payload_index_max; i++) { if (i == ISAKMP_PAYLOAD_PROPOSAL || i == ISAKMP_PAYLOAD_TRANSFORM) continue; - for (p = TAILQ_FIRST(&msg->payload[i]); p; + for (p = payload_first(msg, i); p; p = TAILQ_NEXT(p, link)) { if (p->flags & PL_MARK) continue; @@ -1566,7 +1566,7 @@ exchange_save_nonce(struct message *msg) struct payload *noncep; struct exchange *exchange = msg->exchange; - noncep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NONCE]); + noncep = payload_first(msg, 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); @@ -1576,8 +1576,7 @@ 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 payload *cp = payload_first(msg, ISAKMP_PAYLOAD_CERT_REQ); struct exchange *exchange = msg->exchange; struct certreq_aca *aca; diff --git a/sbin/isakmpd/ike_auth.c b/sbin/isakmpd/ike_auth.c index 0947e1814fa..bcbf94323fc 100644 --- a/sbin/isakmpd/ike_auth.c +++ b/sbin/isakmpd/ike_auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ike_auth.c,v 1.91 2004/06/14 13:53:31 hshoexer Exp $ */ +/* $OpenBSD: ike_auth.c,v 1.92 2004/06/20 17:17:34 ho Exp $ */ /* $EOM: ike_auth.c,v 1.59 2000/11/21 00:21:31 angelos Exp $ */ /* @@ -513,7 +513,7 @@ pre_shared_decode_hash(struct message *msg) /* Choose the right fields to fill-in. */ hash_p = initiator ? &ie->hash_r : &ie->hash_i; - payload = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]); + payload = payload_first(msg, ISAKMP_PAYLOAD_HASH); if (!payload) { log_print("pre_shared_decode_hash: no HASH payload found"); return -1; @@ -574,7 +574,7 @@ rsa_sig_decode_hash(struct message *msg) * remote... moreover, just use the first CERT payload to decide what * to use. */ - p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_CERT]); + p = payload_first(msg, ISAKMP_PAYLOAD_CERT); if (!p) handler = cert_get(ISAKMP_CERTENC_KEYNOTE); else @@ -631,7 +631,7 @@ rsa_sig_decode_hash(struct message *msg) * XXX I believe this is the wrong spot for this. CERTs can appear * anytime. */ - for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_CERT]); p; + for (p = payload_first(msg, ISAKMP_PAYLOAD_CERT); p; p = TAILQ_NEXT(p, link)) { p->flags |= PL_MARK; @@ -769,7 +769,7 @@ rsa_sig_decode_hash(struct message *msg) log_print("rsa_sig_decode_hash: no public key found"); return -1; } - p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SIG]); + p = payload_first(msg, ISAKMP_PAYLOAD_SIG); if (!p) { log_print("rsa_sig_decode_hash: missing signature payload"); RSA_free(key); diff --git a/sbin/isakmpd/ike_phase_1.c b/sbin/isakmpd/ike_phase_1.c index 6077b6ed3cd..400adab618e 100644 --- a/sbin/isakmpd/ike_phase_1.c +++ b/sbin/isakmpd/ike_phase_1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ike_phase_1.c,v 1.51 2004/06/20 15:24:05 ho Exp $ */ +/* $OpenBSD: ike_phase_1.c,v 1.52 2004/06/20 17:17:35 ho Exp $ */ /* $EOM: ike_phase_1.c,v 1.31 2000/12/11 23:47:56 niklas Exp $ */ /* @@ -352,13 +352,12 @@ ike_phase_1_initiator_send_SA(struct message *msg) goto bail_out; } memcpy(ie->sa_i_b, - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA])->p + ISAKMP_GEN_SZ, + payload_first(msg, ISAKMP_PAYLOAD_SA)->p + ISAKMP_GEN_SZ, sa_len - ISAKMP_GEN_SZ); memcpy(ie->sa_i_b + sa_len - ISAKMP_GEN_SZ, - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_PROPOSAL])->p, - proposal_len); + payload_first(msg, ISAKMP_PAYLOAD_PROPOSAL)->p, proposal_len); transforms_len = 0; - for (i = 0, p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); + for (i = 0, p = payload_first(msg, ISAKMP_PAYLOAD_TRANSFORM); i < conf->cnt; i++, p = TAILQ_NEXT(p, link)) { memcpy(ie->sa_i_b + sa_len + proposal_len + transforms_len - ISAKMP_GEN_SZ, p->p, transform_len[i]); @@ -407,11 +406,9 @@ ike_phase_1_initiator_recv_SA(struct message *msg) struct sa *sa = TAILQ_FIRST(&exchange->sa_list); struct ipsec_exch *ie = exchange->data; struct ipsec_sa *isa = sa->data; - struct payload *sa_p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA]); - struct payload *prop = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]); - struct payload *xf = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); + struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA); + struct payload *prop = payload_first(msg, ISAKMP_PAYLOAD_PROPOSAL); + struct payload *xf = payload_first(msg, ISAKMP_PAYLOAD_TRANSFORM); /* * IKE requires that only one SA with only one proposal exists and @@ -475,9 +472,8 @@ ike_phase_1_responder_recv_SA(struct message *msg) struct exchange *exchange = msg->exchange; struct sa *sa = TAILQ_FIRST(&exchange->sa_list); struct ipsec_sa *isa = sa->data; - struct payload *sa_p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA]); - struct payload *prop = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]); + struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA); + struct payload *prop = payload_first(msg, ISAKMP_PAYLOAD_PROPOSAL); struct ipsec_exch *ie = exchange->data; /* Mark the SA as handled. */ @@ -931,7 +927,7 @@ ike_phase_1_recv_ID(struct message *msg) ssize_t sz; struct sockaddr *sa; - payload = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ID]); + payload = payload_first(msg, ISAKMP_PAYLOAD_ID); if (exchange->name) rs = conf_get_str(exchange->name, "Remote-ID"); diff --git a/sbin/isakmpd/ike_quick_mode.c b/sbin/isakmpd/ike_quick_mode.c index affadfc8b21..547dc23d04f 100644 --- a/sbin/isakmpd/ike_quick_mode.c +++ b/sbin/isakmpd/ike_quick_mode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ike_quick_mode.c,v 1.82 2004/06/15 15:53:13 hshoexer Exp $ */ +/* $OpenBSD: ike_quick_mode.c,v 1.83 2004/06/20 17:17:35 ho Exp $ */ /* $EOM: ike_quick_mode.c,v 1.139 2001/01/26 10:43:17 niklas Exp $ */ /* @@ -1025,12 +1025,10 @@ initiator_recv_HASH_SA_NONCE(struct message *msg) struct ipsec_exch *ie = exchange->data; struct sa *sa; struct proto *proto, *next_proto; - struct payload *sa_p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA]); + struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA); struct payload *xf, *idp; - struct payload *hashp = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]); - struct payload *kep = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]); + struct payload *hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); + struct payload *kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH); struct prf *prf; struct sa *isakmp_sa = msg->isakmp_sa; struct ipsec_sa *isa = isakmp_sa->data; @@ -1099,7 +1097,7 @@ initiator_recv_HASH_SA_NONCE(struct message *msg) ie->pfs = 1; /* Handle optional client ID payloads. */ - idp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ID]); + idp = payload_first(msg, ISAKMP_PAYLOAD_ID); if (idp) { /* If IDci is there, IDcr must be too. */ if (!TAILQ_NEXT(idp, link)) { @@ -1211,7 +1209,7 @@ initiator_recv_HASH_SA_NONCE(struct message *msg) } /* Build the protection suite in our SA. */ - for (xf = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); xf; + for (xf = payload_first(msg, ISAKMP_PAYLOAD_TRANSFORM); xf; xf = TAILQ_NEXT(xf, link)) { /* @@ -1474,7 +1472,7 @@ responder_recv_HASH_SA_NONCE(struct message *msg) struct sockaddr *src, *dst; char *name; - hashp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]); + hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); hash = hashp->p; hashp->flags |= PL_MARK; @@ -1530,12 +1528,12 @@ responder_recv_HASH_SA_NONCE(struct message *msg) /* Mark message as authenticated. */ msg->flags |= MSG_AUTHENTICATED; - kep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]); + kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH); if (kep) ie->pfs = 1; /* Handle optional client ID payloads. */ - idp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ID]); + idp = payload_first(msg, ISAKMP_PAYLOAD_ID); if (idp) { /* If IDci is there, IDcr must be too. */ if (!TAILQ_NEXT(idp, link)) { @@ -1926,7 +1924,7 @@ responder_recv_HASH(struct message *msg) struct payload *hashp; /* Find HASH(3) and create our own hash, just as big. */ - hashp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]); + hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); hash = hashp->p; hashp->flags |= PL_MARK; hash_len = GET_ISAKMP_GEN_LENGTH(hash); diff --git a/sbin/isakmpd/init.c b/sbin/isakmpd/init.c index b6fa322e96c..7e320e14393 100644 --- a/sbin/isakmpd/init.c +++ b/sbin/isakmpd/init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init.c,v 1.30 2004/06/20 15:24:05 ho Exp $ */ +/* $OpenBSD: init.c,v 1.31 2004/06/20 17:17:35 ho Exp $ */ /* $EOM: init.c,v 1.25 2000/03/30 14:27:24 ho Exp $ */ /* @@ -73,6 +73,7 @@ init(void) group_init(); ipsec_init(); isakmp_doi_init(); + message_init(); libcrypto_init(); timer_init(); diff --git a/sbin/isakmpd/ipsec.c b/sbin/isakmpd/ipsec.c index f8033a3c527..8508811f613 100644 --- a/sbin/isakmpd/ipsec.c +++ b/sbin/isakmpd/ipsec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec.c,v 1.97 2004/06/20 15:24:05 ho Exp $ */ +/* $OpenBSD: ipsec.c,v 1.98 2004/06/20 17:17:35 ho Exp $ */ /* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */ /* @@ -1040,7 +1040,7 @@ ipsec_responder(struct message *msg) #endif case ISAKMP_EXCH_INFO: - for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); p; + for (p = payload_first(msg, ISAKMP_PAYLOAD_NOTIFY); p; p = TAILQ_NEXT(p, link)) { type = GET_ISAKMP_NOTIFY_MSG_TYPE(p->p); LOG_DBG((LOG_EXCHANGE, 10, @@ -1083,7 +1083,7 @@ ipsec_responder(struct message *msg) * XXX So far we don't accept any proposals for exchanges we don't * support. */ - if (TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA])) { + if (payload_first(msg, ISAKMP_PAYLOAD_SA)) { message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0); return -1; } @@ -1511,7 +1511,7 @@ ipsec_save_g_x(struct message *msg) struct ipsec_exch *ie = exchange->data; struct payload *kep; - kep = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_KEY_EXCH]); + kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH); kep->flags |= PL_MARK; ie->g_x_len = GET_ISAKMP_GEN_LENGTH(kep->p) - ISAKMP_KE_DATA_OFF; @@ -2249,7 +2249,7 @@ ipsec_fill_in_hash(struct message *msg) if (!isa->skeyid_a) return 0; - payload = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]); + payload = payload_first(msg, ISAKMP_PAYLOAD_HASH); if (!payload) { log_print("ipsec_fill_in_hash: no HASH payload found"); return -1; diff --git a/sbin/isakmpd/isakmp_cfg.c b/sbin/isakmpd/isakmp_cfg.c index f7b4e2a11bf..c5b879dc119 100644 --- a/sbin/isakmpd/isakmp_cfg.c +++ b/sbin/isakmpd/isakmp_cfg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isakmp_cfg.c,v 1.32 2004/06/15 15:53:13 hshoexer Exp $ */ +/* $OpenBSD: isakmp_cfg.c,v 1.33 2004/06/20 17:17:35 ho Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist. All rights reserved. @@ -358,8 +358,7 @@ fail: static int cfg_initiator_recv_ATTR(struct message *msg) { - struct payload *attrp = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]); + struct payload *attrp = payload_first(msg, ISAKMP_PAYLOAD_ATTRIBUTE); struct ipsec_exch *ie = msg->exchange->data; struct sa *isakmp_sa = msg->isakmp_sa; struct isakmp_cfg_attr *attr; @@ -468,8 +467,7 @@ cfg_initiator_recv_ATTR(struct message *msg) static int cfg_responder_recv_ATTR(struct message *msg) { - struct payload *attrp = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]); + struct payload *attrp = payload_first(msg, ISAKMP_PAYLOAD_ATTRIBUTE); struct ipsec_exch *ie = msg->exchange->data; struct sa *isakmp_sa = msg->isakmp_sa; struct isakmp_cfg_attr *attr; @@ -637,8 +635,7 @@ cfg_finalize_hash(struct message *msg, u_int8_t *hashp, u_int8_t *data, int cfg_verify_hash(struct message *msg) { - struct payload *hashp = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]); + struct payload *hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); struct ipsec_sa *isa = msg->isakmp_sa->data; struct prf *prf; u_int8_t *hash, *comp_hash; diff --git a/sbin/isakmpd/isakmp_doi.c b/sbin/isakmpd/isakmp_doi.c index 61e40c10050..2fc8c1dab4c 100644 --- a/sbin/isakmpd/isakmp_doi.c +++ b/sbin/isakmpd/isakmp_doi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isakmp_doi.c,v 1.21 2004/06/14 09:55:41 ho Exp $ */ +/* $OpenBSD: isakmp_doi.c,v 1.22 2004/06/20 17:17:35 ho Exp $ */ /* $EOM: isakmp_doi.c,v 1.42 2000/09/12 16:29:41 ho Exp $ */ /* @@ -230,7 +230,7 @@ isakmp_responder(struct message *msg) switch (msg->exchange->type) { case ISAKMP_EXCH_INFO: - for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NOTIFY]); p; + for (p = payload_first(msg, ISAKMP_PAYLOAD_NOTIFY); p; p = TAILQ_NEXT(p, link)) { LOG_DBG((LOG_EXCHANGE, 10, "isakmp_responder: " "got NOTIFY of type %s, ignoring", @@ -239,7 +239,7 @@ isakmp_responder(struct message *msg) p->flags |= PL_MARK; } - for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_DELETE]); p; + for (p = payload_first(msg, ISAKMP_PAYLOAD_DELETE); p; p = TAILQ_NEXT(p, link)) { LOG_DBG((LOG_EXCHANGE, 10, "isakmp_responder: got DELETE, ignoring")); @@ -254,7 +254,7 @@ isakmp_responder(struct message *msg) default: /* XXX So far we don't accept any proposals. */ - if (TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_SA])) { + if (payload_first(msg, ISAKMP_PAYLOAD_SA)) { message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0); return -1; diff --git a/sbin/isakmpd/message.c b/sbin/isakmpd/message.c index 30bcd0e50be..a01f9935bee 100644 --- a/sbin/isakmpd/message.c +++ b/sbin/isakmpd/message.c @@ -1,4 +1,4 @@ -/* $OpenBSD: message.c,v 1.81 2004/06/20 15:24:05 ho Exp $ */ +/* $OpenBSD: message.c,v 1.82 2004/06/20 17:17:35 ho Exp $ */ /* $EOM: message.c,v 1.156 2000/10/10 12:36:39 provos Exp $ */ /* @@ -123,6 +123,27 @@ static struct field *fields[] = { }; /* + * These maps are used for indexing the payloads in msg->payloads[i]. + * payload_revmap should be updated if the payloads in isakmp_num.cst change. + * payload_map is populated during startup by message_init(). + */ +static u_int8_t payload_revmap[] = { + ISAKMP_PAYLOAD_NONE, ISAKMP_PAYLOAD_SA, ISAKMP_PAYLOAD_PROPOSAL, + ISAKMP_PAYLOAD_TRANSFORM, ISAKMP_PAYLOAD_KEY_EXCH, ISAKMP_PAYLOAD_ID, + ISAKMP_PAYLOAD_CERT, ISAKMP_PAYLOAD_CERT_REQ, ISAKMP_PAYLOAD_HASH, + ISAKMP_PAYLOAD_SIG, ISAKMP_PAYLOAD_NONCE, ISAKMP_PAYLOAD_NOTIFY, + ISAKMP_PAYLOAD_DELETE, ISAKMP_PAYLOAD_VENDOR, ISAKMP_PAYLOAD_ATTRIBUTE, +#ifdef notyet + ISAKMP_PAYLOAD_SAK, ISAKMP_PAYLOAD_SAT, ISAKMP_PAYLOAD_KD, + ISAKMP_PAYLOAD_SEQ, ISAKMP_PAYLOAD_POP +#endif + ISAKMP_PAYLOAD_NAT_D, ISAKMP_PAYLOAD_NAT_OA +}; + +static u_int8_t payload_map[256]; +u_int8_t payload_index_max; + +/* * Fields used for checking monotonic increasing of proposal and transform * numbers. */ @@ -166,7 +187,13 @@ message_alloc(struct transport *t, u_int8_t *buf, size_t sz) ISAKMP_HDR_NEXT_PAYLOAD_OFF; msg->transport = t; transport_reference(t); - for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++) + msg->payload = (struct payload_head *)calloc(payload_index_max, + sizeof *msg->payload); + if (!msg->payload) { + message_free(msg); + return 0; + } + for (i = 0; i < payload_index_max; i++) TAILQ_INIT(&msg->payload[i]); TAILQ_INIT(&msg->post_send); LOG_DBG((LOG_MESSAGE, 90, "message_alloc: allocated %p", msg)); @@ -210,12 +237,15 @@ message_free(struct message *msg) } if (msg->retrans) timer_remove_event(msg->retrans); - for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++) - for (payload = TAILQ_FIRST(&msg->payload[i]); payload; - payload = next) { - next = TAILQ_NEXT(payload, link); - free(payload); - } + if (msg->payload) { + for (i = 0; i < payload_index_max; i++) + for (payload = payload_first(msg, i); payload; + payload = next) { + next = TAILQ_NEXT(payload, link); + free(payload); + } + free(msg->payload); + } while (TAILQ_FIRST(&msg->post_send) != 0) TAILQ_REMOVE(&msg->post_send, TAILQ_FIRST(&msg->post_send), link); @@ -224,7 +254,8 @@ message_free(struct message *msg) if (msg->flags & MSG_IN_TRANSIT) TAILQ_REMOVE(msg->transport->vtbl->get_queue(msg), msg, link); - transport_release(msg->transport); + if (msg->transport) + transport_release(msg->transport); if (msg->isakmp_sa) sa_release(msg->isakmp_sa); @@ -361,7 +392,7 @@ message_parse_proposal(struct message *msg, struct payload *p, ZERO(&payload_set); SET(ISAKMP_PAYLOAD_TRANSFORM, &payload_set); if (message_parse_payloads(msg, - TAILQ_LAST(&msg->payload[ISAKMP_PAYLOAD_PROPOSAL], payload_head), + payload_last(msg, ISAKMP_PAYLOAD_PROPOSAL), ISAKMP_PAYLOAD_TRANSFORM, buf + ISAKMP_PROP_SPI_OFF + GET_ISAKMP_PROP_SPI_SZ(buf), &payload_set, message_parse_transform) == -1) @@ -421,14 +452,18 @@ message_payload_sz(u_int8_t payload) return ISAKMP_VENDOR_SZ; case ISAKMP_PAYLOAD_ATTRIBUTE: return ISAKMP_ATTRIBUTE_SZ; +#if defined (USE_NAT_TRAVERSAL) + case ISAKMP_PAYLOAD_NAT_D: + return ISAKMP_NAT_D_SZ; + case ISAKMP_PAYLOAD_NAT_OA: + return ISAKMP_NAT_OA_SZ; +#endif /* Not yet supported and any other unknown payloads. */ case ISAKMP_PAYLOAD_SAK: case ISAKMP_PAYLOAD_SAT: case ISAKMP_PAYLOAD_KD: case ISAKMP_PAYLOAD_SEQ: case ISAKMP_PAYLOAD_POP: - case ISAKMP_PAYLOAD_NAT_D: - case ISAKMP_PAYLOAD_NAT_OA: default: return 0; } @@ -521,7 +556,8 @@ message_validate_delete(struct message *msg, struct payload *p) /* Only accept authenticated DELETEs. */ if ((msg->flags & MSG_AUTHENTICATED) == 0) { - log_print("message_validate_delete: got unauthenticated DELETE"); + log_print("message_validate_delete: " + "got unauthenticated DELETE"); message_free(msg); return -1; } @@ -617,8 +653,7 @@ message_validate_hash(struct message *msg, struct payload *p) struct sa *isakmp_sa = msg->isakmp_sa; struct ipsec_sa *isa; struct hash *hash; - struct payload *hashp = - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_HASH]); + struct payload *hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); struct prf *prf; u_int8_t *comp_hash, *rest; u_int8_t message_id[ISAKMP_HDR_MESSAGE_ID_LEN]; @@ -685,9 +720,8 @@ message_validate_hash(struct message *msg, struct payload *p) if (memcmp(hashp->p + ISAKMP_HASH_DATA_OFF, comp_hash, hash->hashsize)) { - log_print("message_validate_hash: invalid hash value for " - "%s payload", - TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_DELETE]) ? + log_print("message_validate_hash: invalid hash value for %s " + "payload", payload_first(msg, ISAKMP_PAYLOAD_DELETE) ? "DELETE" : "NOTIFY"); message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0); @@ -1105,7 +1139,8 @@ message_index_payload(struct message *msg, struct payload *p, u_int8_t payload, payload_node->p = buf; payload_node->context = p; payload_node->flags = 0; - TAILQ_INSERT_TAIL(&msg->payload[payload], payload_node, link); + TAILQ_INSERT_TAIL(&msg->payload[payload_map[payload]], payload_node, + link); return 0; } @@ -1122,7 +1157,7 @@ message_sort_payloads(struct message *msg, u_int8_t next) int i, sz; ZERO(&payload_set); - for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++) + for (i = ISAKMP_PAYLOAD_SA; i < payload_index_max; i++) if (i != ISAKMP_PAYLOAD_PROPOSAL && i != ISAKMP_PAYLOAD_TRANSFORM) SET(i, &payload_set); @@ -1143,9 +1178,8 @@ message_validate_payloads(struct message *msg) int i; struct payload *p; - for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_RESERVED_MIN; i++) - for (p = TAILQ_FIRST(&msg->payload[i]); p; - p = TAILQ_NEXT(p, link)) { + for (i = ISAKMP_PAYLOAD_SA; i < payload_index_max; i++) + for (p = payload_first(msg, i); p; p = TAILQ_NEXT(p, link)) { LOG_DBG((LOG_MESSAGE, 60, "message_validate_payloads: " "payload %s at %p of message %p", constant_name(isakmp_payload_cst, i), p->p, msg)); @@ -1588,7 +1622,8 @@ message_add_payload(struct message *msg, u_int8_t payload, u_int8_t *buf, * this situation. */ payload_node->p = buf; - TAILQ_INSERT_TAIL(&msg->payload[payload], payload_node, link); + TAILQ_INSERT_TAIL(&msg->payload[payload_map[payload]], payload_node, + link); return 0; } @@ -2001,7 +2036,7 @@ message_negotiate_sa(struct message *msg, int (*validate)(struct exchange *, */ sa = TAILQ_FIRST(&exchange->sa_list); - for (tp = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); tp; + for (tp = payload_first(msg, ISAKMP_PAYLOAD_TRANSFORM); tp; tp = next_tp) { propp = tp->context; sap = propp->context; @@ -2385,3 +2420,38 @@ message_post_send(struct message *msg) free(node); } } + +/* Initialize and populate payload_map[]. */ +void +message_init(void) +{ + u_int8_t i; + + memset(&payload_map, 0, sizeof payload_map); + + payload_index_max = sizeof payload_revmap / sizeof payload_revmap[0]; + for (i = 0; i < payload_index_max; i++) { + payload_map[payload_revmap[i]] = i; + LOG_DBG((LOG_MESSAGE, 95, "message_init: payload_map[%d] = %d", + payload_revmap[i], i)); + } +} + +struct payload * +payload_first(struct message *msg, u_int8_t payload) +{ + if (payload_map[payload]) + return TAILQ_FIRST(&msg->payload[payload_map[payload]]); + else + return 0; +} + +struct payload * +payload_last(struct message *msg, u_int8_t payload) +{ + if (payload_map[payload]) + return TAILQ_LAST(&msg->payload[payload_map[payload]], + payload_head); + else + return 0; +} diff --git a/sbin/isakmpd/message.h b/sbin/isakmpd/message.h index 709278eeefb..63d05d9f7d3 100644 --- a/sbin/isakmpd/message.h +++ b/sbin/isakmpd/message.h @@ -1,10 +1,10 @@ -/* $OpenBSD: message.h,v 1.20 2004/06/10 12:54:53 hshoexer Exp $ */ +/* $OpenBSD: message.h,v 1.21 2004/06/20 17:17:35 ho Exp $ */ /* $EOM: message.h,v 1.51 2000/10/10 12:36:39 provos Exp $ */ /* * Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved. * Copyright (c) 1999 Angelos D. Keromytis. All rights reserved. - * Copyright (c) 2001 Håkan Olsson. All rights reserved. + * Copyright (c) 2001, 2004 Håkan Olsson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -120,7 +120,7 @@ struct message { u_int8_t *nextp; /* "Smart" pointers to each payload, sorted by type. */ - TAILQ_HEAD(payload_head, payload) payload[ISAKMP_PAYLOAD_RESERVED_MIN]; + TAILQ_HEAD(payload_head, payload) *payload; /* Number of times this message has been sent. */ int xmits; @@ -168,6 +168,9 @@ struct message { TAILQ_HEAD(msg_head, message); +/* The number of different ISAKMP payloads supported. */ +extern u_int8_t payload_index_max; + extern int message_add_payload(struct message *, u_int8_t, u_int8_t *, size_t, int); extern int message_add_sa_payload(struct message *); @@ -177,6 +180,7 @@ extern u_int8_t *message_copy(struct message *, size_t, size_t *); extern void message_drop(struct message *, int, struct proto *, int, int); extern void message_dump_raw(char *, struct message *, int); extern void message_free(struct message *); +extern void message_init(void); extern int message_negotiate_sa(struct message *, int (*)(struct exchange *, struct sa *, struct sa *)); extern int message_recv(struct message *); @@ -191,5 +195,7 @@ extern void message_send_notification(struct message *, struct sa *, u_int16_t, struct proto *, int); extern void message_setup_header(struct message *, u_int8_t, u_int8_t, u_int8_t *); +struct payload *payload_first(struct message *, u_int8_t); +struct payload *payload_last(struct message *, u_int8_t); #endif /* _MESSAGE_H_ */ diff --git a/sbin/isakmpd/nat_traversal.c b/sbin/isakmpd/nat_traversal.c index 83713df201f..50b1c12c8c7 100644 --- a/sbin/isakmpd/nat_traversal.c +++ b/sbin/isakmpd/nat_traversal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nat_traversal.c,v 1.1 2004/06/20 15:24:05 ho Exp $ */ +/* $OpenBSD: nat_traversal.c,v 1.2 2004/06/20 17:17:35 ho Exp $ */ /* * Copyright (c) 2004 Håkan Olsson. All rights reserved. @@ -328,7 +328,7 @@ nat_t_match_nat_d_payload(struct message *msg, struct sockaddr *sa) if (!hbuf) return 0; - for (p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_NAT_D]); p; + for (p = payload_first(msg, ISAKMP_PAYLOAD_NAT_D); p; p = TAILQ_NEXT(p, link)) { if (GET_ISAKMP_GEN_LENGTH (p->p) != hbuflen + ISAKMP_NAT_D_DATA_OFF) |