diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-01-25 19:40:34 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-01-25 19:40:34 +0000 |
commit | f8200bf0f703754a66b5760af2779e52e0edc9c1 (patch) | |
tree | d01e1529527f2b04a159aa8a0f06479f20d129f1 | |
parent | 1c266d7d69c5890e0e22d05af8a1ad32f8b75c5e (diff) | |
download | strongswan-f8200bf0f703754a66b5760af2779e52e0edc9c1.tar.bz2 strongswan-f8200bf0f703754a66b5760af2779e52e0edc9c1.tar.xz |
Mode Config refactoring
-rw-r--r-- | src/pluto/constants.h | 2 | ||||
-rw-r--r-- | src/pluto/modecfg.c | 158 |
2 files changed, 117 insertions, 43 deletions
diff --git a/src/pluto/constants.h b/src/pluto/constants.h index 2f3587db2..34cae3c62 100644 --- a/src/pluto/constants.h +++ b/src/pluto/constants.h @@ -664,7 +664,6 @@ extern enum_names attr_msg_type_names; #define SUPPORTED_ATTRIBUTES 14 #define INTERNAL_IP6_SUBNET 15 -#define MODECFG_ROOF 16 extern enum_names modecfg_attr_names; @@ -681,7 +680,6 @@ extern enum_names modecfg_attr_names; #define XAUTH_ANSWER 16529 #define XAUTH_BASE XAUTH_TYPE -#define XAUTH_ROOF 16530 extern enum_names xauth_attr_names; diff --git a/src/pluto/modecfg.c b/src/pluto/modecfg.c index 5b982744f..3b9fdfd50 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 Andreas Steffen - Hochschule fuer Technik Rapperswil + * Copyright (C) 2006-2007 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 @@ -43,12 +43,17 @@ #define MAX_XAUTH_TRIES 3 -#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \ - | LELEM(INTERNAL_IP4_NETMASK) \ - | LELEM(INTERNAL_IP4_DNS) \ - | LELEM(INTERNAL_IP4_NBNS) \ +#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \ + | LELEM(INTERNAL_IP4_NETMASK) \ + | LELEM(INTERNAL_IP4_DNS) \ + | LELEM(INTERNAL_IP4_NBNS) \ + | LELEM(APPLICATION_VERSION) \ ) +#define SUPPORTED_UNITY_ATTR_SET ( LELEM(UNITY_BANNER - UNITY_BASE) ) + +#define UNITY_BANNER_STR "Welcome to strongSwan - the Linux VPN Solution!\n" + /* * Addresses assigned (usually via ModeCfg) to the Initiator */ @@ -57,12 +62,16 @@ typedef struct internal_addr internal_addr_t; struct internal_addr { 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]; + char *unity_banner; + /* XAUTH variables */ u_int16_t xauth_type; xauth_t xauth_secret; @@ -76,9 +85,12 @@ 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_status = FALSE; + ia->unity_attr_set = LEMPTY; + ia->unity_banner = NULL; anyaddr(AF_INET, &ia->ipaddr); anyaddr(AF_INET, &ia->dns[0]); @@ -93,8 +105,6 @@ init_internal_addr(internal_addr_t *ia) static void get_internal_addr(struct connection *c, internal_addr_t *ia) { - init_internal_addr(ia); - if (isanyaddr(&c->spd.that.host_srcip)) { /* not defined in connection - fetch it from LDAP */ @@ -115,10 +125,10 @@ get_internal_addr(struct connection *c, internal_addr_t *ia) c->spd.that.client.maskbits = 32; c->spd.that.has_client = TRUE; - ia->attr_set |= LELEM(INTERNAL_IP4_ADDRESS) | LELEM(INTERNAL_IP4_NETMASK); + 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); @@ -210,6 +220,8 @@ modecfg_build_msg(struct state *st, pb_stream *rbody 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; @@ -223,9 +235,26 @@ modecfg_build_msg(struct state *st, pb_stream *rbody dns_idx = 0; wins_idx = 0; - while (attr_set != 0) + while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set) { + 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 + { + attr_set = ia->unity_attr_set; + attr_type = UNITY_BASE; + is_unity_attr_set = FALSE; + } + } + dont_advance = FALSE; + if (attr_set & 1) { const u_char *byte_ptr; @@ -343,6 +372,14 @@ modecfg_build_msg(struct state *st, pb_stream *rbody 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)); @@ -353,14 +390,6 @@ modecfg_build_msg(struct state *st, pb_stream *rbody if (!dont_advance) { attr_type++; - if (attr_type == MODECFG_ROOF) - { - attr_type = XAUTH_BASE; - } - else if (attr_type == XAUTH_ROOF) - { - attr_type = UNITY_BASE; - } attr_set >>= 1; } } @@ -458,7 +487,7 @@ modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia) { initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr); } - /* fall through to set attribute flags */ + /* fall through to set attribute flag */ case INTERNAL_IP4_NETMASK: case INTERNAL_IP4_DNS: case INTERNAL_IP4_SUBNET: @@ -466,29 +495,57 @@ modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia) ia->attr_set |= LELEM(attr_type); break; case APPLICATION_VERSION: - case UNITY_DDNS_HOSTNAME: 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->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF); + 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->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF); + 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->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF); + ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE); break; case XAUTH_STATUS: ia->xauth_status = attr.isaat_lv; - ia->attr_set |= LELEM(attr_type - XAUTH_BASE + MODECFG_ROOF); + ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE); + break; + case XAUTH_PASSCODE: + case XAUTH_MESSAGE: + 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." @@ -560,6 +617,7 @@ modecfg_send_request(struct state *st) internal_addr_t ia; init_internal_addr(&ia); + ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS) | LELEM(INTERNAL_IP4_NETMASK); @@ -582,14 +640,24 @@ 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; + + init_internal_addr(&ia); get_internal_addr(st->st_connection, &ia); + if (want_unity_banner) + { + ia.unity_banner = UNITY_BANNER_STR; + ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE); + } + plog("sending ModeCfg reply"); stat_build = modecfg_build_msg(st, &md->rbody @@ -637,9 +705,15 @@ modecfg_send_set(struct state *st) stf_status stat; internal_addr_t ia; + init_internal_addr(&ia); get_internal_addr(st->st_connection, &ia); - plog("sending ModeCfg set"); +#ifdef CISCO_QUIRKS + 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) @@ -658,7 +732,7 @@ 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; + lset_t attr_set, unity_attr_set; stf_status stat, stat_build; plog("parsing ModeCfg set"); @@ -671,8 +745,10 @@ modecfg_inI0(struct msg_digest *md) /* 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"); @@ -720,8 +796,8 @@ xauth_send_request(struct state *st) internal_addr_t ia; init_internal_addr(&ia); - ia.attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF) - | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF); + 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; @@ -751,18 +827,18 @@ xauth_inI0(struct msg_digest *md) return stat; /* check XAUTH attributes */ - if ((ia.attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY + if ((ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY && 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.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY) + 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.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY) + 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; @@ -792,13 +868,13 @@ xauth_inI0(struct msg_digest *md) , ia.xauth_secret.user_password.len , ia.xauth_secret.user_password.ptr) ) - ia.attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF) - | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF); + ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE) + | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE); } else { - ia.attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF); - ia.xauth_status = FALSE; + ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE); + ia.xauth_status = XAUTH_STATUS_FAIL; } plog("sending XAUTH reply"); @@ -847,7 +923,7 @@ xauth_inR1(struct msg_digest *md) return stat; /* did the client return an XAUTH FAIL status? */ - if ((ia.attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY) + if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY) { plog("received FAIL status in XAUTH reply"); @@ -857,12 +933,12 @@ xauth_inR1(struct msg_digest *md) } /* check XAUTH reply */ - if ((ia.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY) + 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.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY) + 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; @@ -886,8 +962,8 @@ xauth_inR1(struct msg_digest *md) /* prepare XAUTH set which sends the authentication status */ init_internal_addr(&ia); - ia.attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF); - ia.xauth_status = st->st_xauth.status; + 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:"); |