pluto now supports SQL-based virtual IP pools
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 14 Oct 2009 12:30:14 +0000 (14:30 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 14 Oct 2009 12:30:14 +0000 (14:30 +0200)
16 files changed:
src/charon/plugins/stroke/stroke_attribute.c
src/charon/plugins/stroke/stroke_config.c
src/libstrongswan/plugins/attr_sql/attr_sql_plugin.c
src/libstrongswan/plugins/attr_sql/pool [new file with mode: 0755]
src/pluto/connections.c
src/pluto/connections.h
src/pluto/modecfg.c
src/pluto/rcv_whack.c
src/starter/args.c
src/starter/confread.c
src/starter/confread.h
src/starter/starterstroke.c
src/starter/starterwhack.c
src/stroke/stroke_msg.h
src/whack/whack.c
src/whack/whack.h

index 14464e0..5c24d34 100644 (file)
@@ -320,7 +320,7 @@ static bool release_address(private_stroke_attribute_t *this,
  */
 static void add_pool(private_stroke_attribute_t *this, stroke_msg_t *msg)
 {
-       if (msg->add_conn.other.sourceip_size)
+       if (msg->add_conn.other.sourceip_mask)
        {
                pool_t *pool;
 
@@ -344,7 +344,7 @@ static void add_pool(private_stroke_attribute_t *this, stroke_msg_t *msg)
 
                        DBG1(DBG_CFG, "adding virtual IP address pool '%s': %s/%d",
                                 msg->add_conn.name, msg->add_conn.other.sourceip,
-                                msg->add_conn.other.sourceip_size);
+                                msg->add_conn.other.sourceip_mask);
 
                        pool->base = host_create_from_string(msg->add_conn.other.sourceip, 0);
                        if (!pool->base)
@@ -354,7 +354,7 @@ static void add_pool(private_stroke_attribute_t *this, stroke_msg_t *msg)
                                return;
                        }
                        family = pool->base->get_family(pool->base);
-                       bits = (family == AF_INET ? 32 : 128) - msg->add_conn.other.sourceip_size;
+                       bits = (family == AF_INET ? 32 : 128) - msg->add_conn.other.sourceip_mask;
                        if (bits > POOL_LIMIT)
                        {
                                bits = POOL_LIMIT;
index 2da1948..54d9a15 100644 (file)
@@ -583,7 +583,7 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
        {
                rekey = msg->add_conn.rekey.ike_lifetime - over;
        }
-       if (msg->add_conn.me.sourceip_size)
+       if (msg->add_conn.me.sourceip_mask)
        {
                if (msg->add_conn.me.sourceip)
                {
@@ -641,7 +641,7 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
                msg->add_conn.me.sendcert, unique,
                msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
                msg->add_conn.mobike, msg->add_conn.dpd.delay,
-               vip, msg->add_conn.other.sourceip_size ?
+               vip, msg->add_conn.other.sourceip_mask ?
                                                        msg->add_conn.name : msg->add_conn.other.sourceip,
                msg->add_conn.ikeme.mediation, mediated_by, peer_id);
 
index cb57af8..66b309c 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <library.h>
+#include <debug.h>
 
 #include "attr_sql_plugin.h"
 #include "sql_attribute.h"
diff --git a/src/libstrongswan/plugins/attr_sql/pool b/src/libstrongswan/plugins/attr_sql/pool
new file mode 100755 (executable)
index 0000000..ce789d3
--- /dev/null
@@ -0,0 +1,148 @@
+#! /bin/bash
+
+# pool - temporary wrapper script for .libs/pool
+# Generated by ltmain.sh (GNU libtool) 2.2.6 Debian-2.2.6a-1ubuntu1
+#
+# The pool program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='/bin/sed -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/andi/strongswan/src/libstrongswan/plugins/attr_sql; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/home/andi/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/git-core; export PATH; gcc -rdynamic \"-DPLUGINS=\\\"test-vectors curl aes des blowfish sha1 sha2 md5 fips-prf random x509 pubkey pkcs1 pgp dnskey pem sqlite attr-sql openssl gcrypt xcbc hmac agent gmp\\\"\" -g -O2 -Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -o \$progdir/\$file pool.o  ../../../../src/libstrongswan/.libs/libstrongswan.so -lpthread -ldl -lrt -Wl,-rpath -Wl,/home/andi/strongswan/src/libstrongswan/.libs)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='2.2.6'
+  notinst_deplibs=' ../../../../src/libstrongswan/libstrongswan.la'
+else
+  # When we are sourced in execute mode, $file and $ECHO are already set.
+  if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+    ECHO="echo"
+    file="$0"
+    # Make sure echo works.
+    if test "X$1" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
+      # Yippee, $ECHO works!
+      :
+    else
+      # Restart under the correct shell, and then maybe $ECHO will work.
+      exec /bin/bash "$0" --no-reexec ${1+"$@"}
+    fi
+  fi
+
+  # Find the directory that this script lives in.
+  thisdir=`$ECHO "X$file" | $Xsed -e 's%/[^/]*$%%'`
+  test "x$thisdir" = "x$file" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+  while test -n "$file"; do
+    destdir=`$ECHO "X$file" | $Xsed -e 's%/[^/]*$%%'`
+
+    # If there was a directory component, then change thisdir.
+    if test "x$destdir" != "x$file"; then
+      case "$destdir" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+      *) thisdir="$thisdir/$destdir" ;;
+      esac
+    fi
+
+    file=`$ECHO "X$file" | $Xsed -e 's%^.*/%%'`
+    file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+  done
+
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+  if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+    # special case for '.'
+    if test "$thisdir" = "."; then
+      thisdir=`pwd`
+    fi
+    # remove .libs from thisdir
+    case "$thisdir" in
+    *[\\/].libs ) thisdir=`$ECHO "X$thisdir" | $Xsed -e 's%[\\/][^\\/]*$%%'` ;;
+    .libs )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=`cd "$thisdir" && pwd`
+  test -n "$absdir" && thisdir="$absdir"
+
+  program=lt-'pool'
+  progdir="$thisdir/.libs"
+
+  if test ! -f "$progdir/$program" ||
+     { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+       test "X$file" != "X$progdir/$program"; }; then
+
+    file="$$-$program"
+
+    if test ! -d "$progdir"; then
+      mkdir "$progdir"
+    else
+      rm -f "$progdir/$file"
+    fi
+
+    # relink executable if necessary
+    if test -n "$relink_command"; then
+      if relink_command_output=`eval $relink_command 2>&1`; then :
+      else
+       echo "$relink_command_output" >&2
+       rm -f "$progdir/$file"
+       exit 1
+      fi
+    fi
+
+    mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+    { rm -f "$progdir/$program";
+      mv -f "$progdir/$file" "$progdir/$program"; }
+    rm -f "$progdir/$file"
+  fi
+
+  if test -f "$progdir/$program"; then
+    if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+      # Run the actual program with our arguments.
+
+      exec "$progdir/$program" ${1+"$@"}
+
+      $ECHO "$0: cannot exec $program $*" 1>&2
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+    $ECHO "This script is just a wrapper for $program." 1>&2
+    echo "See the libtool documentation for more information." 1>&2
+    exit 1
+  fi
+fi
index 1e707f4..1258536 100644 (file)
@@ -320,7 +320,9 @@ void delete_connection(connection_t *c, bool relations)
        release_connection(c, relations);   /* won't delete c */
 
        if (c->kind == CK_GROUP)
+       {
                delete_group(c);
+       }
 
        /* free up any logging resources */
        perpeer_logfree(c);
@@ -333,7 +335,9 @@ void delete_connection(connection_t *c, bool relations)
        if (c->host_pair == NULL)
        {
                if (c->ikev1)
+               {
                        list_rm(connection_t, hp_next, c, unoriented_connections);
+               }
        }
        else
        {
@@ -358,6 +362,20 @@ void delete_connection(connection_t *c, bool relations)
        {
                free(c->spd.that.virt);
        }
+
+       /* release virtual IP address lease if any */
+       if (c->spd.that.modecfg && c->spd.that.pool &&
+               !isanyaddr(&c->spd.that.host_srcip))
+       {
+               host_t *vip;
+
+               vip = host_create_from_sockaddr((sockaddr_t*)&c->spd.that.host_srcip);
+               lib->attributes->release_address(lib->attributes, c->spd.that.pool,
+                                                                                vip, c->spd.that.id);
+               vip->destroy(vip);
+       }
+
+       /* free internal data */
 #ifdef DEBUG
        cur_debugging = old_cur_debugging;
 #endif
@@ -366,10 +384,12 @@ void delete_connection(connection_t *c, bool relations)
        DESTROY_IF(c->spd.this.ca);
        DESTROY_IF(c->spd.this.groups);
        free(c->spd.this.updown);
+       free(c->spd.this.pool);
        DESTROY_IF(c->spd.that.id);
        DESTROY_IF(c->spd.that.ca);
        DESTROY_IF(c->spd.that.groups);
        free(c->spd.that.updown);
+       free(c->spd.that.pool);
        if (c->requested_ca)
        {
                c->requested_ca->destroy_offset(c->requested_ca,
@@ -562,7 +582,7 @@ static err_t default_end(struct end *e, ip_address *dflt_nexthop)
 size_t format_end(char *buf, size_t buf_len, const struct end *this,
                                 const struct end *that, bool is_left, lset_t policy)
 {
-       char client[SUBNETTOT_BUF];
+       char client[BUF_LEN];
        const char *client_sep = "";
        char protoport[sizeof(":255/65535")];
        const char *host = NULL;
@@ -618,17 +638,24 @@ size_t format_end(char *buf, size_t buf_len, const struct end *this,
 
                if (isanyaddr(&client_net) && isanyaddr(&client_mask)
                && (policy & (POLICY_GROUP | POLICY_OPPO)))
+               {
                        client_sep = "";    /* boring case */
+               }
                else if (subnetisnone(&this->client))
+               {
                        strcpy(client, "?");
+               }
                else
+               {
                        subnettot(&this->client, 0, client, sizeof(client));
+               }
        }
        else if (this->modecfg && isanyaddr(&this->host_srcip))
        {
-               /* we are mode config client */
+               /* we are mode config client, or a server with a pool */
                client_sep = "===";
-               strcpy(client, "%modecfg");
+               client[0] = '%';
+               strcpy(client+1, this->pool ? this->pool : "modecfg");
        }
 
        /* host */
@@ -640,16 +667,21 @@ size_t format_end(char *buf, size_t buf_len, const struct end *this,
 
        host_port[0] = '\0';
        if (this->host_port != IKE_UDP_PORT)
-               snprintf(host_port, sizeof(host_port), ":%u"
-                       , this->host_port);
+       {
+               snprintf(host_port, sizeof(host_port), ":%u", this->host_port);
+       }
 
        /* payload portocol and port */
        protoport[0] = '\0';
        if (this->has_port_wildcard)
+       {
                snprintf(protoport, sizeof(protoport), ":%u/%%any", this->protocol);
+       }
        else if (this->port || this->protocol)
+       {
                snprintf(protoport, sizeof(protoport), ":%u/%u", this->protocol
                        , this->port);
+       }
 
        /* id */
        snprintf(host_id, sizeof(host_id), "[%Y]", this->id); 
@@ -664,17 +696,21 @@ size_t format_end(char *buf, size_t buf_len, const struct end *this,
        }
 
        if (is_left)
+       {
                snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
                        , open_brackets, client, close_brackets, client_sep
                        , this->allow_any? "%":""
                        , host, host_port, host_id, protoport
                        , hop_sep, hop);
+       }
        else
+       {
                snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
                        , hop, hop_sep
                        , this->allow_any? "%":""
                        , host, host_port, host_id, protoport, client_sep
                        , open_brackets, client, close_brackets);
+       }
        return strlen(buf);
 }
 
@@ -697,6 +733,7 @@ static void unshare_connection_strings(connection_t *c)
 {
        c->name = clone_str(c->name);
        c->spd.this.id = c->spd.this.id->clone(c->spd.this.id);
+       c->spd.this.pool = clone_str(c->spd.this.pool);
        c->spd.this.updown = clone_str(c->spd.this.updown);
        scx_share(c->spd.this.sc);
        share_cert(c->spd.this.cert);
@@ -709,6 +746,7 @@ static void unshare_connection_strings(connection_t *c)
                c->spd.this.groups = c->spd.this.groups->get_ref(c->spd.this.groups);
        }
        c->spd.that.id = c->spd.that.id->clone(c->spd.that.id);
+       c->spd.that.pool = clone_str(c->spd.that.pool);
        c->spd.that.updown = clone_str(c->spd.that.updown);
        scx_share(c->spd.that.sc);
        share_cert(c->spd.that.cert);
@@ -886,13 +924,17 @@ static bool extract_end(struct end *dst, const whack_end_t *src,
        dst->updown = clone_str(src->updown);
        dst->host_port = src->host_port;
 
+       /* if the sourceip netmask is zero a named pool exists */
+       if (src->sourceip_mask == 0)
+       {
+               dst->pool = clone_str(src->sourceip);
+       }
+
        /* if host sourceip is defined but no client is present
         * behind the host then set client to sourceip/32
         */
-       if (addrbytesptr(&dst->host_srcip, NULL)
-       && !isanyaddr(&dst->host_srcip)
-       && !dst->has_natip
-       && !dst->has_client)
+       if (addrbytesptr(&dst->host_srcip, NULL) &&
+               !isanyaddr(&dst->host_srcip) && !dst->has_natip && !dst->has_client)
        {
                err_t ugh = addrtosubnet(&dst->host_srcip, &dst->client);
 
@@ -2987,7 +3029,9 @@ void ISAKMP_SA_established(connection_t *c, so_serial_t serial)
         * whether we are a mode config server with a virtual IP to send.
         */
        if (!isanyaddr(&c->spd.that.host_srcip) && !c->spd.that.has_natip)
+       {
                c->spd.that.modecfg = TRUE;
+       }
 
        if (uniqueIDs)
        {
index e1d7b2c..5a12812 100644 (file)
@@ -154,6 +154,7 @@ struct end {
        struct virtual_t *virt;
        bool modecfg;               /* this end: request local address from server */
                                                                /* that end: give local addresses to clients */
+       char *pool;                                     /* name of an associated virtual IP address pool */
        bool hostaccess;            /* allow access to host via iptables INPUT/OUTPUT */
                                                                /* rules if client behind host is a subnet */
        bool allow_any;             /* IP address is subject to change */
@@ -187,10 +188,10 @@ struct connection {
        time_t dpd_timeout;
        dpd_action_t dpd_action;
 
-       char              *log_file_name;       /* name of log file */
-       FILE              *log_file;            /* possibly open FILE */
+       char              *log_file_name;     /* name of log file */
+       FILE              *log_file;          /* possibly open FILE */
        TAILQ_ENTRY(connection) log_link;     /* linked list of open conns */
-       bool               log_file_err;        /* only bitch once */
+       bool               log_file_err;      /* only bitch once */
 
        struct spd_route spd;
 
index c8f9bb5..e63b189 100644 (file)
@@ -82,11 +82,10 @@ struct internal_addr
        bool       xauth_status;
 };
 
-/*
+/**
  * Initialize an internal_addr struct
  */
-static void
-init_internal_addr(internal_addr_t *ia)
+static void init_internal_addr(internal_addr_t *ia)
 {
        int i;
 
@@ -114,17 +113,36 @@ init_internal_addr(internal_addr_t *ia)
        }
 }
 
-/*
- * get internal IP address for a connection
+/**
+ * Get internal IP address for a connection
  */
-static void
-get_internal_addr(connection_t *c, internal_addr_t *ia)
+static void get_internal_addr(connection_t *c, host_t *requested_vip,
+                                                         internal_addr_t *ia)
 {
        int i, dns_idx = 0, nbns_idx = 0;
 
        if (isanyaddr(&c->spd.that.host_srcip))
        {
-               /* not defined in connection - fetch it from LDAP */
+               if (c->spd.that.pool)
+               {
+                       host_t *vip;
+
+                       vip = lib->attributes->acquire_address(lib->attributes,
+                                                                               c->spd.that.pool, c->spd.that.id,
+                                                                               requested_vip);
+                       if (vip)
+                       {
+                               chunk_t addr = vip->get_address(vip);
+               
+                               plog("assigning virtual IP %H to peer", vip);
+                               initaddr(addr.ptr, addr.len, vip->get_family(vip), &ia->ipaddr);
+                               vip->destroy(vip);
+                       }
+               }
+               else
+               {
+                       plog("no virtual IP found");
+               }
        }
        else
        {
@@ -133,11 +151,12 @@ get_internal_addr(connection_t *c, internal_addr_t *ia)
                ia->ipaddr = c->spd.that.host_srcip;
 
                addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
-               plog("assigning virtual IP source address %s", srcip);
+               plog("assigning virtual IP  %s to peer", srcip);
        }
 
        if (!isanyaddr(&ia->ipaddr))        /* We got an IP address, send it */
        {
+               c->spd.that.host_srcip      = ia->ipaddr;
                c->spd.that.client.addr     = ia->ipaddr;
                c->spd.that.client.maskbits = 32;
                c->spd.that.has_client      = TRUE;
@@ -200,11 +219,10 @@ get_internal_addr(connection_t *c, internal_addr_t *ia)
 }
 
 
-/*
+/**
  * Set srcip and client subnet to internal IP address
  */
-static bool
-set_internal_addr(connection_t *c, internal_addr_t *ia)
+static bool set_internal_addr(connection_t *c, internal_addr_t *ia)
 {
        if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
        && !isanyaddr(&ia->ipaddr))
@@ -241,7 +259,7 @@ set_internal_addr(connection_t *c, internal_addr_t *ia)
        return FALSE;
 }
 
-/*
+/**
  * Compute HASH of Mode Config.
  */
 static size_t modecfg_hash(u_char *dest, u_char *start, u_char *roof,
@@ -269,14 +287,13 @@ static size_t modecfg_hash(u_char *dest, u_char *start, u_char *roof,
 }
 
 
-/*
+/**
  * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS)
  */
-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)
+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_char *r_hash_start, *r_hashval;
 
@@ -492,11 +509,11 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
        return STF_OK;
 }
 
-/*
+/**
  * Send ModeCfg message
  */
-static stf_status
-modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
+static stf_status modecfg_send_msg(struct state *st, int isama_type,
+                                                                  internal_addr_t *ia)
 {
        pb_stream msg;
        pb_stream rbody;
@@ -550,11 +567,10 @@ modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
        return STF_OK;
 }
 
-/*
+/**
  * Parse a ModeCfg attribute payload
  */
-static stf_status
-modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
+static stf_status modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
 {
        struct isakmp_attribute attr;
        pb_stream strattr;
@@ -736,12 +752,11 @@ modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
        return STF_OK;
 }
 
-/*
+/**
  * Parse a ModeCfg message
  */
-static stf_status
-modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
-                               , 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)
 {
        struct state *const st = md->st;
        struct payload_digest *p;
@@ -789,12 +804,12 @@ modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
        return STF_IGNORE;
 }
 
-/*
+/**
  * Send ModeCfg request message from client to server in pull mode
  */
-stf_status
-modecfg_send_request(struct state *st)
+stf_status modecfg_send_request(struct state *st)
 {
+       connection_t *c = st->st_connection;
        stf_status stat;
        internal_addr_t ia;
 
@@ -802,6 +817,7 @@ modecfg_send_request(struct state *st)
 
        ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
                                | LELEM(INTERNAL_IP4_NETMASK);
+       ia.ipaddr = c->spd.this.host_srcip;
 
        plog("sending ModeCfg request");
        st->st_state = STATE_MODE_CFG_I1;
@@ -818,14 +834,14 @@ modecfg_send_request(struct state *st)
  *
  * used in ModeCfg pull mode, on the server (responder)
  */
-stf_status
-modecfg_inR0(struct msg_digest *md)
+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;
+       host_t *requested_vip;
 
        stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
        if (stat != STF_OK)
@@ -833,9 +849,20 @@ modecfg_inR0(struct msg_digest *md)
                return stat;
        }
 
+       if (ia.attr_set & LELEM(INTERNAL_IP4_ADDRESS))
+       {
+               requested_vip = host_create_from_sockaddr((sockaddr_t*)&ia.ipaddr);
+       }
+       else
+       {
+               requested_vip = host_create_any(AF_INET);
+       }
+       plog("peer requested virtual IP %H", requested_vip);
+
        want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
        init_internal_addr(&ia);
-       get_internal_addr(st->st_connection, &ia);
+       get_internal_addr(st->st_connection, requested_vip, &ia);
+       requested_vip->destroy(requested_vip);
 
        if (want_unity_banner)
        {
@@ -862,8 +889,7 @@ modecfg_inR0(struct msg_digest *md)
  *
  * used in ModeCfg pull mode, on the client (initiator)
  */
-stf_status
-modecfg_inI1(struct msg_digest *md)
+stf_status modecfg_inI1(struct msg_digest *md)
 {
        struct state *const st = md->st;
        u_int16_t isama_id;
@@ -883,17 +909,19 @@ modecfg_inI1(struct msg_digest *md)
 }
 
 
-/*
+/**
  * Send ModeCfg set message from server to client in push mode
  */
-stf_status
-modecfg_send_set(struct state *st)
+stf_status modecfg_send_set(struct state *st)
 {
        stf_status stat;
        internal_addr_t ia;
+       host_t *vip;
 
        init_internal_addr(&ia);
-       get_internal_addr(st->st_connection, &ia);
+       vip = host_create_any(AF_INET);
+       get_internal_addr(st->st_connection, vip, &ia);
+       vip->destroy(vip);
 
 #ifdef CISCO_QUIRKS
        ia.unity_banner = UNITY_BANNER_STR;
@@ -915,8 +943,7 @@ modecfg_send_set(struct state *st)
  *
  * used in ModeCfg push mode, on the client (initiator).
  */
-stf_status
-modecfg_inI0(struct msg_digest *md)
+stf_status modecfg_inI0(struct msg_digest *md)
 {
        struct state *const st = md->st;
        u_int16_t isama_id;
@@ -959,8 +986,7 @@ modecfg_inI0(struct msg_digest *md)
  *
  * used in ModeCfg push mode, on the server (responder)
  */
-stf_status
-modecfg_inR3(struct msg_digest *md)
+stf_status modecfg_inR3(struct msg_digest *md)
 {
        struct state *const st = md->st;
        u_int16_t isama_id;
@@ -978,11 +1004,10 @@ modecfg_inR3(struct msg_digest *md)
        return STF_OK;
 }
 
-/*
+/**
  * Send XAUTH credentials request (username + password)
  */
-stf_status
-xauth_send_request(struct state *st)
+stf_status xauth_send_request(struct state *st)
 {
        stf_status stat;
        internal_addr_t ia;
@@ -1006,8 +1031,7 @@ xauth_send_request(struct state *st)
  *
  * used on the XAUTH client (initiator)
  */
-stf_status
-xauth_inI0(struct msg_digest *md)
+stf_status xauth_inI0(struct msg_digest *md)
 {
        struct state *const st = md->st;
        u_int16_t isama_id;
@@ -1112,8 +1136,7 @@ xauth_inI0(struct msg_digest *md)
  *
  *  used on the XAUTH server (responder)
  */
-stf_status
-xauth_inR1(struct msg_digest *md)
+stf_status xauth_inR1(struct msg_digest *md)
 {
        struct state *const st = md->st;
        u_int16_t isama_id;
@@ -1193,8 +1216,7 @@ xauth_inR1(struct msg_digest *md)
  *
  * used on the XAUTH client (initiator)
  */
-stf_status
-xauth_inI1(struct msg_digest *md)
+stf_status xauth_inI1(struct msg_digest *md)
 {
        struct state *const st = md->st;
        u_int16_t isama_id;
@@ -1245,8 +1267,7 @@ xauth_inI1(struct msg_digest *md)
  *
  * used on the XAUTH server (responder)
  */
-stf_status
-xauth_inR2(struct msg_digest *md)
+stf_status xauth_inR2(struct msg_digest *md)
 {
        struct state *const st = md->st;
        u_int16_t isama_id;
index 804c3c4..29de2e9 100644 (file)
@@ -306,24 +306,26 @@ void whack_handle(int whackctlfd)
                || !unpack_str(&msg.left.ca)            /* string  4 */
                || !unpack_str(&msg.left.groups)        /* string  5 */
                || !unpack_str(&msg.left.updown)        /* string  6 */
-               || !unpack_str(&msg.left.virt)          /* string  7 */
-               || !unpack_str(&msg.right.id)           /* string  8 */
-               || !unpack_str(&msg.right.cert)         /* string  9 */
-               || !unpack_str(&msg.right.ca)           /* string 10 */
-               || !unpack_str(&msg.right.groups)       /* string 11 */
-               || !unpack_str(&msg.right.updown)       /* string 12 */
-               || !unpack_str(&msg.right.virt)         /* string 13 */
-               || !unpack_str(&msg.keyid)              /* string 14 */
-               || !unpack_str(&msg.myid)               /* string 15 */
-               || !unpack_str(&msg.cacert)             /* string 16 */
-               || !unpack_str(&msg.ldaphost)           /* string 17 */
-               || !unpack_str(&msg.ldapbase)           /* string 18 */
-               || !unpack_str(&msg.crluri)             /* string 19 */
-               || !unpack_str(&msg.crluri2)            /* string 20 */
-               || !unpack_str(&msg.ocspuri)            /* string 21 */
-               || !unpack_str(&msg.ike)                /* string 22 */
-               || !unpack_str(&msg.esp)                /* string 23 */
-               || !unpack_str(&msg.sc_data)            /* string 24 */
+               || !unpack_str(&msg.left.sourceip)      /* string  7 */
+               || !unpack_str(&msg.left.virt)          /* string  8 */
+               || !unpack_str(&msg.right.id)           /* string  9 */
+               || !unpack_str(&msg.right.cert)         /* string 10 */
+               || !unpack_str(&msg.right.ca)           /* string 11 */
+               || !unpack_str(&msg.right.groups)       /* string 12 */
+               || !unpack_str(&msg.right.updown)       /* string 13 */
+               || !unpack_str(&msg.right.sourceip)     /* string 14 */
+               || !unpack_str(&msg.right.virt)         /* string 15 */
+               || !unpack_str(&msg.keyid)              /* string 16 */
+               || !unpack_str(&msg.myid)               /* string 17 */
+               || !unpack_str(&msg.cacert)             /* string 18 */
+               || !unpack_str(&msg.ldaphost)           /* string 19 */
+               || !unpack_str(&msg.ldapbase)           /* string 20 */
+               || !unpack_str(&msg.crluri)             /* string 21 */
+               || !unpack_str(&msg.crluri2)            /* string 22 */
+               || !unpack_str(&msg.ocspuri)            /* string 23 */
+               || !unpack_str(&msg.ike)                /* string 24 */
+               || !unpack_str(&msg.esp)                /* string 25 */
+               || !unpack_str(&msg.sc_data)            /* string 26 */
                || str_roof - next_str != (ptrdiff_t)msg.keyval.len)    /* check chunk */
                {
                        ugh = "message from whack contains bad string";
index b648d40..f6fbd2d 100644 (file)
@@ -246,7 +246,7 @@ static const token_info_t token_info[] =
        { ARG_STR, offsetof(starter_end_t, subnet), NULL                               },
        { ARG_MISC, 0, NULL  /* KW_SUBNETWITHIN */                                     },
        { ARG_MISC, 0, NULL  /* KW_PROTOPORT */                                        },
-       { ARG_STR, offsetof(starter_end_t, srcip), NULL                                },
+       { ARG_MISC, 0, NULL  /* KW_SOURCEIP */                                             },
        { ARG_MISC, 0, NULL  /* KW_NATIP */                                            },
        { ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool                        },
        { ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool                      },
index c4b8916..45fbb03 100644 (file)
@@ -136,9 +136,8 @@ load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
        }
 }
 
-static void
-kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
-    , kw_list_t *kw, char *conn_name, starter_config_t *cfg)
+static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
+                                  kw_list_t *kw, char *conn_name, starter_config_t *cfg)
 {
        err_t ugh = NULL;
        bool assigned = FALSE;
@@ -188,31 +187,54 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
                        plog("# natip and sourceip cannot be defined at the same time");
                        goto err;
                }
-               if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
-                       streq(value, "%config") || streq(value, "%cfg"))
+               if (value[0] == '%')
                {
-                       free(end->srcip);
-                       end->srcip = NULL;
+                       if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
+                               streq(value, "%config") || streq(value, "%cfg"))
+                       {
+                               /* request ip via config payload */
+                               end->sourceip = NULL;
+                               end->sourceip_mask = 1;
+                       }
+                       else
+                       {       /* %poolname, strip %, serve ip requests */
+                               end->sourceip = clone_str(value+1);
+                               end->sourceip_mask = 0; 
+                       }
                        end->modecfg = TRUE;
                }
                else
                {
+                       char *pos;
                        ip_address addr;
                        ip_subnet net;
 
                        conn->tunnel_addr_family = ip_version(value);
-                       if (strchr(value, '/'))
+                       pos = strchr(value, '/');
+
+                       if (pos)
                        {       /* CIDR notation, address pool */
                                ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &net);
+                               if (ugh != NULL)
+                               {
+                                       plog("# bad subnet: %s=%s [%s]", name, value, ugh);
+                                       goto err;
+                                }
+                               *pos = '\0';
+                               end->sourceip = clone_str(value);
+                               end->sourceip_mask = atoi(pos + 1);
                        }
-                       else if (value[0] != '%')
-                       {       /* old style fixed srcip, a %poolname otherwise */
+                       else 
+                       {       /* fixed srcip */
                                ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr);
-                       }
-                       if (ugh != NULL)
-                       {
-                               plog("# bad addr: %s=%s [%s]", name, value, ugh);
-                               goto err;
+                               if (ugh != NULL)
+                               {
+                                       plog("# bad addr: %s=%s [%s]", name, value, ugh);
+                                       goto err;
+                               }
+                               end->sourceip = clone_str(value);
+                               end->sourceip_mask = (conn->tunnel_addr_family == AF_INET) ?
+                                                                         32 : 128;
                        }
                }
                conn->policy |= POLICY_TUNNEL;
@@ -302,7 +324,9 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
                if (streq(value, "%defaultroute"))
                {
                        if (cfg->defaultroute.defined)
+                       {
                                end->nexthop = cfg->defaultroute.nexthop;
+                       }
                        else
                        {
                                plog("# default route not known: %s=%s", name, value);
@@ -346,7 +370,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
                end->has_port_wildcard = has_port_wildcard;
                break;
        case KW_NATIP:
-               if (end->srcip)
+               if (end->sourceip)
                {
                        plog("# natip and sourceip cannot be defined at the same time");
                        goto err;
@@ -358,7 +382,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
                        if (cfg->defaultroute.defined)
                        {
                                addrtot(&cfg->defaultroute.addr, 0, buf, sizeof(buf));
-                               end->srcip = clone_str(buf);
+                               end->sourceip = clone_str(buf);
                        }
                        else
                        {
@@ -377,7 +401,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
                                plog("# bad addr: %s=%s [%s]", name, value, ugh);
                                goto err;
                        }
-                       end->srcip = clone_str(value);
+                       end->sourceip = clone_str(value);
                }
                end->has_natip = TRUE;
                conn->policy |= POLICY_TUNNEL;
index 9fc1138..12ea6b0 100644 (file)
@@ -82,7 +82,8 @@ struct starter_end {
                char            *updown;
                u_int16_t       port;
                u_int8_t        protocol;
-               char            *srcip;
+               char            *sourceip;
+               int                             sourceip_mask;
 };
 
 typedef struct also also_t;
index 60da12b..b0eb419 100644 (file)
@@ -187,45 +187,13 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
        ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
        msg_end->address = push_string(msg, buffer);
        msg_end->subnets = push_string(msg, conn_end->subnet);
+       msg_end->sourceip = push_string(msg, conn_end->sourceip);
+       msg_end->sourceip_mask = conn_end->sourceip_mask;
        msg_end->sendcert = conn_end->sendcert;
        msg_end->hostaccess = conn_end->hostaccess;
        msg_end->tohost = !conn_end->has_client;
        msg_end->protocol = conn_end->protocol;
        msg_end->port = conn_end->port;
-       if (conn_end->srcip)
-       {
-               if (conn_end->srcip[0] == '%')
-               {       /* %poolname, strip % */
-                       msg_end->sourceip_size = 0;
-                       msg_end->sourceip = push_string(msg, conn_end->srcip + 1);
-               }
-               else
-               {
-                       char *pos = strchr(conn_end->srcip, '/');
-                       if (pos)
-                       {       /* CIDR subnet definition */
-                               snprintf(buffer, pos - conn_end->srcip + 1, "%s", conn_end->srcip);
-                               msg_end->sourceip = push_string(msg, buffer);
-                               msg_end->sourceip_size = atoi(pos + 1);
-                       }
-                       else
-                       {       /* a single address */
-                               msg_end->sourceip = push_string(msg, conn_end->srcip);
-                               if (strchr(conn_end->srcip, ':'))
-                               {       /* IPv6 */
-                                       msg_end->sourceip_size = 128;
-                               }
-                               else
-                               {       /* IPv4 */
-                                       msg_end->sourceip_size = 32;
-                               }
-                       }
-               }
-       }
-       else if (conn_end->modecfg)
-       {
-               msg_end->sourceip_size = 1;
-       }
 }
 
 int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
index b680961..d3c6fc5 100644 (file)
@@ -33,8 +33,7 @@
 
 #define ip_version(string)      (strchr(string, '.') ? AF_INET : AF_INET6)
 
-static int
-pack_str (char **p, char **next, char **roof)
+static int pack_str (char **p, char **next, char **roof)
 {
        const char *s = (*p==NULL) ? "" : *p;    /* note: NULL becomes ""! */
        size_t len = strlen(s) + 1;
@@ -52,8 +51,7 @@ pack_str (char **p, char **next, char **roof)
        }
 }
 
-static int
-send_whack_msg (whack_message_t *msg)
+static int send_whack_msg (whack_message_t *msg)
 {
        struct sockaddr_un ctl_addr;
        int sock;
@@ -67,37 +65,41 @@ send_whack_msg (whack_message_t *msg)
        str_next = (char *)msg->string;
        str_roof = (char *)&msg->string[sizeof(msg->string)];
 
-       if (!pack_str(&msg->name,         &str_next, &str_roof)
-       ||  !pack_str(&msg->left.id,      &str_next, &str_roof)
-       ||  !pack_str(&msg->left.cert,    &str_next, &str_roof)
-       ||  !pack_str(&msg->left.ca,      &str_next, &str_roof)
-       ||  !pack_str(&msg->left.groups,  &str_next, &str_roof)
-       ||  !pack_str(&msg->left.updown,  &str_next, &str_roof)
-       ||  !pack_str(&msg->left.virt,    &str_next, &str_roof)
-       ||  !pack_str(&msg->right.id,     &str_next, &str_roof)
-       ||  !pack_str(&msg->right.cert,   &str_next, &str_roof)
-       ||  !pack_str(&msg->right.ca,     &str_next, &str_roof)
-       ||  !pack_str(&msg->right.groups, &str_next, &str_roof)
-       ||  !pack_str(&msg->right.updown, &str_next, &str_roof)
-       || !pack_str(&msg->right.virt,    &str_next, &str_roof)
-       || !pack_str(&msg->keyid,         &str_next, &str_roof)
-       || !pack_str(&msg->myid,          &str_next, &str_roof)
-       || !pack_str(&msg->cacert,        &str_next, &str_roof)
-       || !pack_str(&msg->ldaphost,      &str_next, &str_roof)
-       || !pack_str(&msg->ldapbase,      &str_next, &str_roof)
-       || !pack_str(&msg->crluri,        &str_next, &str_roof)
-       || !pack_str(&msg->crluri2,       &str_next, &str_roof)
-       || !pack_str(&msg->ocspuri,       &str_next, &str_roof)
-       || !pack_str(&msg->ike,           &str_next, &str_roof)
-       || !pack_str(&msg->esp,           &str_next, &str_roof)
-       || !pack_str(&msg->sc_data,       &str_next, &str_roof)
-       || (str_roof - str_next < msg->keyval.len))
+       if (!pack_str(&msg->name,           &str_next, &str_roof)
+       ||  !pack_str(&msg->left.id,        &str_next, &str_roof)
+       ||  !pack_str(&msg->left.cert,      &str_next, &str_roof)
+       ||  !pack_str(&msg->left.ca,        &str_next, &str_roof)
+       ||  !pack_str(&msg->left.groups,    &str_next, &str_roof)
+       ||  !pack_str(&msg->left.updown,    &str_next, &str_roof)
+       ||  !pack_str(&msg->left.sourceip,  &str_next, &str_roof)
+       ||  !pack_str(&msg->left.virt,      &str_next, &str_roof)
+       ||  !pack_str(&msg->right.id,       &str_next, &str_roof)
+       ||  !pack_str(&msg->right.cert,     &str_next, &str_roof)
+       ||  !pack_str(&msg->right.ca,       &str_next, &str_roof)
+       ||  !pack_str(&msg->right.groups,   &str_next, &str_roof)
+       ||  !pack_str(&msg->right.updown,   &str_next, &str_roof)
+       ||  !pack_str(&msg->right.sourceip, &str_next, &str_roof)
+       ||  !pack_str(&msg->right.virt,     &str_next, &str_roof)
+       ||  !pack_str(&msg->keyid,          &str_next, &str_roof)
+       ||  !pack_str(&msg->myid,           &str_next, &str_roof)
+       ||  !pack_str(&msg->cacert,         &str_next, &str_roof)
+       ||  !pack_str(&msg->ldaphost,       &str_next, &str_roof)
+       ||  !pack_str(&msg->ldapbase,       &str_next, &str_roof)
+       ||  !pack_str(&msg->crluri,         &str_next, &str_roof)
+       ||  !pack_str(&msg->crluri2,        &str_next, &str_roof)
+       ||  !pack_str(&msg->ocspuri,        &str_next, &str_roof)
+       ||  !pack_str(&msg->ike,            &str_next, &str_roof)
+       ||  !pack_str(&msg->esp,            &str_next, &str_roof)
+       ||  !pack_str(&msg->sc_data,        &str_next, &str_roof)
+       ||  (str_roof - str_next < msg->keyval.len))
        {
                plog("send_wack_msg(): can't pack strings");
                return -1;
        }
        if (msg->keyval.ptr)
+       {
                memcpy(str_next, msg->keyval.ptr, msg->keyval.len);
+       }
        msg->keyval.ptr = NULL;
        str_next += msg->keyval.len;
        len = str_next - (char *)msg;
@@ -130,15 +132,13 @@ send_whack_msg (whack_message_t *msg)
        return 0;
 }
 
-static void
-init_whack_msg(whack_message_t *msg)
+static void init_whack_msg(whack_message_t *msg)
 {
        memset(msg, 0, sizeof(whack_message_t));
        msg->magic = WHACK_MAGIC;
 }
 
-static char *
-connection_name(starter_conn_t *conn)
+static char *connection_name(starter_conn_t *conn)
 {
        /* if connection name is '%auto', create a new name like conn_xxxxx */
        static char buf[32];
@@ -151,35 +151,27 @@ connection_name(starter_conn_t *conn)
        return conn->name;
 }
 
-static void
-set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
+static void set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
 {
-       if (end->srcip && end->srcip[0] != '%')
+       w->id                  = end->id;
+       w->cert                = end->cert;
+       w->ca                  = end->ca;
+       w->groups              = end->groups;
+       w->host_addr           = end->addr;
+       w->has_client          = end->has_client;
+       w->sourceip            = end->sourceip;
+       w->sourceip_mask       = end->sourceip_mask;
+       
+       if (end->sourceip && end->sourceip_mask > 0)
        {
-               int len = 0;
-               char *pos;
-
-               pos = strchr(end->srcip, '/');
-               if (pos)
-               {
-                       /* use first address only for pluto */
-                       len = pos - end->srcip;
-               }
+               ttoaddr(end->sourceip, 0, ip_version(end->sourceip), &w->host_srcip);
                w->has_srcip = !end->has_natip;
-               ttoaddr(end->srcip, len, ip_version(end->srcip), &w->host_srcip);
        }
        else
        {
                anyaddr(AF_INET, &w->host_srcip);
        }
 
-       w->id                  = end->id;
-       w->cert                = end->cert;
-       w->ca                  = end->ca;
-       w->groups              = end->groups;
-       w->host_addr           = end->addr;
-       w->has_client          = end->has_client;
-
        if (family == AF_INET6 && isanyaddr(&end->nexthop))
        {
                anyaddr(AF_INET6, &end->nexthop);
@@ -266,8 +258,7 @@ starter_whack_add_pubkey (starter_conn_t *conn, starter_end_t *end
        return 0;
 }
 
-int
-starter_whack_add_conn(starter_conn_t *conn)
+int starter_whack_add_conn(starter_conn_t *conn)
 {
        whack_message_t msg;
        int r;
@@ -332,8 +323,7 @@ starter_whack_add_conn(starter_conn_t *conn)
        return r;
 }
 
-int
-starter_whack_del_conn(starter_conn_t *conn)
+int starter_whack_del_conn(starter_conn_t *conn)
 {
        whack_message_t msg;
 
@@ -343,8 +333,7 @@ starter_whack_del_conn(starter_conn_t *conn)
        return send_whack_msg(&msg);
 }
 
-int
-starter_whack_route_conn(starter_conn_t *conn)
+int starter_whack_route_conn(starter_conn_t *conn)
 {
        whack_message_t msg;
 
@@ -354,8 +343,7 @@ starter_whack_route_conn(starter_conn_t *conn)
        return send_whack_msg(&msg);
 }
 
-int
-starter_whack_initiate_conn(starter_conn_t *conn)
+int starter_whack_initiate_conn(starter_conn_t *conn)
 {
        whack_message_t msg;
 
@@ -366,8 +354,7 @@ starter_whack_initiate_conn(starter_conn_t *conn)
        return send_whack_msg(&msg);
 }
 
-int
-starter_whack_listen(void)
+int starter_whack_listen(void)
 {
        whack_message_t msg;
        init_whack_msg(&msg);
@@ -384,8 +371,7 @@ int starter_whack_shutdown(void)
        return send_whack_msg(&msg);
 }
 
-int
-starter_whack_add_ca(starter_ca_t *ca)
+int starter_whack_add_ca(starter_ca_t *ca)
 {
        whack_message_t msg;
 
@@ -404,8 +390,7 @@ starter_whack_add_ca(starter_ca_t *ca)
        return send_whack_msg(&msg);
 }
 
-int
-starter_whack_del_ca(starter_ca_t *ca)
+int starter_whack_del_ca(starter_ca_t *ca)
 {
        whack_message_t msg;
 
index f6cf091..ace0401 100644 (file)
@@ -138,7 +138,7 @@ struct stroke_end_t {
        char *updown;
        char *address;
        char *sourceip;
-       int sourceip_size;
+       int sourceip_mask;
        char *subnets;
        int sendcert;
        int hostaccess;
index 817a676..c458d67 100644 (file)
@@ -1745,31 +1745,33 @@ int main(int argc, char **argv)
                                        msg.pfsgroup ? msg.pfsgroup : "");
                        msg.esp=esp_buf;
        }
-       if (!pack_str(&msg.name)            /* string  1 */
-       || !pack_str(&msg.left.id)          /* string  2 */
-       || !pack_str(&msg.left.cert)        /* string  3 */
-       || !pack_str(&msg.left.ca)          /* string  4 */
-       || !pack_str(&msg.left.groups)      /* string  5 */
-       || !pack_str(&msg.left.updown)      /* string  6 */
-       || !pack_str(&msg.left.virt)        /* string  7 */
-       || !pack_str(&msg.right.id)         /* string  8 */
-       || !pack_str(&msg.right.cert)       /* string  9 */
-       || !pack_str(&msg.right.ca)         /* string 10 */
-       || !pack_str(&msg.right.groups)     /* string 11 */
-       || !pack_str(&msg.right.updown)     /* string 12 */
-       || !pack_str(&msg.right.virt)       /* string 13 */
-       || !pack_str(&msg.keyid)            /* string 14 */
-       || !pack_str(&msg.myid)             /* string 15 */
-       || !pack_str(&msg.cacert)           /* string 16 */
-       || !pack_str(&msg.ldaphost)         /* string 17 */
-       || !pack_str(&msg.ldapbase)         /* string 18 */
-       || !pack_str(&msg.crluri)           /* string 19 */
-       || !pack_str(&msg.crluri2)          /* string 20 */
-       || !pack_str(&msg.ocspuri)          /* string 21 */
-       || !pack_str(&msg.ike)              /* string 22 */
-       || !pack_str(&msg.esp)              /* string 23 */
-       || !pack_str(&msg.sc_data)          /* string 24 */
-       || str_roof - next_str < (ptrdiff_t)msg.keyval.len)    /* chunk (sort of string 5) */
+       if (!pack_str(&msg.name)             /* string  1 */
+       ||  !pack_str(&msg.left.id)          /* string  2 */
+       ||  !pack_str(&msg.left.cert)        /* string  3 */
+       ||  !pack_str(&msg.left.ca)          /* string  4 */
+       ||  !pack_str(&msg.left.groups)      /* string  5 */
+       ||  !pack_str(&msg.left.updown)      /* string  6 */
+       ||  !pack_str(&msg.left.sourceip)    /* string  7 */
+       ||  !pack_str(&msg.left.virt)        /* string  8 */
+       ||  !pack_str(&msg.right.id)         /* string  9 */
+       ||  !pack_str(&msg.right.cert)       /* string 10 */
+       ||  !pack_str(&msg.right.ca)         /* string 11 */
+       ||  !pack_str(&msg.right.groups)     /* string 12 */
+       ||  !pack_str(&msg.right.updown)     /* string 13 */
+       ||  !pack_str(&msg.right.sourceip)   /* string 14 */
+       ||  !pack_str(&msg.right.virt)       /* string 15 */
+       ||  !pack_str(&msg.keyid)            /* string 16 */
+       ||  !pack_str(&msg.myid)             /* string 17 */
+       ||  !pack_str(&msg.cacert)           /* string 18 */
+       ||  !pack_str(&msg.ldaphost)         /* string 19 */
+       ||  !pack_str(&msg.ldapbase)         /* string 20 */
+       ||  !pack_str(&msg.crluri)           /* string 21 */
+       ||  !pack_str(&msg.crluri2)          /* string 22 */
+       ||  !pack_str(&msg.ocspuri)          /* string 23 */
+       ||  !pack_str(&msg.ike)              /* string 24 */
+       ||  !pack_str(&msg.esp)              /* string 25 */
+       ||  !pack_str(&msg.sc_data)          /* string 26 */
+       ||  str_roof - next_str < (ptrdiff_t)msg.keyval.len)
                diag("too many bytes of strings to fit in message to pluto");
 
        memcpy(next_str, msg.keyval.ptr, msg.keyval.len);
index 5a04171..6d5f0fb 100644 (file)
@@ -60,12 +60,12 @@ struct whack_end {
        char *cert;         /* path string (if any) -- loaded by pluto  */
        char *ca;           /* distinguished name string (if any) -- parsed by pluto */
        char *groups;       /* access control groups (if any) -- parsed by pluto */
-       ip_address
-               host_addr,
-               host_nexthop,
-               host_srcip;
+       char *sourceip;         /* source IP address or pool identifier -- parsed by pluto */
+       int   sourceip_mask;
+       ip_address host_addr;
+       ip_address host_nexthop;
+       ip_address host_srcip;  
        ip_subnet client;
-
        bool key_from_DNS_on_demand;
        bool has_client;
        bool has_client_wildcard;