summaryrefslogtreecommitdiff
path: root/sbin/isakmpd/isakmp_cfg.c
diff options
context:
space:
mode:
authorHakan Olsson <ho@cvs.openbsd.org>2002-06-08 23:16:50 +0000
committerHakan Olsson <ho@cvs.openbsd.org>2002-06-08 23:16:50 +0000
commit901a277224c59da450fe2e92709bfff3ad6299a1 (patch)
tree0858f4f107bd01ee4656357de154fab298733e8b /sbin/isakmpd/isakmp_cfg.c
parentbfb4b7b2960e3f22e4c047b03ed3afbb8f9b9d29 (diff)
Factor out hash operations, some other cleanup.
Diffstat (limited to 'sbin/isakmpd/isakmp_cfg.c')
-rw-r--r--sbin/isakmpd/isakmp_cfg.c633
1 files changed, 305 insertions, 328 deletions
diff --git a/sbin/isakmpd/isakmp_cfg.c b/sbin/isakmpd/isakmp_cfg.c
index 0231e774033..4aa180f845b 100644
--- a/sbin/isakmpd/isakmp_cfg.c
+++ b/sbin/isakmpd/isakmp_cfg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isakmp_cfg.c,v 1.13 2002/06/08 17:35:06 ho Exp $ */
+/* $openbsd: isakmp_cfg.c,v 1.13 2002/06/08 17:35:06 ho Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist. All rights reserved.
@@ -70,11 +70,18 @@ int16_t script_transaction[] = {
};
static int cfg_decode_attribute (u_int16_t, u_int8_t *, u_int16_t, void *);
+static int cfg_encode_attributes (struct isakmp_cfg_attr_head *, u_int32_t,
+ u_int32_t, char *, u_int8_t **, u_int16_t *);
static int cfg_initiator_send_ATTR (struct message *);
static int cfg_initiator_recv_ATTR (struct message *);
static int cfg_responder_recv_ATTR (struct message *);
static int cfg_responder_send_ATTR (struct message *);
+u_int8_t *cfg_add_hash (struct message *);
+int cfg_finalize_hash (struct message *,u_int8_t *, u_int8_t *,
+ u_int16_t);
+int cfg_verify_hash (struct message *msg);
+
/* Server: SET/ACK Client; REQ/REPLY */
int (*isakmp_cfg_initiator[]) (struct message *) = {
cfg_initiator_send_ATTR,
@@ -95,13 +102,8 @@ int (*isakmp_cfg_responder[]) (struct message *) = {
static int
cfg_initiator_send_ATTR (struct message *msg)
{
- struct exchange *exchange = msg->exchange;
struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct ipsec_exch *ie = exchange->data;
- struct hash *hash = hash_get (isa->hash);
- struct prf *prf;
- size_t hashsize = hash->hashsize;
+ struct ipsec_exch *ie = msg->exchange->data;
u_int8_t *hashp = 0, *attrp, *attr;
size_t attrlen, off;
char *id_string, *cfg_mode, *field;
@@ -109,26 +111,18 @@ cfg_initiator_send_ATTR (struct message *msg)
#define CFG_ATTR_BIT_MAX ISAKMP_CFG_ATTR_FUTURE_MIN /* XXX */
bitstr_t bit_decl (attrbits, CFG_ATTR_BIT_MAX);
- if (exchange->phase == 2)
+ if (msg->exchange->phase == 2)
{
- /* We want a HASH payload to start with. XXX Share with others? */
- hashp = malloc (ISAKMP_HASH_SZ + hashsize);
+ hashp = cfg_add_hash (msg);
if (!hashp)
- {
- log_error ("cfg_initiator_send_ATTR: malloc (%lu) failed",
- ISAKMP_HASH_SZ + (unsigned long)hashsize);
- return -1;
- }
- if (message_add_payload (msg, ISAKMP_PAYLOAD_HASH, hashp,
- ISAKMP_HASH_SZ + hashsize, 1))
- {
- free (hashp);
- return -1;
- }
+ return -1;
}
- /* XXX This is wrong. */
- id_string = ipsec_id_string (isakmp_sa->id_i, isakmp_sa->id_i_len);
+ /* We inititated of this exchange, check isakmp_sa for other side. */
+ if (isakmp_sa->initiator)
+ id_string = ipsec_id_string (isakmp_sa->id_r, isakmp_sa->id_r_len);
+ else
+ id_string = ipsec_id_string (isakmp_sa->id_i, isakmp_sa->id_i_len);
if (!id_string)
{
log_print ("cfg_initiator_send_ATTR: cannot parse ID");
@@ -235,7 +229,6 @@ cfg_initiator_send_ATTR (struct message *msg)
if (bit_test (attrbits, bit))
{
attr = attrp + off;
- SET_ISAKMP_ATTR_TYPE (attr, bit);
/* All the other are similar, this is the odd one. */
if (bit == ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY)
@@ -301,6 +294,8 @@ cfg_initiator_send_ATTR (struct message *msg)
}
sa = conf_get_address (id_string, field);
+
+ SET_ISAKMP_ATTR_TYPE (attr, bit);
SET_ISAKMP_ATTR_LENGTH_VALUE (attr, length);
memcpy (attr + ISAKMP_ATTR_VALUE_OFF, sockaddr_addrdata (sa),
length);
@@ -314,19 +309,10 @@ cfg_initiator_send_ATTR (struct message *msg)
goto fail;
}
- if (exchange->phase == 2)
- {
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a,
- isa->skeyid_len);
- if (!prf)
- goto fail;
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, exchange->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- prf->Update (prf->prfctx, attrp, attrlen);
- prf->Final (hashp + ISAKMP_GEN_SZ, prf->prfctx);
- prf_free (prf);
- }
+ if (msg->exchange->phase == 2)
+ if (cfg_finalize_hash (msg, hashp, attrp, attrlen))
+ goto fail;
+
return 0;
fail:
@@ -347,70 +333,21 @@ cfg_initiator_recv_ATTR (struct message *msg)
#ifdef notyet
struct payload *p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]);
#endif
- struct payload *hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
struct exchange *exchange = msg->exchange;
struct ipsec_exch *ie = exchange->data;
struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
struct isakmp_cfg_attr *attr;
- struct prf *prf;
- u_int8_t *hash, *comp_hash;
- size_t hash_len;
struct sockaddr *sa;
char *addr;
if (exchange->phase == 2)
- {
- if (!hashp)
- {
- /* XXX Should another NOTIFY type be used? */
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- log_print ("cfg_initiator_recv_ATTR: phase 2 message missing HASH");
- return -1;
- }
-
- hash = hashp->p;
- hash_len = GET_ISAKMP_GEN_LENGTH (hash);
- comp_hash = malloc (hash_len - ISAKMP_GEN_SZ);
- if (!comp_hash)
- {
- log_error ("cfg_initiator_recv_ATTR: malloc (%lu) failed",
- (unsigned long)hash_len - ISAKMP_GEN_SZ);
- return -1;
- }
-
- /* Verify hash! */
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a,
- isa->skeyid_len);
- if (!prf)
- {
- free (comp_hash);
- return -1;
- }
-
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, exchange->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- prf->Update (prf->prfctx, hash + hash_len,
- msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len);
- prf->Final (comp_hash, prf->prfctx);
- prf_free (prf);
- if (memcmp (hash + ISAKMP_GEN_SZ, comp_hash, hash_len - ISAKMP_GEN_SZ)
- != 0)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- free (comp_hash);
- return -1;
- }
- free (comp_hash);
-
- /* Mark the HASH as handled. */
- hashp->flags |= PL_MARK;
- }
+ if (cfg_verify_hash (msg))
+ return -1;
ie->cfg_id = GET_ISAKMP_ATTRIBUTE_ID (attrp->p);
+ ie->cfg_type = attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF];
- switch (attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF])
+ switch (ie->cfg_type)
{
case ISAKMP_CFG_ACK:
case ISAKMP_CFG_REPLY:
@@ -428,7 +365,7 @@ cfg_initiator_recv_ATTR (struct message *msg)
GET_ISAKMP_GEN_LENGTH (attrp->p)
- ISAKMP_TRANSFORM_SA_ATTRS_OFF, cfg_decode_attribute, ie);
- switch (attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF])
+ switch (ie->cfg_type)
{
case ISAKMP_CFG_ACK:
{
@@ -477,68 +414,20 @@ cfg_responder_recv_ATTR (struct message *msg)
struct exchange *exchange = msg->exchange;
struct payload *attrp
= TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ATTRIBUTE]);
- struct payload *hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
struct ipsec_exch *ie = exchange->data;
struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
struct isakmp_cfg_attr *attr;
struct sockaddr *sa;
- struct prf *prf;
- u_int8_t *hash, *comp_hash;
- size_t hash_len;
char *addr;
if (exchange->phase == 2)
- {
- if (!hashp)
- {
- /* XXX Should another NOTIFY type be used? */
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- log_print ("cfg_responder_recv_ATTR: phase 2 message missing HASH");
- return -1;
- }
-
- hash = hashp->p;
- hash_len = GET_ISAKMP_GEN_LENGTH (hash);
- comp_hash = malloc (hash_len - ISAKMP_GEN_SZ);
- if (!comp_hash)
- {
- log_error ("cfg_responder_recv_ATTR: malloc (%lu) failed",
- (unsigned long)hash_len - ISAKMP_GEN_SZ);
- return -1;
- }
-
- /* Verify hash! */
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a,
- isa->skeyid_len);
- if (!prf)
- {
- free (comp_hash);
- return -1;
- }
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, exchange->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- prf->Update (prf->prfctx, hash + hash_len,
- msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len);
- prf->Final (comp_hash, prf->prfctx);
- prf_free (prf);
- if (memcmp (hash + ISAKMP_GEN_SZ, comp_hash, hash_len - ISAKMP_GEN_SZ)
- != 0)
- {
- message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
- free (comp_hash);
- return -1;
- }
- free (comp_hash);
-
- /* Mark the HASH as handled. */
- hashp->flags |= PL_MARK;
- }
+ if (cfg_verify_hash (msg))
+ return -1;
ie->cfg_id = GET_ISAKMP_ATTRIBUTE_ID (attrp->p);
+ ie->cfg_type = attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF];
- switch (attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF])
+ switch (ie->cfg_type)
{
case ISAKMP_CFG_REQUEST:
case ISAKMP_CFG_SET:
@@ -547,17 +436,15 @@ cfg_responder_recv_ATTR (struct message *msg)
default:
message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
log_print ("cfg_responder_recv_ATTR: "
- "unexpected configuration message type %d",
- attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF]);
+ "unexpected configuration message type %d", ie->cfg_type);
return -1;
}
attribute_map (attrp->p + ISAKMP_ATTRIBUTE_ATTRS_OFF,
GET_ISAKMP_GEN_LENGTH (attrp->p)
- - ISAKMP_TRANSFORM_SA_ATTRS_OFF, cfg_decode_attribute,
- ie);
+ - ISAKMP_TRANSFORM_SA_ATTRS_OFF, cfg_decode_attribute, ie);
- switch (attrp->p[ISAKMP_ATTRIBUTE_TYPE_OFF])
+ switch (ie->cfg_type)
{
case ISAKMP_CFG_REQUEST:
break;
@@ -567,7 +454,7 @@ cfg_responder_recv_ATTR (struct message *msg)
/* SET/ACK -- Client side (SET from server) */
const char *uk_addr = "<unknown>";
- msg->transport->vtbl->get_src (isakmp_sa->transport, &sa);
+ msg->transport->vtbl->get_dst (isakmp_sa->transport, &sa);
if (sockaddr2text (sa, &addr, 0) < 0)
addr = (char *)uk_addr;
@@ -579,6 +466,8 @@ cfg_responder_recv_ATTR (struct message *msg)
if (addr != uk_addr)
free (addr);
+
+ attrp->flags |= PL_MARK;
}
break;
@@ -592,58 +481,221 @@ cfg_responder_recv_ATTR (struct message *msg)
/*
* As "the server", this ends REQ/REPLY mode.
* As "the client", this ends SET/ACK mode.
- * XXX A lot can be shared with initiator_send_ATTR.
*/
static int
cfg_responder_send_ATTR (struct message *msg)
{
- struct exchange *exchange = msg->exchange;
- struct ipsec_exch *ie = exchange->data;
+ struct ipsec_exch *ie = msg->exchange->data;
struct sa *isakmp_sa = msg->isakmp_sa;
- struct ipsec_sa *isa = isakmp_sa->data;
- struct hash *hash = hash_get (isa->hash);
- struct prf *prf;
- size_t hashsize = hash->hashsize;
u_int8_t *hashp = 0, *attrp;
- size_t attrlen, off;
- struct isakmp_cfg_attr *attr;
- struct sockaddr *sa;
- u_int32_t value;
- char *id_string, *field;
- sa_family_t family;
+ u_int16_t attrlen;
+ char *id_string;
+
+ if (msg->exchange->phase == 2)
+ {
+ hashp = cfg_add_hash (msg);
+ if (!hashp)
+ return -1;
+ }
- /*
- * XXX I can only assume it is the client who was the initiator
- * in phase 1, but I have not thought it through thoroughly.
- */
- id_string = ipsec_id_string (isakmp_sa->id_i, isakmp_sa->id_i_len);
+ /* We are responder, check isakmp_sa for other side. */
+ if (isakmp_sa->initiator)
+ id_string = ipsec_id_string (isakmp_sa->id_i, isakmp_sa->id_i_len);
+ else
+ id_string = ipsec_id_string (isakmp_sa->id_r, isakmp_sa->id_r_len);
if (!id_string)
{
log_print ("cfg_responder_send_ATTR: cannot parse client's ID");
- goto fail;
+ return -1;
}
- if (exchange->phase == 2)
+ if (cfg_encode_attributes (&ie->attrs, (ie->cfg_type == ISAKMP_CFG_SET ?
+ ISAKMP_CFG_ACK : ISAKMP_CFG_REPLY),
+ ie->cfg_id, id_string, &attrp, &attrlen))
{
- /* We want a HASH payload to start with. XXX Share with others? */
- hashp = malloc (ISAKMP_HASH_SZ + hashsize);
- if (!hashp)
- {
- log_error ("cfg_responder_send_ATTR: malloc (%lu) failed",
- ISAKMP_HASH_SZ + (unsigned long)hashsize);
- goto fail;
- }
- if (message_add_payload (msg, ISAKMP_PAYLOAD_HASH, hashp,
- ISAKMP_HASH_SZ + hashsize, 1))
+ free (id_string);
+ return -1;
+ }
+ free (id_string);
+
+ if (message_add_payload (msg, ISAKMP_PAYLOAD_ATTRIBUTE, attrp, attrlen, 1))
+ {
+ free (attrp);
+ return -1;
+ }
+
+ if (msg->exchange->phase == 2)
+ if (cfg_finalize_hash (msg, hashp, attrp, attrlen))
+ return -1;
+
+ return 0;
+}
+
+u_int8_t *
+cfg_add_hash (struct message *msg)
+{
+ struct ipsec_sa *isa = msg->isakmp_sa->data;
+ struct hash *hash = hash_get (isa->hash);
+ u_int8_t *hashp;
+
+ hashp = malloc (ISAKMP_HASH_SZ + hash->hashsize);
+ if (!hashp)
+ {
+ log_error ("cfg_add_hash: malloc (%lu) failed",
+ ISAKMP_HASH_SZ + (unsigned long)hash->hashsize);
+ return 0;
+ }
+ if (message_add_payload (msg, ISAKMP_PAYLOAD_HASH, hashp,
+ ISAKMP_HASH_SZ + hash->hashsize, 1))
+ {
+ free (hashp);
+ return 0;
+ }
+ return hashp;
+}
+
+int
+cfg_finalize_hash (struct message *msg, u_int8_t *hashp, u_int8_t *data,
+ u_int16_t length)
+{
+ struct ipsec_sa *isa = msg->isakmp_sa->data;
+ struct prf *prf;
+
+ prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a, isa->skeyid_len);
+ if (!prf)
+ return -1;
+
+ prf->Init (prf->prfctx);
+ prf->Update (prf->prfctx, msg->exchange->message_id,
+ ISAKMP_HDR_MESSAGE_ID_LEN);
+ prf->Update (prf->prfctx, data, length);
+ prf->Final (hashp + ISAKMP_GEN_SZ, prf->prfctx);
+ prf_free (prf);
+ return 0;
+}
+
+int
+cfg_verify_hash (struct message *msg)
+{
+ struct payload *hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
+ struct exchange *exchange = msg->exchange;
+ struct ipsec_sa *isa = msg->isakmp_sa->data;
+ struct prf *prf;
+ u_int8_t *hash, *comp_hash;
+ size_t hash_len;
+
+ if (!hashp)
+ {
+ log_print ("cfg_verify_hash: phase 2 message missing HASH");
+ message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ return -1;
+ }
+
+ hash = hashp->p;
+ hash_len = GET_ISAKMP_GEN_LENGTH (hash);
+ comp_hash = malloc (hash_len - ISAKMP_GEN_SZ);
+ if (!comp_hash)
+ {
+ log_error ("cfg_verify_hash: malloc (%lu) failed",
+ (unsigned long)hash_len - ISAKMP_GEN_SZ);
+ return -1;
+ }
+
+ /* Verify hash. */
+ prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a,
+ isa->skeyid_len);
+ if (!prf)
+ {
+ free (comp_hash);
+ return -1;
+ }
+
+ prf->Init (prf->prfctx);
+ prf->Update (prf->prfctx, exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
+ prf->Update (prf->prfctx, hash + hash_len,
+ msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len);
+ prf->Final (comp_hash, prf->prfctx);
+ prf_free (prf);
+
+ if (memcmp (hash + ISAKMP_GEN_SZ, comp_hash, hash_len - ISAKMP_GEN_SZ) != 0)
+ {
+ message_drop (msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 0);
+ free (comp_hash);
+ return -1;
+ }
+ free (comp_hash);
+
+ /* Mark the HASH as handled. */
+ hashp->flags |= PL_MARK;
+
+ return 0;
+}
+
+/*
+ * Decode the attribute of type TYPE with a LEN length value pointed to by
+ * VALUE. VIE is a pointer to the IPsec exchange context holding the
+ * attributes indexed by type for easy retrieval.
+ */
+static int
+cfg_decode_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
+ void *vie)
+{
+ struct ipsec_exch *ie = vie;
+ struct isakmp_cfg_attr *attr;
+
+ if (type >= ISAKMP_CFG_ATTR_PRIVATE_MIN
+ && type <= ISAKMP_CFG_ATTR_PRIVATE_MAX)
+ return 0;
+ if (type == 0 || type >= ISAKMP_CFG_ATTR_FUTURE_MIN)
+ {
+ LOG_DBG ((LOG_NEGOTIATION, 30,
+ "cfg_decode_attribute: invalid attr type %u", type));
+ return -1;
+ }
+
+ attr = calloc (1, sizeof *attr);
+ if (!attr)
+ {
+ log_error ("cfg_decode_attribute: calloc (1, %lu) failed",
+ (unsigned long)sizeof *attr);
+ return -1;
+ }
+ attr->type = type;
+ attr->length = len;
+ if (len)
+ {
+ attr->value = malloc (len);
+ if (!attr->value)
{
- free (hashp);
- goto fail;
+ log_error ("cfg_decode_attribute: malloc (%d) failed", len);
+ free (attr);
+ /* Should we also deallocate all other values? */
+ return -1;
}
+ memcpy (attr->value, value, len);
}
+ LIST_INSERT_HEAD (&ie->attrs, attr, link);
+ return 0;
+}
- /* Compute reply attribute payload length. */
+/*
+ * Encode list of attributes from ie->attrs into a attribute payload.
+ */
+static int
+cfg_encode_attributes (struct isakmp_cfg_attr_head *attrs, u_int32_t type,
+ u_int32_t cfg_id, char *id_string, u_int8_t **attrp,
+ u_int16_t *len)
+{
+ struct isakmp_cfg_attr *attr;
+ struct sockaddr *sa;
+ sa_family_t family;
+ u_int32_t value;
+ u_int16_t attrlen, off;
+ char *field;
+
+ /* Compute length */
attrlen = ISAKMP_ATTRIBUTE_SZ;
- for (attr = LIST_FIRST (&ie->attrs); attr; attr = LIST_NEXT (attr, link))
+ for (attr = LIST_FIRST (attrs); attr; attr = LIST_NEXT (attr, link))
{
switch (attr->type)
{
@@ -688,89 +740,82 @@ cfg_responder_send_ATTR (struct message *msg)
attrlen += ISAKMP_ATTR_SZ + attr->length;
}
- attrp = calloc (1, attrlen);
- if (!attrp)
+ /* Allocate enough space for the payload */
+ *attrp = calloc (1, attrlen);
+ if (!*attrp)
{
- log_error ("cfg_responder_send_ATTR: calloc (1, %lu) failed",
+ log_error ("cfg_encode_attributes: calloc (1, %lu) failed",
(unsigned long)attrlen);
- goto fail;
- }
-
- if (message_add_payload (msg, ISAKMP_PAYLOAD_ATTRIBUTE, attrp, attrlen, 1))
- {
- free (attrp);
- goto fail;
+ return -1;
}
- SET_ISAKMP_ATTRIBUTE_TYPE (attrp, ISAKMP_CFG_REPLY); /* XXX or ACK */
- SET_ISAKMP_ATTRIBUTE_ID (attrp, ie->cfg_id);
+ SET_ISAKMP_ATTRIBUTE_TYPE (*attrp, type);
+ SET_ISAKMP_ATTRIBUTE_ID (*attrp, cfg_id);
off = ISAKMP_ATTRIBUTE_SZ;
- for (attr = LIST_FIRST (&ie->attrs); attr;
- off += ISAKMP_ATTR_SZ + attr->length, attr = LIST_NEXT (attr, link))
+ for (attr = LIST_FIRST (attrs); attr; attr = LIST_NEXT (attr, link))
{
- SET_ISAKMP_ATTR_TYPE (attrp + off, attr->type);
switch (attr->type)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- family = AF_INET;
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- family = AF_INET6;
- break;
-
- default:
- family = 0;
- break;
- }
+ {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ family = AF_INET;
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ family = AF_INET6;
+ break;
+
+ default:
+ family = 0;
+ break;
+ }
switch (attr->type)
- {
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
- field = "Address";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
- field = "Network"; /* XXX or just "Address" */
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
- field = "Netmask";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
- field = "DHCP-server";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
- field = "Nameserver";
- break;
-
- case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
- case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
- field = "WINS-server";
- break;
+ {
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_ADDRESS:
+ field = "Address";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_SUBNET:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET:
+ field = "Network"; /* XXX or just "Address" */
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NETMASK:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NETMASK:
+ field = "Netmask";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DHCP:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DHCP:
+ field = "DHCP-server";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_DNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_DNS:
+ field = "Nameserver";
+ break;
+
+ case ISAKMP_CFG_ATTR_INTERNAL_IP4_NBNS:
+ case ISAKMP_CFG_ATTR_INTERNAL_IP6_NBNS:
+ field = "WINS-server";
+ break;
+
+ default:
+ field = 0;
+ }
- default:
- field = 0;
- }
-
switch (attr->type)
{
case ISAKMP_CFG_ATTR_INTERNAL_IP4_ADDRESS:
@@ -809,7 +854,7 @@ cfg_responder_send_ATTR (struct message *msg)
else if (attr->type == ISAKMP_CFG_ATTR_INTERNAL_IP6_SUBNET)
attr->length = 16;
- memcpy (attrp + off + ISAKMP_ATTR_VALUE_OFF, sockaddr_addrdata (sa),
+ memcpy (*attrp + off + ISAKMP_ATTR_VALUE_OFF, sockaddr_addrdata (sa),
attr->length);
free (sa);
@@ -832,7 +877,7 @@ cfg_responder_send_ATTR (struct message *msg)
attr->length = 0;
break;
}
- memcpy (attrp + off + ISAKMP_ATTR_VALUE_OFF + attr->length,
+ memcpy (*attrp + off + ISAKMP_ATTR_VALUE_OFF + attr->length,
sockaddr_addrdata (sa), attr->length);
attr->length = 8;
free (sa);
@@ -856,14 +901,14 @@ cfg_responder_send_ATTR (struct message *msg)
break;
}
- *(attrp + off + ISAKMP_ATTR_VALUE_OFF + 16) = (u_int8_t)prefix;
+ *(*attrp + off + ISAKMP_ATTR_VALUE_OFF + 16) = (u_int8_t)prefix;
attr->length = 17;
}
break;
case ISAKMP_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY:
value = conf_get_num (id_string, "Lifetime", 1200);
- encode_32 (attrp + off + ISAKMP_ATTR_VALUE_OFF, value);
+ encode_32 (*attrp + off + ISAKMP_ATTR_VALUE_OFF, value);
break;
case ISAKMP_CFG_ATTR_APPLICATION_VERSION:
@@ -876,77 +921,9 @@ cfg_responder_send_ATTR (struct message *msg)
default:
break;
}
- SET_ISAKMP_ATTR_LENGTH_VALUE (attrp + off, attr->length);
- }
-
- if (exchange->phase == 2)
- {
- prf = prf_alloc (isa->prf_type, isa->hash, isa->skeyid_a,
- isa->skeyid_len);
- if (!prf)
- {
- /* XXX Log? */
- goto fail;
- }
- prf->Init (prf->prfctx);
- prf->Update (prf->prfctx, exchange->message_id,
- ISAKMP_HDR_MESSAGE_ID_LEN);
- prf->Update (prf->prfctx, attrp, attrlen);
- prf->Final (hashp + ISAKMP_GEN_SZ, prf->prfctx);
- prf_free (prf);
- }
-
- return 0;
-
- fail:
- if (id_string)
- free (id_string);
- return -1;
-}
-
-/*
- * Decode the attribute of type TYPE with a LEN length value pointed to by
- * VALUE. VIE is a pointer to the IPsec exchange context holding the
- * attributes indexed by type for easy retrieval.
- */
-static int
-cfg_decode_attribute (u_int16_t type, u_int8_t *value, u_int16_t len,
- void *vie)
-{
- struct ipsec_exch *ie = vie;
- struct isakmp_cfg_attr *attr;
- if (type >= ISAKMP_CFG_ATTR_PRIVATE_MIN
- && type <= ISAKMP_CFG_ATTR_PRIVATE_MAX)
- return 0;
- if (type == 0 || type >= ISAKMP_CFG_ATTR_FUTURE_MIN)
- {
- LOG_DBG ((LOG_NEGOTIATION, 30,
- "cfg_decode_attribute: invalid attr type %u", type));
- return -1;
+ SET_ISAKMP_ATTR_LENGTH_VALUE (*attrp + off, attr->length);
}
- attr = calloc (1, sizeof *attr);
- if (!attr)
- {
- log_error ("cfg_decode_attribute: calloc (1, %lu) failed",
- (unsigned long)sizeof *attr);
- return -1;
- }
- attr->type = type;
- attr->length = len;
- if (len)
- {
- attr->value = malloc (len);
- if (!attr->value)
- {
- log_error ("cfg_decode_attribute: malloc (%d) failed", len);
- free (attr);
- /* Should we also deallocate all other values? */
- return -1;
- }
- memcpy (attr->value, value, len);
- }
- LIST_INSERT_HEAD (&ie->attrs, attr, link);
return 0;
}