summaryrefslogtreecommitdiff
path: root/src/pluto/modecfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/modecfg.c')
-rw-r--r--src/pluto/modecfg.c1773
1 files changed, 980 insertions, 793 deletions
diff --git a/src/pluto/modecfg.c b/src/pluto/modecfg.c
index 93624588a..228827f2a 100644
--- a/src/pluto/modecfg.c
+++ b/src/pluto/modecfg.c
@@ -2,7 +2,7 @@
* Copyright (C) 2001-2002 Colubris Networks
* Copyright (C) 2003 Sean Mathews - Nu Tech Software Solutions, inc.
* Copyright (C) 2003-2004 Xelerance Corporation
- * Copyright (C) 2006-2007 Andreas Steffen - Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2006-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -14,8 +14,6 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.c 3738 2008-04-02 19:04:45Z andreas $
- *
* This code originally written by Colubris Networks, Inc.
* Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
* Porting to 2.x by Sean Mathews
@@ -27,6 +25,9 @@
#include <freeswan.h>
+#include <library.h>
+#include <crypto/prfs/prf.h>
+
#include "constants.h"
#include "defs.h"
#include "state.h"
@@ -34,21 +35,23 @@
#include "timer.h"
#include "ipsec_doi.h"
#include "log.h"
-#include "md5.h"
-#include "sha1.h"
#include "crypto.h"
#include "modecfg.h"
#include "whack.h"
#include "xauth.h"
-#define MAX_XAUTH_TRIES 3
+#define MAX_XAUTH_TRIES 3
+#define DNS_SERVER_MAX 2
+#define NBNS_SERVER_MAX 2
#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
- | LELEM(INTERNAL_IP4_NETMASK) \
- | LELEM(INTERNAL_IP4_DNS) \
- | LELEM(INTERNAL_IP4_NBNS) \
- | LELEM(APPLICATION_VERSION) \
- )
+ | LELEM(INTERNAL_IP4_NETMASK) \
+ | LELEM(INTERNAL_IP4_DNS) \
+ | LELEM(INTERNAL_IP4_NBNS) \
+ | LELEM(APPLICATION_VERSION) \
+ | LELEM(INTERNAL_IP6_DNS) \
+ | LELEM(INTERNAL_IP6_NBNS) \
+ )
#define SUPPORTED_UNITY_ATTR_SET ( LELEM(UNITY_BANNER - UNITY_BASE) )
@@ -61,21 +64,21 @@ typedef struct internal_addr internal_addr_t;
struct internal_addr
{
- lset_t attr_set;
- lset_t xauth_attr_set;
- lset_t unity_attr_set;
+ lset_t attr_set;
+ lset_t xauth_attr_set;
+ lset_t unity_attr_set;
- /* ModeCfg variables */
- ip_address ipaddr;
- ip_address dns[2];
- ip_address wins[2];
+ /* ModeCfg variables */
+ ip_address ipaddr;
+ ip_address dns[DNS_SERVER_MAX];
+ ip_address nbns[NBNS_SERVER_MAX];
- char *unity_banner;
+ char *unity_banner;
- /* XAUTH variables */
- u_int16_t xauth_type;
- xauth_t xauth_secret;
- bool xauth_status;
+ /* XAUTH variables */
+ u_int16_t xauth_type;
+ xauth_t xauth_secret;
+ bool xauth_status;
};
/*
@@ -84,20 +87,30 @@ struct internal_addr
static void
init_internal_addr(internal_addr_t *ia)
{
- ia->attr_set = LEMPTY;
- ia->xauth_attr_set = LEMPTY;
- ia->xauth_secret.user_name = empty_chunk;
- ia->xauth_secret.user_password = empty_chunk;
- ia->xauth_type = XAUTH_TYPE_GENERIC;
- ia->xauth_status = XAUTH_STATUS_FAIL;
- ia->unity_attr_set = LEMPTY;
- ia->unity_banner = NULL;
-
- anyaddr(AF_INET, &ia->ipaddr);
- anyaddr(AF_INET, &ia->dns[0]);
- anyaddr(AF_INET, &ia->dns[1]);
- anyaddr(AF_INET, &ia->wins[0]);
- anyaddr(AF_INET, &ia->wins[1]);
+ int i;
+
+ ia->attr_set = LEMPTY;
+ ia->xauth_attr_set = LEMPTY;
+ ia->xauth_secret.user_name = chunk_empty;
+ ia->xauth_secret.user_password = chunk_empty;
+ ia->xauth_type = XAUTH_TYPE_GENERIC;
+ ia->xauth_status = XAUTH_STATUS_FAIL;
+ ia->unity_attr_set = LEMPTY;
+ ia->unity_banner = NULL;
+
+ anyaddr(AF_INET, &ia->ipaddr);
+
+ /* initialize DNS server information */
+ for (i = 0; i < DNS_SERVER_MAX; i++)
+ {
+ anyaddr(AF_INET, &ia->dns[i]);
+ }
+
+ /* initialize WINS server information */
+ for (i = 0; i < NBNS_SERVER_MAX; i++)
+ {
+ anyaddr(AF_INET, &ia->nbns[i]);
+ }
}
/*
@@ -106,97 +119,152 @@ init_internal_addr(internal_addr_t *ia)
static void
get_internal_addr(struct connection *c, internal_addr_t *ia)
{
- if (isanyaddr(&c->spd.that.host_srcip))
- {
- /* not defined in connection - fetch it from LDAP */
- }
- else
- {
- char srcip[ADDRTOT_BUF];
-
- ia->ipaddr = c->spd.that.host_srcip;
-
- addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
- plog("assigning virtual IP source address %s", srcip);
- }
-
- if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
- {
- c->spd.that.client.addr = ia->ipaddr;
- c->spd.that.client.maskbits = 32;
- c->spd.that.has_client = TRUE;
-
- ia->attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
- }
-
- if (!isanyaddr(&ia->dns[0])) /* We got DNS addresses, send them */
- ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
-
- if (!isanyaddr(&ia->wins[0])) /* We got WINS addresses, send them */
- ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
+ int i, dns_idx = 0, nbns_idx = 0;
+
+ if (isanyaddr(&c->spd.that.host_srcip))
+ {
+ /* not defined in connection - fetch it from LDAP */
+ }
+ else
+ {
+ char srcip[ADDRTOT_BUF];
+
+ ia->ipaddr = c->spd.that.host_srcip;
+
+ addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
+ plog("assigning virtual IP source address %s", srcip);
+ }
+
+ if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
+ {
+ c->spd.that.client.addr = ia->ipaddr;
+ c->spd.that.client.maskbits = 32;
+ c->spd.that.has_client = TRUE;
+
+ ia->attr_set = LELEM(INTERNAL_IP4_ADDRESS)
+ | LELEM(INTERNAL_IP4_NETMASK);
+ }
+
+ /* assign DNS servers */
+ for (i = 1; i <= DNS_SERVER_MAX; i++)
+ {
+ char dns_key[16], *dns_str;
+
+ snprintf(dns_key, sizeof(dns_key), "pluto.dns%d", i);
+ dns_str = lib->settings->get_str(lib->settings, dns_key, NULL);
+ if (dns_str)
+ {
+ err_t ugh;
+ sa_family_t family = strchr(dns_str, ':') ? AF_INET6 : AF_INET;
+
+ ugh = ttoaddr(dns_str, 0, family, &ia->dns[dns_idx]);
+ if (ugh != NULL)
+ {
+ plog("error in DNS server address: %s", ugh);
+ continue;
+ }
+ plog("assigning DNS server %s to peer", dns_str);
+
+ /* differentiate between IP4 and IP6 in modecfg_build_msg() */
+ ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
+ dns_idx++;
+ }
+ }
+
+ /* assign WINS servers */
+ for (i = 1; i <= NBNS_SERVER_MAX; i++)
+ {
+ char nbns_key[16], *nbns_str;
+
+ snprintf(nbns_key, sizeof(nbns_key), "pluto.nbns%d", i);
+ nbns_str = lib->settings->get_str(lib->settings, nbns_key, NULL);
+ if (nbns_str)
+ {
+ err_t ugh;
+ sa_family_t family = strchr(nbns_str, ':') ? AF_INET6 : AF_INET;
+
+ ugh = ttoaddr(nbns_str, 0, family, &ia->nbns[nbns_idx]);
+ if (ugh != NULL)
+ {
+ plog("error in WINS server address: %s", ugh);
+ continue;
+ }
+ plog("assigning NBNS server %s to peer", nbns_str);
+
+ /* differentiate between IP4 and IP6 in modecfg_build_msg() */
+ ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
+ nbns_idx++;
+ }
+ }
}
+
/*
* Set srcip and client subnet to internal IP address
*/
static bool
set_internal_addr(struct connection *c, internal_addr_t *ia)
{
- if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
- && !isanyaddr(&ia->ipaddr))
- {
- if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
- || isanyaddr(&c->spd.this.host_srcip)
- || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr))
+ if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
+ && !isanyaddr(&ia->ipaddr))
{
- char srcip[ADDRTOT_BUF];
+ if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
+ || isanyaddr(&c->spd.this.host_srcip)
+ || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr))
+ {
+ char srcip[ADDRTOT_BUF];
- addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
- plog("setting virtual IP source address to %s", srcip);
- }
- else
- {
- char old_srcip[ADDRTOT_BUF];
- char new_srcip[ADDRTOT_BUF];
+ addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
+ plog("setting virtual IP source address to %s", srcip);
+ }
+ else
+ {
+ char old_srcip[ADDRTOT_BUF];
+ char new_srcip[ADDRTOT_BUF];
- addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip));
- addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip));
- plog("replacing virtual IP source address %s by %s"
- , old_srcip, new_srcip);
+ addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip));
+ addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip));
+ plog("replacing virtual IP source address %s by %s"
+ , old_srcip, new_srcip);
+ }
+
+ /* setting srcip */
+ c->spd.this.host_srcip = ia->ipaddr;
+
+ /* setting client subnet to srcip/32 */
+ addrtosubnet(&ia->ipaddr, &c->spd.this.client);
+ setportof(0, &c->spd.this.client.addr);
+ c->spd.this.has_client = TRUE;
+ return TRUE;
}
-
- /* setting srcip */
- c->spd.this.host_srcip = ia->ipaddr;
-
- /* setting client subnet to srcip/32 */
- addrtosubnet(&ia->ipaddr, &c->spd.this.client);
- setportof(0, &c->spd.this.client.addr);
- c->spd.this.has_client = TRUE;
- return TRUE;
- }
- return FALSE;
+ return FALSE;
}
/*
* Compute HASH of Mode Config.
*/
-static size_t
-modecfg_hash(u_char *dest, const u_char *start, const u_char *roof
- , const struct state *st)
+static size_t modecfg_hash(u_char *dest, u_char *start, u_char *roof,
+ const struct state *st)
{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const u_char *) &st->st_msgid, sizeof(st->st_msgid));
- hmac_update(&ctx, start, roof-start);
- hmac_final(dest, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("ModeCfg HASH computed:");
- DBG_dump("", dest, ctx.hmac_digest_size)
- )
- return ctx.hmac_digest_size;
+ chunk_t msgid_chunk = chunk_from_thing(st->st_msgid);
+ chunk_t msg_chunk = { start, roof - start };
+ size_t prf_block_size;
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid_a);
+ prf->get_bytes(prf, msgid_chunk, NULL);
+ prf->get_bytes(prf, msg_chunk, dest);
+ prf_block_size = prf->get_block_size(prf);
+ prf->destroy(prf);
+
+ DBG(DBG_CRYPT,
+ DBG_log("ModeCfg HASH computed:");
+ DBG_dump("", dest, prf_block_size)
+ )
+ return prf_block_size;
}
@@ -205,202 +273,222 @@ modecfg_hash(u_char *dest, const u_char *start, const u_char *roof
*/
static stf_status
modecfg_build_msg(struct state *st, pb_stream *rbody
- , u_int16_t msg_type
- , internal_addr_t *ia
- , u_int16_t ap_id)
+ , u_int16_t msg_type
+ , internal_addr_t *ia
+ , u_int16_t ap_id)
{
- u_char *r_hash_start, *r_hashval;
+ u_char *r_hash_start, *r_hashval;
- START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
+ START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
- /* ATTR out */
- {
- struct isakmp_mode_attr attrh;
- struct isakmp_attribute attr;
- pb_stream strattr,attrval;
- int attr_type;
- int dns_idx, wins_idx;
- bool dont_advance;
- bool is_xauth_attr_set = ia->xauth_attr_set != LEMPTY;
- bool is_unity_attr_set = ia->unity_attr_set != LEMPTY;
- lset_t attr_set = ia->attr_set;
-
- attrh.isama_np = ISAKMP_NEXT_NONE;
- attrh.isama_type = msg_type;
- attrh.isama_identifier = ap_id;
-
- if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
- return STF_INTERNAL_ERROR;
-
- attr_type = 0;
- dns_idx = 0;
- wins_idx = 0;
-
- while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set)
+ /* ATTR out */
{
- if (attr_set == LEMPTY)
- {
- if (is_xauth_attr_set)
- {
- attr_set = ia->xauth_attr_set;
- attr_type = XAUTH_BASE;
- is_xauth_attr_set = FALSE;
- }
- else
+ struct isakmp_mode_attr attrh;
+ struct isakmp_attribute attr;
+ pb_stream strattr,attrval;
+ int attr_type, dns_attr_type, nbns_attr_type;
+ int dns_idx, nbns_idx;
+ bool dont_advance;
+ bool is_xauth_attr_set = ia->xauth_attr_set != LEMPTY;
+ bool is_unity_attr_set = ia->unity_attr_set != LEMPTY;
+ lset_t attr_set = ia->attr_set;
+
+ attrh.isama_np = ISAKMP_NEXT_NONE;
+ attrh.isama_type = msg_type;
+ attrh.isama_identifier = ap_id;
+
+ if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
{
- attr_set = ia->unity_attr_set;
- attr_type = UNITY_BASE;
- is_unity_attr_set = FALSE;
+ return STF_INTERNAL_ERROR;
}
- }
-
- dont_advance = FALSE;
+ attr_type = 0;
+ dns_idx = 0;
+ nbns_idx = 0;
- if (attr_set & 1)
- {
- const u_char *byte_ptr;
- u_int len;
-
- /* ISAKMP attr out */
- if (attr_type == XAUTH_TYPE)
- {
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = ia->xauth_type;
- }
- else if (attr_type == XAUTH_STATUS)
+ while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set)
{
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = ia->xauth_status;
- }
- else
- {
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
- }
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
-
- switch (attr_type)
- {
- case INTERNAL_IP4_ADDRESS:
- if (!isanyaddr(&ia->ipaddr))
- {
- len = addrbytesptr(&ia->ipaddr, &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_addr");
- }
- break;
- case INTERNAL_IP4_NETMASK:
- {
- u_int mask;
-#if 0
- char mask[4],bits[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t,m=st->st_connection->that.host_addr.maskbit;
- for (t=0; t<4; t++)
+ if (attr_set == LEMPTY)
{
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
+ if (is_xauth_attr_set)
+ {
+ attr_set = ia->xauth_attr_set;
+ attr_type = XAUTH_BASE;
+ is_xauth_attr_set = FALSE;
+ }
+ else
+ {
+ attr_set = ia->unity_attr_set;
+ attr_type = UNITY_BASE;
+ is_unity_attr_set = FALSE;
+ }
}
-#endif
- if (st->st_connection->spd.this.client.maskbits == 0)
- mask = 0;
- else
- mask = 0xffffffff * 1;
- out_raw(&mask, 4, &attrval, "IP4_mask");
- }
- break;
- case INTERNAL_IP4_SUBNET:
- {
- char mask[4];
- char bits[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t;
- int m = st->st_connection->spd.this.client.maskbits;
+
+ dont_advance = FALSE;
- for (t = 0; t < 4; t++)
+ if (attr_set & 1)
{
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
- if (m < 0)
- m = 0;
+ const u_char *byte_ptr;
+ u_int len;
+
+ /* ISAKMP attr out */
+ if (attr_type == XAUTH_TYPE)
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
+ attr.isaat_lv = ia->xauth_type;
+ }
+ else if (attr_type == XAUTH_STATUS)
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
+ attr.isaat_lv = ia->xauth_status;
+ }
+ else if (attr_type == INTERNAL_IP4_DNS && !isanyaddr(&ia->dns[dns_idx]))
+ {
+ dns_attr_type = (addrtypeof(&ia->dns[dns_idx]) == AF_INET) ?
+ INTERNAL_IP4_DNS : INTERNAL_IP6_DNS;
+ attr.isaat_af_type = dns_attr_type | ISAKMP_ATTR_AF_TLV;
+
+ }
+ else if (attr_type == INTERNAL_IP4_NBNS && !isanyaddr(&ia->nbns[nbns_idx]))
+ {
+ nbns_attr_type = (addrtypeof(&ia->nbns[nbns_idx]) == AF_INET) ?
+ INTERNAL_IP4_NBNS : INTERNAL_IP6_NBNS;
+ attr.isaat_af_type = nbns_attr_type | ISAKMP_ATTR_AF_TLV;
+
+ }
+ else
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
+ }
+ out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
+
+ switch (attr_type)
+ {
+ case INTERNAL_IP4_ADDRESS:
+ if (!isanyaddr(&ia->ipaddr))
+ {
+ len = addrbytesptr(&ia->ipaddr, &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_addr");
+ }
+ break;
+ case INTERNAL_IP4_NETMASK:
+ {
+ u_int mask;
+#if 0
+ char mask[4],bits[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
+ int t,m=st->st_connection->that.host_addr.maskbit;
+ for (t=0; t<4; t++)
+ {
+ if (m < 8)
+ mask[t] = bits[m];
+ else
+ mask[t] = 0xff;
+ m -= 8;
+ }
+#endif
+ if (st->st_connection->spd.this.client.maskbits == 0)
+ {
+ mask = 0;
+ }
+ else
+ {
+ mask = 0xffffffff * 1;
+ out_raw(&mask, 4, &attrval, "IP4_mask");
+ }
+ }
+ break;
+ case INTERNAL_IP4_SUBNET:
+ {
+ char mask[4];
+ char bits[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
+ int t;
+ int m = st->st_connection->spd.this.client.maskbits;
+
+ for (t = 0; t < 4; t++)
+ {
+ mask[t] = (m < 8) ? bits[m] : 0xff;
+ m -= 8;
+ if (m < 0)
+ {
+ m = 0;
+ }
+ }
+ len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_subnet");
+ out_raw(mask, sizeof(mask), &attrval, "IP4_submsk");
+ }
+ break;
+ case INTERNAL_IP4_DNS:
+ case INTERNAL_IP6_DNS:
+ if (!isanyaddr(&ia->dns[dns_idx]))
+ {
+ len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP_dns");
+ }
+ if (dns_idx < DNS_SERVER_MAX && !isanyaddr(&ia->dns[dns_idx]))
+ {
+ dont_advance = TRUE;
+ }
+ break;
+ case INTERNAL_IP4_NBNS:
+ case INTERNAL_IP6_NBNS:
+ if (!isanyaddr(&ia->nbns[nbns_idx]))
+ {
+ len = addrbytesptr(&ia->nbns[nbns_idx++], &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP_nbns");
+ }
+ if (nbns_idx < NBNS_SERVER_MAX && !isanyaddr(&ia->nbns[nbns_idx]))
+ {
+ dont_advance = TRUE;
+ }
+ break;
+ case XAUTH_TYPE:
+ break;
+ case XAUTH_USER_NAME:
+ if (ia->xauth_secret.user_name.ptr != NULL)
+ {
+ out_raw(ia->xauth_secret.user_name.ptr
+ , ia->xauth_secret.user_name.len
+ , &attrval, "xauth_user_name");
+ }
+ break;
+ case XAUTH_USER_PASSWORD:
+ if (ia->xauth_secret.user_password.ptr != NULL)
+ {
+ out_raw(ia->xauth_secret.user_password.ptr
+ , ia->xauth_secret.user_password.len
+ , &attrval, "xauth_user_password");
+ }
+ break;
+ case XAUTH_STATUS:
+ break;
+ case UNITY_BANNER:
+ if (ia->unity_banner != NULL)
+ {
+ out_raw(ia->unity_banner
+ , strlen(ia->unity_banner)
+ , &attrval, "UNITY_BANNER");
+ }
+ break;
+ default:
+ plog("attempt to send unsupported mode cfg attribute %s."
+ , enum_show(&modecfg_attr_names, attr_type));
+ break;
+ }
+ close_output_pbs(&attrval);
+ }
+ if (!dont_advance)
+ {
+ attr_type++;
+ attr_set >>= 1;
}
- len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_subnet");
- out_raw(mask, sizeof(mask), &attrval, "IP4_submsk");
- }
- break;
- case INTERNAL_IP4_DNS:
- if (!isanyaddr(&ia->dns[dns_idx]))
- {
- len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_dns");
- }
- if (dns_idx < 2 && !isanyaddr(&ia->dns[dns_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- case INTERNAL_IP4_NBNS:
- if (!isanyaddr(&ia->wins[wins_idx]))
- {
- len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_wins");
- }
- if (wins_idx < 2 && !isanyaddr(&ia->wins[wins_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- case XAUTH_TYPE:
- break;
- case XAUTH_USER_NAME:
- if (ia->xauth_secret.user_name.ptr != NULL)
- {
- out_raw(ia->xauth_secret.user_name.ptr
- , ia->xauth_secret.user_name.len
- , &attrval, "xauth_user_name");
- }
- break;
- case XAUTH_USER_PASSWORD:
- if (ia->xauth_secret.user_password.ptr != NULL)
- {
- out_raw(ia->xauth_secret.user_password.ptr
- , ia->xauth_secret.user_password.len
- , &attrval, "xauth_user_password");
- }
- break;
- case XAUTH_STATUS:
- break;
- case UNITY_BANNER:
- if (ia->unity_banner != NULL)
- {
- out_raw(ia->unity_banner
- , strlen(ia->unity_banner)
- , &attrval, "UNITY_BANNER");
- }
- break;
- default:
- plog("attempt to send unsupported mode cfg attribute %s."
- , enum_show(&modecfg_attr_names, attr_type));
- break;
}
- close_output_pbs(&attrval);
- }
- if (!dont_advance)
- {
- attr_type++;
- attr_set >>= 1;
- }
+ close_message(&strattr);
}
- close_message(&strattr);
- }
- modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
- close_message(rbody);
- encrypt_message(rbody, st);
- return STF_OK;
+ modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
+ close_message(rbody);
+ encrypt_message(rbody, st);
+ return STF_OK;
}
/*
@@ -409,55 +497,56 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
static stf_status
modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
{
- pb_stream msg;
- pb_stream rbody;
- char buf[BUF_LEN];
-
- /* set up attr */
- init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
-
- /* this is the beginning of a new exchange */
- st->st_msgid = generate_msgid(st);
- init_phase2_iv(st, &st->st_msgid);
-
- /* HDR out */
- {
- struct isakmp_hdr hdr;
-
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- hdr.isa_msgid = st->st_msgid;
-
- if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
+ pb_stream msg;
+ pb_stream rbody;
+ char buf[BUF_LEN];
+
+ /* set up attr */
+ init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
+
+ /* this is the beginning of a new exchange */
+ st->st_msgid = generate_msgid(st);
+ init_phase2_iv(st, &st->st_msgid);
+
+ /* HDR out */
{
- return STF_INTERNAL_ERROR;
+ struct isakmp_hdr hdr;
+
+ zero(&hdr); /* default to 0 */
+ hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ hdr.isa_np = ISAKMP_NEXT_HASH;
+ hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
+ hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
+ memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
+ memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
+ hdr.isa_msgid = st->st_msgid;
+
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
+ {
+ return STF_INTERNAL_ERROR;
+ }
}
- }
-
- /* ATTR out */
- modecfg_build_msg(st, &rbody
- , isama_type
- , ia
- , 0 /* XXX isama_id */
- );
-
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, msg.start, pbs_offset(&msg), "ModeCfg msg");
-
- /* Transmit */
- send_packet(st, "ModeCfg msg");
-
- if (st->st_event->ev_type != EVENT_RETRANSMIT)
- {
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
- }
- return STF_OK;
+
+ /* ATTR out */
+ modecfg_build_msg(st, &rbody
+ , isama_type
+ , ia
+ , 0 /* XXX isama_id */
+ );
+
+ free(st->st_tpacket.ptr);
+ st->st_tpacket = chunk_create(msg.start, pbs_offset(&msg));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+
+ /* Transmit */
+ send_packet(st, "ModeCfg msg");
+
+ if (st->st_event->ev_type != EVENT_RETRANSMIT)
+ {
+ delete_event(st);
+ event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
+ }
+ return STF_OK;
}
/*
@@ -466,111 +555,184 @@ modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
static stf_status
modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
{
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
- {
- u_int16_t attr_type;
- u_int16_t attr_len;
+ struct isakmp_attribute attr;
+ pb_stream strattr;
+ err_t ugh;
+ char buf[BUF_LEN];
+ int dns_idx = 0;
+ int nbns_idx = 0;
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
+ while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
{
- return STF_FAIL;
- }
- attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
- attr_len = attr.isaat_lv;
+ u_int16_t attr_type;
+ u_int16_t attr_len;
- switch (attr_type)
- {
- case INTERNAL_IP4_ADDRESS:
- if (attr_len == 4)
- {
- initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr);
- }
- /* fall through to set attribute flag */
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- case INTERNAL_ADDRESS_EXPIRY:
- case INTERNAL_IP4_DHCP:
- case INTERNAL_IP6_ADDRESS:
- case INTERNAL_IP6_NETMASK:
- case INTERNAL_IP6_DNS:
- case INTERNAL_IP6_NBNS:
- case INTERNAL_IP6_DHCP:
- case SUPPORTED_ATTRIBUTES:
- case INTERNAL_IP6_SUBNET:
- ia->attr_set |= LELEM(attr_type);
- break;
- case APPLICATION_VERSION:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- ia->attr_set |= LELEM(attr_type);
- break;
- case XAUTH_TYPE:
- ia->xauth_type = attr.isaat_lv;
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_USER_NAME:
- setchunk(ia->xauth_secret.user_name, strattr.cur, attr_len);
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_USER_PASSWORD:
- setchunk(ia->xauth_secret.user_password, strattr.cur, attr_len);
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_STATUS:
- ia->xauth_status = attr.isaat_lv;
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_MESSAGE:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- /* fall through to set attribute flag */
- case XAUTH_PASSCODE:
- case XAUTH_CHALLENGE:
- case XAUTH_DOMAIN:
- case XAUTH_NEXT_PIN:
- case XAUTH_ANSWER:
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case UNITY_DDNS_HOSTNAME:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- /* fall through to set attribute flag */
- case UNITY_BANNER:
- case UNITY_SAVE_PASSWD:
- case UNITY_DEF_DOMAIN:
- case UNITY_SPLITDNS_NAME:
- case UNITY_SPLIT_INCLUDE:
- case UNITY_NATT_PORT:
- case UNITY_LOCAL_LAN:
- case UNITY_PFS:
- case UNITY_FW_TYPE:
- case UNITY_BACKUP_SERVERS:
- ia->unity_attr_set |= LELEM(attr_type - UNITY_BASE);
- break;
- default:
- plog("unsupported ModeCfg attribute %s received."
- , enum_show(&modecfg_attr_names, attr_type));
- break;
+ if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
+ {
+ return STF_FAIL;
+ }
+ attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
+ attr_len = attr.isaat_lv;
+
+ switch (attr_type)
+ {
+ case INTERNAL_IP4_ADDRESS:
+ if (attr_len == 4)
+ {
+ ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr);
+ if (ugh != NULL)
+ {
+ plog("received invalid virtual IPv4 address: %s", ugh);
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP4_DNS:
+ if (attr_len == 4 && dns_idx < DNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->dns[dns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv4 DNS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->dns[dns_idx], 0, buf, BUF_LEN);
+ plog("received IPv4 DNS server address %s", buf);
+ dns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP4_NBNS:
+ if (attr_len == 4 && nbns_idx < NBNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->nbns[nbns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv4 WINS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->nbns[nbns_idx], 0, buf, BUF_LEN);
+ plog("received IPv4 WINS server address %s", buf);
+ nbns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP6_DNS:
+ if (attr_len == 16 && dns_idx < DNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 16, AF_INET6, &ia->dns[dns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv6 DNS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->dns[dns_idx], 0, buf, BUF_LEN);
+ plog("received IPv6 DNS server address %s", buf);
+ dns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP6_NBNS:
+ if (attr_len == 16 && nbns_idx < NBNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 16, AF_INET6, &ia->nbns[nbns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv6 WINS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->nbns[nbns_idx], 0, buf, BUF_LEN);
+ plog("received IPv6 WINS server address %s", buf);
+ nbns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP4_NETMASK:
+ case INTERNAL_IP4_SUBNET:
+ case INTERNAL_ADDRESS_EXPIRY:
+ case INTERNAL_IP4_DHCP:
+ case INTERNAL_IP6_ADDRESS:
+ case INTERNAL_IP6_NETMASK:
+ case INTERNAL_IP6_DHCP:
+ case SUPPORTED_ATTRIBUTES:
+ case INTERNAL_IP6_SUBNET:
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case APPLICATION_VERSION:
+ if (attr_len > 0)
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'", attr_len, strattr.cur)
+ )
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case XAUTH_TYPE:
+ ia->xauth_type = attr.isaat_lv;
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_USER_NAME:
+ ia->xauth_secret.user_name = chunk_create(strattr.cur, attr_len);
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_USER_PASSWORD:
+ ia->xauth_secret.user_password = chunk_create(strattr.cur, attr_len);
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_STATUS:
+ ia->xauth_status = attr.isaat_lv;
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_MESSAGE:
+ if (attr_len > 0)
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'", attr_len, strattr.cur)
+ )
+ }
+ /* fall through to set attribute flag */
+ case XAUTH_PASSCODE:
+ case XAUTH_CHALLENGE:
+ case XAUTH_DOMAIN:
+ case XAUTH_NEXT_PIN:
+ case XAUTH_ANSWER:
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case UNITY_DDNS_HOSTNAME:
+ if (attr_len > 0)
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'", attr_len, strattr.cur)
+ )
+ }
+ /* fall through to set attribute flag */
+ case UNITY_BANNER:
+ case UNITY_SAVE_PASSWD:
+ case UNITY_DEF_DOMAIN:
+ case UNITY_SPLITDNS_NAME:
+ case UNITY_SPLIT_INCLUDE:
+ case UNITY_NATT_PORT:
+ case UNITY_LOCAL_LAN:
+ case UNITY_PFS:
+ case UNITY_FW_TYPE:
+ case UNITY_BACKUP_SERVERS:
+ ia->unity_attr_set |= LELEM(attr_type - UNITY_BASE);
+ break;
+ default:
+ plog("unsupported ModeCfg attribute %s received."
+ , enum_show(&modecfg_attr_names, attr_type));
+ break;
+ }
}
- }
- return STF_OK;
+ return STF_OK;
}
/*
@@ -578,50 +740,52 @@ modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
*/
static stf_status
modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
- , internal_addr_t *ia)
+ , internal_addr_t *ia)
{
- struct state *const st = md->st;
- struct payload_digest *p;
- stf_status stat;
+ struct state *const st = md->st;
+ struct payload_digest *p;
+ stf_status stat;
- st->st_msgid = md->hdr.isa_msgid;
+ st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md, modecfg_hash(hash_val
- , hash_pbs->roof
- , md->message_pbs.roof, st)
- , "MODECFG-HASH", "ISAKMP_CFG_MSG");
+ CHECK_QUICK_HASH(md, modecfg_hash(hash_val
+ , hash_pbs->roof
+ , md->message_pbs.roof, st)
+ , "MODECFG-HASH", "ISAKMP_CFG_MSG");
- /* process the ModeCfg payloads received */
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- internal_addr_t ia_candidate;
+ /* process the ModeCfg payloads received */
+ for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
+ {
+ internal_addr_t ia_candidate;
- init_internal_addr(&ia_candidate);
+ init_internal_addr(&ia_candidate);
- if (p->payload.attribute.isama_type == isama_type)
- {
- *isama_id = p->payload.attribute.isama_identifier;
+ if (p->payload.attribute.isama_type == isama_type)
+ {
+ *isama_id = p->payload.attribute.isama_identifier;
- stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
- if (stat == STF_OK)
- {
- /* return with a valid set of attributes */
- *ia = ia_candidate;
- return STF_OK;
- }
- }
- else
- {
- plog("expected %s, got %s instead (ignored)"
- , enum_name(&attr_msg_type_names, isama_type)
- , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
+ stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
+ if (stat == STF_OK)
+ {
+ /* return with a valid set of attributes */
+ *ia = ia_candidate;
+ return STF_OK;
+ }
+ }
+ else
+ {
+ plog("expected %s, got %s instead (ignored)"
+ , enum_name(&attr_msg_type_names, isama_type)
+ , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
- stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
+ stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
+ }
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
}
- if (stat != STF_OK)
- return stat;
- }
- return STF_IGNORE;
+ return STF_IGNORE;
}
/*
@@ -630,20 +794,22 @@ modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
stf_status
modecfg_send_request(struct state *st)
{
- stf_status stat;
- internal_addr_t ia;
+ stf_status stat;
+ internal_addr_t ia;
- init_internal_addr(&ia);
+ init_internal_addr(&ia);
- ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
+ ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
+ | LELEM(INTERNAL_IP4_NETMASK);
- plog("sending ModeCfg request");
- st->st_state = STATE_MODE_CFG_I1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
+ plog("sending ModeCfg request");
+ st->st_state = STATE_MODE_CFG_I1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ {
+ st->st_modecfg.started = TRUE;
+ }
+ return stat;
}
/* STATE_MODE_CFG_R0:
@@ -654,38 +820,40 @@ modecfg_send_request(struct state *st)
stf_status
modecfg_inR0(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- bool want_unity_banner;
- stf_status stat, stat_build;
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ bool want_unity_banner;
+ stf_status stat, stat_build;
- init_internal_addr(&ia);
- get_internal_addr(st->st_connection, &ia);
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
- if (want_unity_banner)
- {
- ia.unity_banner = UNITY_BANNER_STR;
- ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
- }
+ want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
+ init_internal_addr(&ia);
+ get_internal_addr(st->st_connection, &ia);
- plog("sending ModeCfg reply");
+ if (want_unity_banner)
+ {
+ ia.unity_banner = UNITY_BANNER_STR;
+ ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
+ }
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
+ plog("sending ModeCfg reply");
- st->st_msgid = 0;
- return STF_OK;
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ st->st_msgid = 0;
+ return STF_OK;
}
/* STATE_MODE_CFG_I1:
@@ -696,20 +864,21 @@ modecfg_inR0(struct msg_digest *md)
stf_status
modecfg_inI1(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
-
- plog("parsing ModeCfg reply");
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
+ plog("parsing ModeCfg reply");
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
- st->st_msgid = 0;
- return STF_OK;
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+ st->st_msgid = 0;
+ return STF_OK;
}
@@ -719,23 +888,25 @@ modecfg_inI1(struct msg_digest *md)
stf_status
modecfg_send_set(struct state *st)
{
- stf_status stat;
- internal_addr_t ia;
+ stf_status stat;
+ internal_addr_t ia;
- init_internal_addr(&ia);
- get_internal_addr(st->st_connection, &ia);
+ init_internal_addr(&ia);
+ get_internal_addr(st->st_connection, &ia);
#ifdef CISCO_QUIRKS
- ia.unity_banner = UNITY_BANNER_STR;
- ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
+ ia.unity_banner = UNITY_BANNER_STR;
+ ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
#endif
plog("sending ModeCfg set");
- st->st_state = STATE_MODE_CFG_R3;
- stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
+ st->st_state = STATE_MODE_CFG_R3;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
+ if (stat == STF_OK)
+ {
+ st->st_modecfg.started = TRUE;
+ }
+ return stat;
}
/* STATE_MODE_CFG_I0:
@@ -746,38 +917,40 @@ modecfg_send_set(struct state *st)
stf_status
modecfg_inI0(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- lset_t attr_set, unity_attr_set;
- stf_status stat, stat_build;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ lset_t attr_set, unity_attr_set;
+ stf_status stat, stat_build;
- plog("parsing ModeCfg set");
+ plog("parsing ModeCfg set");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
-
- /* prepare ModeCfg ack which sends zero length attributes */
- attr_set = ia.attr_set;
- unity_attr_set = ia.unity_attr_set;
- init_internal_addr(&ia);
- ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
- ia.unity_attr_set = unity_attr_set & SUPPORTED_UNITY_ATTR_SET;
-
- plog("sending ModeCfg ack");
-
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- st->st_msgid = 0;
- return STF_OK;
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+
+ /* prepare ModeCfg ack which sends zero length attributes */
+ attr_set = ia.attr_set;
+ unity_attr_set = ia.unity_attr_set;
+ init_internal_addr(&ia);
+ ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
+ ia.unity_attr_set = unity_attr_set & SUPPORTED_UNITY_ATTR_SET;
+
+ plog("sending ModeCfg ack");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ st->st_msgid = 0;
+ return STF_OK;
}
/* STATE_MODE_CFG_R3:
@@ -788,19 +961,20 @@ modecfg_inI0(struct msg_digest *md)
stf_status
modecfg_inR3(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
- plog("parsing ModeCfg ack");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
+ plog("parsing ModeCfg ack");
- st->st_msgid = 0;
- return STF_OK;
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_msgid = 0;
+ return STF_OK;
}
/*
@@ -809,19 +983,21 @@ modecfg_inR3(struct msg_digest *md)
stf_status
xauth_send_request(struct state *st)
{
- stf_status stat;
- internal_addr_t ia;
-
- init_internal_addr(&ia);
- ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
- | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
-
- plog("sending XAUTH request");
- st->st_state = STATE_XAUTH_R1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_xauth.started = TRUE;
- return stat;
+ stf_status stat;
+ internal_addr_t ia;
+
+ init_internal_addr(&ia);
+ ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
+ | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
+
+ plog("sending XAUTH request");
+ st->st_state = STATE_XAUTH_R1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ {
+ st->st_xauth.started = TRUE;
+ }
+ return stat;
}
/* STATE_XAUTH_I0:
@@ -832,97 +1008,102 @@ xauth_send_request(struct state *st)
stf_status
xauth_inI0(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
- bool xauth_type_present;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
+ bool xauth_type_present;
- plog("parsing XAUTH request");
+ plog("parsing XAUTH request");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- /* check XAUTH attributes */
- xauth_type_present = (ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY;
-
- if (xauth_type_present && ia.xauth_type != XAUTH_TYPE_GENERIC)
- {
- plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
- stat = STF_FAIL;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
- {
- plog("user name attribute is missing in XAUTH request");
- stat = STF_FAIL;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
- {
- plog("user password attribute is missing in XAUTH request");
- stat = STF_FAIL;
- }
-
- /* prepare XAUTH reply */
- init_internal_addr(&ia);
-
- if (stat == STF_OK)
- {
- /* get user credentials using a plugin function */
- if (!xauth_module.get_secret(&ia.xauth_secret))
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
+ if (stat != STF_OK)
{
- plog("xauth user credentials not found");
- stat = STF_FAIL;
+ return stat;
}
- }
- if (stat == STF_OK)
- {
- DBG(DBG_CONTROL,
- DBG_log("my xauth user name is '%.*s'"
- , ia.xauth_secret.user_name.len
- , ia.xauth_secret.user_name.ptr)
- )
- DBG(DBG_PRIVATE,
- DBG_log("my xauth user password is '%.*s'"
- , ia.xauth_secret.user_password.len
- , ia.xauth_secret.user_password.ptr)
- )
- ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
- | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
- if (xauth_type_present)
- ia.xauth_attr_set |= LELEM(XAUTH_TYPE - XAUTH_BASE);
- }
- else
- {
- ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
- ia.xauth_status = XAUTH_STATUS_FAIL;
- }
- plog("sending XAUTH reply");
+ /* check XAUTH attributes */
+ xauth_type_present = (ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY;
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
+ if (xauth_type_present && ia.xauth_type != XAUTH_TYPE_GENERIC)
+ {
+ plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
+ stat = STF_FAIL;
+ }
+ else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user name attribute is missing in XAUTH request");
+ stat = STF_FAIL;
+ }
+ else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user password attribute is missing in XAUTH request");
+ stat = STF_FAIL;
+ }
- if (stat == STF_OK)
- {
- st->st_xauth.started = TRUE;
- st->st_msgid = 0;
- return STF_OK;
- }
- else
- {
- /* send XAUTH reply msg and then delete ISAKMP SA */
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "XAUTH reply msg");
- send_packet(st, "XAUTH reply msg");
- delete_state(st);
- return STF_IGNORE;
- }
+ /* prepare XAUTH reply */
+ init_internal_addr(&ia);
+
+ if (stat == STF_OK)
+ {
+ /* get user credentials using a plugin function */
+ if (!xauth_module.get_secret(&ia.xauth_secret))
+ {
+ plog("xauth user credentials not found");
+ stat = STF_FAIL;
+ }
+ }
+ if (stat == STF_OK)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("my xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("my xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
+ ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
+ | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
+ if (xauth_type_present)
+ {
+ ia.xauth_attr_set |= LELEM(XAUTH_TYPE - XAUTH_BASE);
+ }
+ }
+ else
+ {
+ ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
+ ia.xauth_status = XAUTH_STATUS_FAIL;
+ }
+
+ plog("sending XAUTH reply");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ if (stat == STF_OK)
+ {
+ st->st_xauth.started = TRUE;
+ st->st_msgid = 0;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH reply msg and then delete ISAKMP SA */
+ free(st->st_tpacket.ptr);
+ st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+ send_packet(st, "XAUTH reply msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
/* STATE_XAUTH_R1:
@@ -933,72 +1114,76 @@ xauth_inI0(struct msg_digest *md)
stf_status
xauth_inR1(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
- plog("parsing XAUTH reply");
+ plog("parsing XAUTH reply");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- /* did the client return an XAUTH FAIL status? */
- if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY)
- {
- plog("received FAIL status in XAUTH reply");
-
- /* client is not able to do XAUTH, delete ISAKMP SA */
- delete_state(st);
- return STF_IGNORE;
- }
-
- /* check XAUTH reply */
- if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
- {
- plog("user name attribute is missing in XAUTH reply");
- st->st_xauth.status = FALSE;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
- {
- plog("user password attribute is missing in XAUTH reply");
- st->st_xauth.status = FALSE;
- }
- else
- {
- xauth_peer_t peer;
-
- peer.conn_name = st->st_connection->name;
- addrtot(&md->sender, 0, peer.ip_address, sizeof(peer.ip_address));
- idtoa(&md->st->st_connection->spd.that.id, peer.id, sizeof(peer.id));
-
- DBG(DBG_CONTROL,
- DBG_log("peer xauth user name is '%.*s'"
- , ia.xauth_secret.user_name.len
- , ia.xauth_secret.user_name.ptr)
- )
- DBG(DBG_PRIVATE,
- DBG_log("peer xauth user password is '%.*s'"
- , ia.xauth_secret.user_password.len
- , ia.xauth_secret.user_password.ptr)
- )
- /* verify the user credentials using a plugin function */
- st->st_xauth.status = xauth_module.verify_secret(&peer, &ia.xauth_secret);
- plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
- }
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+
+ /* did the client return an XAUTH FAIL status? */
+ if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY)
+ {
+ plog("received FAIL status in XAUTH reply");
+
+ /* client is not able to do XAUTH, delete ISAKMP SA */
+ delete_state(st);
+ return STF_IGNORE;
+ }
+
+ /* check XAUTH reply */
+ if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user name attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
+ }
+ else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user password attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
+ }
+ else
+ {
+ xauth_peer_t peer;
+
+ peer.conn_name = st->st_connection->name;
+ addrtot(&md->sender, 0, peer.ip_address, sizeof(peer.ip_address));
+ idtoa(&md->st->st_connection->spd.that.id, peer.id, sizeof(peer.id));
+
+ DBG(DBG_CONTROL,
+ DBG_log("peer xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("peer xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
+ /* verify the user credentials using a plugin function */
+ st->st_xauth.status = xauth_module.verify_secret(&peer, &ia.xauth_secret);
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
+ }
- /* prepare XAUTH set which sends the authentication status */
- init_internal_addr(&ia);
- ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
- ia.xauth_status = (st->st_xauth.status)? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
+ /* prepare XAUTH set which sends the authentication status */
+ init_internal_addr(&ia);
+ ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
+ ia.xauth_status = (st->st_xauth.status)? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
- plog("sending XAUTH status:");
+ plog("sending XAUTH status:");
- stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
- if (stat_build != STF_OK)
- return stat_build;
- return STF_OK;
+ stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ return STF_OK;
}
/* STATE_XAUTH_I1:
@@ -1009,47 +1194,48 @@ xauth_inR1(struct msg_digest *md)
stf_status
xauth_inI1(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
-
- plog("parsing XAUTH status");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
- if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = ATTRIBUTES_NOT_SUPPORTED;
- return stat;
- }
-
- st->st_xauth.status = ia.xauth_status;
- plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
-
- plog("sending XAUTH ack");
- init_internal_addr(&ia);
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- if (st->st_xauth.status)
- {
- st->st_msgid = 0;
- return STF_OK;
- }
- else
- {
- /* send XAUTH ack msg and then delete ISAKMP SA */
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "XAUTH ack msg");
- send_packet(st, "XAUTH ack msg");
- delete_state(st);
- return STF_IGNORE;
- }
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
+
+ plog("parsing XAUTH status");
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ /* notification payload - not exactly the right choice, but okay */
+ md->note = ATTRIBUTES_NOT_SUPPORTED;
+ return stat;
+ }
+
+ st->st_xauth.status = ia.xauth_status;
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
+
+ plog("sending XAUTH ack");
+ init_internal_addr(&ia);
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ if (st->st_xauth.status)
+ {
+ st->st_msgid = 0;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH ack msg and then delete ISAKMP SA */
+ free(st->st_tpacket.ptr);
+ st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+ send_packet(st, "XAUTH ack msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
/* STATE_XAUTH_R2:
@@ -1060,25 +1246,26 @@ xauth_inI1(struct msg_digest *md)
stf_status
xauth_inR2(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
- plog("parsing XAUTH ack");
+ plog("parsing XAUTH ack");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_msgid = 0;
- if (st->st_xauth.status)
- {
- return STF_OK;
- }
- else
- {
- delete_state(st);
- return STF_IGNORE;
- }
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_msgid = 0;
+ if (st->st_xauth.status)
+ {
+ return STF_OK;
+ }
+ else
+ {
+ delete_state(st);
+ return STF_IGNORE;
+ }
}