Mode Config refactoring
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 25 Jan 2007 19:40:34 +0000 (19:40 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 25 Jan 2007 19:40:34 +0000 (19:40 -0000)
src/pluto/constants.h
src/pluto/modecfg.c

index 2f3587d..34cae3c 100644 (file)
@@ -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;
 
index 5b98274..3b9fdfd 100644 (file)
@@ -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
 
 #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:");