diff options
author | Hakan Olsson <ho@cvs.openbsd.org> | 2002-06-08 23:16:50 +0000 |
---|---|---|
committer | Hakan Olsson <ho@cvs.openbsd.org> | 2002-06-08 23:16:50 +0000 |
commit | 901a277224c59da450fe2e92709bfff3ad6299a1 (patch) | |
tree | 0858f4f107bd01ee4656357de154fab298733e8b /sbin/isakmpd/isakmp_cfg.c | |
parent | bfb4b7b2960e3f22e4c047b03ed3afbb8f9b9d29 (diff) |
Factor out hash operations, some other cleanup.
Diffstat (limited to 'sbin/isakmpd/isakmp_cfg.c')
-rw-r--r-- | sbin/isakmpd/isakmp_cfg.c | 633 |
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; } |