summaryrefslogtreecommitdiff
path: root/programs/pluto/modecfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'programs/pluto/modecfg.c')
-rw-r--r--programs/pluto/modecfg.c196
1 files changed, 152 insertions, 44 deletions
diff --git a/programs/pluto/modecfg.c b/programs/pluto/modecfg.c
index 01bab8c6e..620c595fb 100644
--- a/programs/pluto/modecfg.c
+++ b/programs/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
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.c,v 1.10 2007/01/10 00:36:19 as Exp $
+ * RCSID $Id: modecfg.c,v 1.16 2007/01/29 08:27:54 as Exp $
*
* This code originally written by Colubris Networks, Inc.
* Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
@@ -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,13 @@ 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->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]);
@@ -93,8 +106,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 +126,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 +221,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 +236,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 +373,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,10 +391,6 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
if (!dont_advance)
{
attr_type++;
- if (attr_type == MODECFG_ROOF)
- {
- attr_type = XAUTH_BASE;
- }
attr_set >>= 1;
}
}
@@ -454,28 +488,81 @@ 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:
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->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_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."
@@ -547,6 +634,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);
@@ -569,14 +657,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
@@ -624,9 +722,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)
@@ -645,7 +749,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");
@@ -658,8 +762,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");
@@ -707,8 +813,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;
@@ -730,6 +836,7 @@ xauth_inI0(struct msg_digest *md)
u_int16_t isama_id;
internal_addr_t ia;
stf_status stat, stat_build;
+ bool xauth_type_present;
plog("parsing XAUTH request");
@@ -738,18 +845,19 @@ xauth_inI0(struct msg_digest *md)
return stat;
/* check XAUTH attributes */
- if ((ia.attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY
- && ia.xauth_type != XAUTH_TYPE_GENERIC)
+ 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.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;
@@ -779,13 +887,15 @@ 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);
+ if (xauth_type_present)
+ ia.xauth_attr_set |= LELEM(XAUTH_TYPE - 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");
@@ -800,6 +910,7 @@ xauth_inI0(struct msg_digest *md)
if (stat == STF_OK)
{
st->st_xauth.started = TRUE;
+ st->st_msgid = 0;
return STF_OK;
}
else
@@ -834,7 +945,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");
@@ -844,12 +955,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;
@@ -873,16 +984,13 @@ 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:");
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_SET
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
+ stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
+ if (stat_build != STF_OK)
return stat_build;
return STF_OK;
}