summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorHakan Olsson <ho@cvs.openbsd.org>2004-06-20 17:17:36 +0000
committerHakan Olsson <ho@cvs.openbsd.org>2004-06-20 17:17:36 +0000
commitdaefe33e51f796ec859b8a5545e90394afe00af9 (patch)
tree7bab3c8a8dab66dd6b9c16ef2f66b3f3e81acfa9 /sbin
parent7dbb36820e270a6f9f37634264b8474a613d0247 (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.c8
-rw-r--r--sbin/isakmpd/exchange.c25
-rw-r--r--sbin/isakmpd/ike_auth.c10
-rw-r--r--sbin/isakmpd/ike_phase_1.c24
-rw-r--r--sbin/isakmpd/ike_quick_mode.c22
-rw-r--r--sbin/isakmpd/init.c3
-rw-r--r--sbin/isakmpd/ipsec.c10
-rw-r--r--sbin/isakmpd/isakmp_cfg.c11
-rw-r--r--sbin/isakmpd/isakmp_doi.c8
-rw-r--r--sbin/isakmpd/message.c120
-rw-r--r--sbin/isakmpd/message.h12
-rw-r--r--sbin/isakmpd/nat_traversal.c4
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)