summaryrefslogtreecommitdiff
path: root/programs
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2006-11-06 19:00:10 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2006-11-06 19:00:10 +0000
commit58d26e02cd8686e177eebb9fb81e6b17798bbb30 (patch)
treee7329ae5a85bb2d6b8bba0ebcd65c6c41999f96f /programs
parent0b5d496ea2fd532dcf5e5b6b804a7db32f488364 (diff)
downloadvyos-strongswan-58d26e02cd8686e177eebb9fb81e6b17798bbb30.tar.gz
vyos-strongswan-58d26e02cd8686e177eebb9fb81e6b17798bbb30.zip
Load /tmp/tmp.IBEBMao893/strongswan-2.8.0+dfsg into
branches/source-dist/debian/strongswan.
Diffstat (limited to 'programs')
-rw-r--r--programs/Makefile4
-rw-r--r--programs/pluto/connections.c9
-rw-r--r--programs/pluto/connections.h3
-rw-r--r--programs/pluto/constants.c7
-rw-r--r--programs/pluto/constants.h28
-rw-r--r--programs/pluto/demux.c47
-rw-r--r--programs/pluto/log.c4
-rw-r--r--programs/pluto/modecfg.c779
-rw-r--r--programs/pluto/modecfg.h19
-rw-r--r--programs/pluto/state.c17
-rw-r--r--programs/pluto/state.h6
-rw-r--r--programs/pluto/vendor.c10
-rw-r--r--programs/pluto/vendor.h6
-rw-r--r--programs/pluto/whack.h3
-rw-r--r--programs/starter/args.c4
-rw-r--r--programs/starter/confread.c26
-rw-r--r--programs/starter/confread.h9
-rw-r--r--programs/starter/keywords.c179
-rw-r--r--programs/starter/keywords.h8
-rw-r--r--programs/starter/keywords.txt5
-rw-r--r--programs/starter/starterwhack.c3
21 files changed, 540 insertions, 636 deletions
diff --git a/programs/Makefile b/programs/Makefile
index 03c9d582a..dbc03f416 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -12,7 +12,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: Makefile,v 1.8 2006/04/17 11:04:45 as Exp $
+# RCSID $Id: Makefile,v 1.9 2006/08/28 11:12:36 as Exp $
FREESWANSRCDIR=..
include ${FREESWANSRCDIR}/Makefile.inc
@@ -42,5 +42,5 @@ cleanall distclean mostlyclean realclean install programs checkprograms check cl
@for d in $(SUBDIRS) ; \
do \
(cd $$d && $(MAKE) FREESWANSRCDIR=$(FREESWANSRCDIR)/.. $@ ) || exit 1;\
- done; \
+ done;
diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c
index 8bd3ed49b..1ea6ac5fa 100644
--- a/programs/pluto/connections.c
+++ b/programs/pluto/connections.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: connections.c,v 1.44 2006/07/06 19:20:09 as Exp $
+ * RCSID $Id: connections.c,v 1.46 2006/10/19 15:40:52 as Exp $
*/
#include <string.h>
@@ -862,6 +862,7 @@ extract_end(struct end *dst, const whack_end_t *src, const char *which)
dst->host_addr = src->host_addr;
dst->host_nexthop = src->host_nexthop;
dst->host_srcip = src->host_srcip;
+ dst->has_natip = src->has_natip;
dst->client = src->client;
dst->protocol = src->protocol;
dst->port = src->port;
@@ -880,6 +881,7 @@ extract_end(struct end *dst, const whack_end_t *src, const char *which)
*/
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);
@@ -2024,7 +2026,8 @@ cannot_oppo(struct connection *c
char state_buf2[LOG_WIDTH];
time_t n = now();
- fmt_state(st, n, state_buf, sizeof(state_buf)
+ fmt_state(FALSE, st, n
+ , state_buf, sizeof(state_buf)
, state_buf2, sizeof(state_buf2));
DBG_log("cannot_oppo, failure SA1: %s", state_buf);
DBG_log("cannot_oppo, failure SA2: %s", state_buf2);
@@ -3065,7 +3068,7 @@ ISAKMP_SA_established(struct connection *c, so_serial_t serial)
/* the connection is now oriented so that we are able to determine
* whether we are a mode config server with a virtual IP to send.
*/
- if (!isanyaddr(&c->spd.that.host_srcip))
+ if (!isanyaddr(&c->spd.that.host_srcip) && !c->spd.that.has_natip)
c->spd.that.modecfg = TRUE;
if (uniqueIDs)
diff --git a/programs/pluto/connections.h b/programs/pluto/connections.h
index 6dfddbe22..33fbc3fea 100644
--- a/programs/pluto/connections.h
+++ b/programs/pluto/connections.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: connections.h,v 1.18 2006/04/22 21:59:20 as Exp $
+ * RCSID $Id: connections.h,v 1.19 2006/10/19 15:38:27 as Exp $
*/
#ifndef _CONNECTIONS_H
@@ -143,6 +143,7 @@ struct end {
bool has_client_wildcard;
bool has_port_wildcard;
bool has_id_wildcards;
+ bool has_natip;
char *updown;
u_int16_t host_port; /* host order */
u_int16_t port; /* host order */
diff --git a/programs/pluto/constants.c b/programs/pluto/constants.c
index 27e4db1e0..5ca7b65ce 100644
--- a/programs/pluto/constants.c
+++ b/programs/pluto/constants.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: constants.c,v 1.21 2006/03/27 07:38:59 as Exp $
+ * RCSID $Id: constants.c,v 1.22 2006/10/19 21:07:40 as Exp $
*/
/*
@@ -188,6 +188,7 @@ static const char *const state_name[] = {
"STATE_MODE_CFG_R2",
"STATE_MODE_CFG_I1",
"STATE_MODE_CFG_I2",
+ "STATE_MODE_CFG_I3",
"STATE_IKE_ROOF"
};
@@ -218,9 +219,10 @@ const char *const state_story[] = {
"sent ModeCfg reply", /* STATE_MODE_CFG_R0 */
"sent ModeCfg reply", /* STATE_MODE_CFG_R1 */
- "ModeCfg R2", /* STATE_MODE_CFG_R2 */
+ "received ModeCfg ack", /* STATE_MODE_CFG_R2 */
"sent ModeCfg request, expecting reply", /* STATE_MODE_CFG_I1 */
"received ModeCfg reply", /* STATE_MODE_CFG_I2 */
+ "received ModeCfg set, sent ack", /* STATE_MODE_CFG_I3 */
};
/* kind of struct connection */
@@ -484,6 +486,7 @@ const char *const sa_policy_bit_names[] = {
"GROUP",
"GROUTED",
"UP",
+ "MODECFGPUSH",
NULL
};
diff --git a/programs/pluto/constants.h b/programs/pluto/constants.h
index b66d002ee..bad162898 100644
--- a/programs/pluto/constants.h
+++ b/programs/pluto/constants.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: constants.h,v 1.20 2006/02/28 19:13:33 as Exp $
+ * RCSID $Id: constants.h,v 1.22 2006/10/19 21:07:40 as Exp $
*/
#ifndef _CONSTANTS_H
@@ -510,6 +510,7 @@ enum state_kind {
STATE_MODE_CFG_I1, /* this is used on the initiator */
STATE_MODE_CFG_I2,
+ STATE_MODE_CFG_I3,
STATE_IKE_ROOF
};
@@ -519,17 +520,21 @@ enum state_kind {
#define PHASE1_INITIATOR_STATES (LELEM(STATE_MAIN_I1) | LELEM(STATE_MAIN_I2) \
| LELEM(STATE_MAIN_I3) | LELEM(STATE_MAIN_I4))
#define ISAKMP_SA_ESTABLISHED_STATES (LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \
- | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2))
+ | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_R2) \
+ | LELEM(STATE_MODE_CFG_I2) | LELEM(STATE_MODE_CFG_I3))
#define IS_PHASE1(s) ((STATE_MAIN_R0 <= (s) && (s) <= STATE_MAIN_I4) \
- || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_I2))
+ || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_I3))
#define IS_QUICK(s) (STATE_QUICK_R0 <= (s) && (s) <= STATE_QUICK_R2)
#define IS_ISAKMP_ENCRYPTED(s) (STATE_MAIN_I2 <= (s))
-#define IS_ISAKMP_SA_ESTABLISHED(s) ((s) == STATE_MAIN_R3 \
- || (s) == STATE_MAIN_I4 \
+#define IS_ISAKMP_SA_ESTABLISHED(s) ( \
+ (s) == STATE_MAIN_R3 \
+ || (s) == STATE_MAIN_I4 \
|| (s) == STATE_MODE_CFG_R0 \
|| (s) == STATE_MODE_CFG_R1 \
- || (s) == STATE_MODE_CFG_I2)
+ || (s) == STATE_MODE_CFG_R2 \
+ || (s) == STATE_MODE_CFG_I2 \
+ || (s) == STATE_MODE_CFG_I3)
#define IS_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_I2 || (s) == STATE_QUICK_R2)
#define IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_R1)
@@ -783,11 +788,12 @@ extern const char *prettypolicy(lset_t policy);
/* connection policy
* Other policies could vary per state object. These live in connection.
*/
-#define POLICY_DONT_REKEY LELEM(12) /* don't rekey state either Phase */
-#define POLICY_OPPO LELEM(13) /* is this opportunistic? */
-#define POLICY_GROUP LELEM(14) /* is this a group template? */
-#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */
-#define POLICY_UP LELEM(16) /* do we want this up? */
+#define POLICY_DONT_REKEY LELEM(12) /* don't rekey state either Phase */
+#define POLICY_OPPO LELEM(13) /* is this opportunistic? */
+#define POLICY_GROUP LELEM(14) /* is this a group template? */
+#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */
+#define POLICY_UP LELEM(16) /* do we want this up? */
+#define POLICY_MODECFG_PUSH LELEM(17) /* is modecfg pushed by server? */
/* Any IPsec policy? If not, a connection description
diff --git a/programs/pluto/demux.c b/programs/pluto/demux.c
index db7f1c4a6..3146b3d40 100644
--- a/programs/pluto/demux.c
+++ b/programs/pluto/demux.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: demux.c,v 1.14 2006/06/22 11:58:25 as Exp $
+ * RCSID $Id: demux.c,v 1.16 2006/10/19 21:07:40 as Exp $
*/
/* Ordering Constraints on Payloads
@@ -481,7 +481,17 @@ static const struct state_microcode state_microcode_table[] = {
{ STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
, P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR1 },
+ , EVENT_SA_REPLACE, modecfg_inI1 },
+
+ { STATE_MODE_CFG_I2, STATE_MODE_CFG_I3
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inI2 },
+
+ { STATE_MODE_CFG_I3, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
#undef P
#undef PT
@@ -1441,7 +1451,7 @@ process_packet(struct msg_digest **mdp)
{
st->st_state = STATE_MAIN_R3; /* ISAKMP is up... */
}
-
+
set_cur_state(st);
if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
@@ -1471,7 +1481,7 @@ process_packet(struct msg_digest **mdp)
}
else
{
- set_cur_state(st);
+ set_cur_state(st);
from_state = st->st_state;
}
@@ -1563,7 +1573,7 @@ process_packet(struct msg_digest **mdp)
else if (st->st_connection->spd.this.modecfg
&& IS_PHASE1(st->st_state))
{
- from_state = STATE_MODE_CFG_R1;
+ from_state = STATE_MODE_CFG_I2;
}
else
{
@@ -2323,38 +2333,39 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
, story, sadetails);
}
- /* Should we start Mode Config as a client */
+ /* Should we start ModeConfig as a client? */
if (st->st_connection->spd.this.modecfg
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !(st->st_connection->policy & POLICY_MODECFG_PUSH)
&& !st->st_modecfg.started)
{
DBG(DBG_CONTROL,
- DBG_log("modecfg client is starting")
+ DBG_log("starting ModeCfg client in pull mode")
)
modecfg_send_request(st);
break;
}
- /* Should we set the peer's IP address regardless? */
-/* if (st->st_connection->spd.that.modecfg
+ /* Should we start ModeConfig as a server? */
+ if (st->st_connection->spd.that.modecfg
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_modecfg.vars_set
- && !(st->st_connection->policy & POLICY_MODECFG_PULL))
+ && !st->st_modecfg.started
+ && (st->st_connection->policy & POLICY_MODECFG_PUSH))
{
- st->st_state = STATE_MODE_CFG_R1;
- set_cur_state(st);
- plog("Sending MODE CONFIG set");
- modecfg_start_set(st);
+ DBG(DBG_CONTROL,
+ DBG_log("starting ModeCfg server in push mode")
+ )
+ modecfg_send_set(st);
break;
}
-*/
- /* wait for modecfg_set */
+
+ /* Wait for ModeConfig set from server */
if (st->st_connection->spd.this.modecfg
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
&& !st->st_modecfg.vars_set)
{
DBG(DBG_CONTROL,
- DBG_log("waiting for modecfg set from server")
+ DBG_log("waiting for ModeCfg set from server")
)
break;
}
diff --git a/programs/pluto/log.c b/programs/pluto/log.c
index 73ffceccd..aef93ff3c 100644
--- a/programs/pluto/log.c
+++ b/programs/pluto/log.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: log.c,v 1.8 2006/04/29 18:16:02 as Exp $
+ * RCSID $Id: log.c,v 1.9 2006/10/17 10:30:54 as Exp $
*/
#include <stdio.h>
@@ -773,7 +773,7 @@ show_status(bool all, const char *name)
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
}
show_connections_status(all, name);
- show_states_status(name);
+ show_states_status(all, name);
#ifdef KLIPS
show_shunt_status();
#endif
diff --git a/programs/pluto/modecfg.c b/programs/pluto/modecfg.c
index 1c22845a5..ec334aaf5 100644
--- a/programs/pluto/modecfg.c
+++ b/programs/pluto/modecfg.c
@@ -2,6 +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
*
* 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
@@ -13,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.c,v 1.6 2006/04/24 20:44:57 as Exp $
+ * RCSID $Id: modecfg.c,v 1.9 2006/10/21 17:11:13 as Exp $
*
* This code originally written by Colubris Networks, Inc.
* Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
@@ -39,23 +40,46 @@
#include "modecfg.h"
#include "whack.h"
+#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
+ | LELEM(INTERNAL_IP4_NETMASK) \
+ | LELEM(INTERNAL_IP4_DNS) \
+ | LELEM(INTERNAL_IP4_NBNS) \
+ )
+
/*
- * Addresses assigned (usually via MODE_CONFIG) to the Initiator
+ * Addresses assigned (usually via ModeCfg) to the Initiator
*/
+typedef struct internal_addr internal_addr_t;
+
struct internal_addr
{
+ lset_t attr_set;
ip_address ipaddr;
ip_address dns[2];
- ip_address wins[2];
+ ip_address wins[2];
};
/*
- * Get inside IP address for a connection
+ * Initialize an internal_addr struct
*/
static void
-get_internal_addresses(struct connection *c, struct internal_addr *ia)
+init_internal_addr(internal_addr_t *ia)
{
- zero(ia);
+ ia->attr_set = LEMPTY;
+ anyaddr(AF_INET, &ia->ipaddr);
+ anyaddr(AF_INET, &ia->dns[0]);
+ anyaddr(AF_INET, &ia->dns[1]);
+ anyaddr(AF_INET, &ia->wins[0]);
+ anyaddr(AF_INET, &ia->wins[1]);
+}
+
+/*
+ * get internal IP address for a connection
+ */
+static void
+get_internal_addr(struct connection *c, internal_addr_t *ia)
+{
+ init_internal_addr(ia);
if (isanyaddr(&c->spd.that.host_srcip))
{
@@ -63,16 +87,78 @@ get_internal_addresses(struct connection *c, struct internal_addr *ia)
}
else
{
+ char srcip[ADDRTOT_BUF];
+
ia->ipaddr = c->spd.that.host_srcip;
+
+ addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
+ plog("assigning virtual IP source address %s", srcip);
+ }
+
+ if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
+ {
+ c->spd.that.client.addr = ia->ipaddr;
+ c->spd.that.client.maskbits = 32;
+ c->spd.that.has_client = TRUE;
+
+ ia->attr_set |= LELEM(INTERNAL_IP4_ADDRESS) | LELEM(INTERNAL_IP4_NETMASK);
+ }
+
+
+ if (!isanyaddr(&ia->dns[0])) /* We got DNS addresses, send them */
+ ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
+
+ if (!isanyaddr(&ia->wins[0])) /* We got WINS addresses, send them */
+ ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
+}
+
+/*
+ * Set srcip and client subnet to internal IP address
+ */
+static bool
+set_internal_addr(struct connection *c, internal_addr_t *ia)
+{
+ if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
+ && !isanyaddr(&ia->ipaddr))
+ {
+ if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
+ || isanyaddr(&c->spd.this.host_srcip)
+ || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr))
+ {
+ char srcip[ADDRTOT_BUF];
+
+ addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
+ plog("setting virtual IP source address to %s", srcip);
+ }
+ else
+ {
+ char old_srcip[ADDRTOT_BUF];
+ char new_srcip[ADDRTOT_BUF];
+
+ addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip));
+ addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip));
+ plog("replacing virtual IP source address %s by %s"
+ , old_srcip, new_srcip);
+ }
+
+ /* setting srcip */
+ c->spd.this.host_srcip = ia->ipaddr;
+
+ /* setting client subnet to srcip/32 */
+ addrtosubnet(&ia->ipaddr, &c->spd.this.client);
+ setportof(0, &c->spd.this.client.addr);
+ c->spd.this.has_client = TRUE;
+ return TRUE;
}
+ return FALSE;
}
/*
* Compute HASH of Mode Config.
*/
static size_t
-mode_cfg_hash(u_char *dest, const u_char *start, const u_char *roof
- , const struct state *st)
+modecfg_hash(u_char *dest, const u_char *start, const u_char *roof
+ , const struct state *st)
{
struct hmac_ctx ctx;
@@ -82,92 +168,51 @@ mode_cfg_hash(u_char *dest, const u_char *start, const u_char *roof
hmac_final(dest, &ctx);
DBG(DBG_CRYPT,
- DBG_log("MODE CFG: HASH computed:");
+ DBG_log("ModeCfg HASH computed:");
DBG_dump("", dest, ctx.hmac_digest_size)
)
return ctx.hmac_digest_size;
}
-/* Mode Config Reply
- * Generates a reply stream containing Mode Config information (eg: IP, DNS, WINS)
+/*
+ * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS)
*/
-stf_status modecfg_resp(struct state *st
- , u_int resp
- , pb_stream *rbody
- , u_int16_t replytype
- , bool hackthat
- , 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;
-
- /* START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_ATTR); */
+ u_char *r_hash_start, *r_hashval;
- {
- pb_stream hash_pbs;
- int np = ISAKMP_NEXT_ATTR;
-
- if (!out_generic(np, &isakmp_hash_desc, rbody, &hash_pbs))
- return STF_INTERNAL_ERROR;
- r_hashval = hash_pbs.cur; /* remember where to plant value */
- if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&hash_pbs);
- r_hash_start = (rbody)->cur; /* hash from after HASH payload */
- }
+ START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
/* ATTR out */
{
- struct isakmp_mode_attr attrh;
+ struct isakmp_mode_attr attrh;
struct isakmp_attribute attr;
pb_stream strattr,attrval;
int attr_type;
- struct internal_addr ia;
int dns_idx, wins_idx;
bool dont_advance;
+ lset_t attr_set = ia->attr_set;
- attrh.isama_np = ISAKMP_NEXT_NONE;
- attrh.isama_type = replytype;
-
+ attrh.isama_np = ISAKMP_NEXT_NONE;
+ attrh.isama_type = msg_type;
attrh.isama_identifier = ap_id;
+
if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
return STF_INTERNAL_ERROR;
- get_internal_addresses(st->st_connection, &ia);
-
- if (!isanyaddr(&ia.dns[0])) /* We got DNS addresses, answer with those */
- resp |= LELEM(INTERNAL_IP4_DNS);
- else
- resp &= ~LELEM(INTERNAL_IP4_DNS);
-
- if (!isanyaddr(&ia.wins[0])) /* We got WINS addresses, answer with those */
- resp |= LELEM(INTERNAL_IP4_NBNS);
- else
- resp &= ~LELEM(INTERNAL_IP4_NBNS);
-
- if (hackthat)
- {
- if (memcmp(&st->st_connection->spd.that.client.addr
- ,&ia.ipaddr
- ,sizeof(ia.ipaddr)) != 0)
- {
- /* Make the Internal IP address and Netmask
- * as that client address
- */
- st->st_connection->spd.that.client.addr = ia.ipaddr;
- st->st_connection->spd.that.client.maskbits = 32;
- st->st_connection->spd.that.has_client = TRUE;
- }
- }
-
attr_type = 0;
dns_idx = 0;
wins_idx = 0;
- while (resp != 0)
+ while (attr_set != 0)
{
dont_advance = FALSE;
- if (resp & 1)
+ if (attr_set & 1)
{
const u_char *byte_ptr;
u_int len;
@@ -179,14 +224,11 @@ stf_status modecfg_resp(struct state *st
switch (attr_type)
{
case INTERNAL_IP4_ADDRESS:
+ if (!isanyaddr(&ia->ipaddr))
{
- char srcip[ADDRTOT_BUF];
-
- addrtot(&ia.ipaddr, 0, srcip, sizeof(srcip));
- plog("assigning virtual IP source address %s", srcip);
- len = addrbytesptr(&ia.ipaddr, &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_addr");
- }
+ len = addrbytesptr(&ia->ipaddr, &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_addr");
+ }
break;
case INTERNAL_IP4_NETMASK:
{
@@ -207,7 +249,7 @@ stf_status modecfg_resp(struct state *st
mask = 0;
else
mask = 0xffffffff * 1;
- out_raw(&mask,4,&attrval,"IP4_mask");
+ out_raw(&mask, 4, &attrval, "IP4_mask");
}
break;
case INTERNAL_IP4_SUBNET:
@@ -228,22 +270,28 @@ stf_status modecfg_resp(struct state *st
m = 0;
}
len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_subnet");
- out_raw(mask,sizeof(mask),&attrval,"IP4_submsk");
+ out_raw(byte_ptr, len, &attrval, "IP4_subnet");
+ out_raw(mask, sizeof(mask), &attrval, "IP4_submsk");
}
break;
case INTERNAL_IP4_DNS:
- len = addrbytesptr(&ia.dns[dns_idx++], &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_dns");
- if (dns_idx < 2 && !isanyaddr(&ia.dns[dns_idx]))
+ if (!isanyaddr(&ia->dns[dns_idx]))
+ {
+ len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_dns");
+ }
+ if (dns_idx < 2 && !isanyaddr(&ia->dns[dns_idx]))
{
dont_advance = TRUE;
}
break;
case INTERNAL_IP4_NBNS:
- len = addrbytesptr(&ia.wins[wins_idx++], &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_wins");
- if (wins_idx < 2 && !isanyaddr(&ia.wins[wins_idx]))
+ if (!isanyaddr(&ia->wins[wins_idx]))
+ {
+ len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_wins");
+ }
+ if (wins_idx < 2 && !isanyaddr(&ia->wins[wins_idx]))
{
dont_advance = TRUE;
}
@@ -254,35 +302,39 @@ stf_status modecfg_resp(struct state *st
break;
}
close_output_pbs(&attrval);
-
}
if (!dont_advance)
{
attr_type++;
- resp >>= 1;
+ attr_set >>= 1;
}
}
close_message(&strattr);
}
- mode_cfg_hash(r_hashval,r_hash_start,rbody->cur,st);
+ modecfg_hash(r_hashval, r_hash_start, rbody->cur,st);
close_message(rbody);
encrypt_message(rbody, st);
return STF_OK;
}
-/* Set MODE_CONFIG data to client.
- * Pack IP Addresses, DNS, etc... and ship
+/*
+ * Send ModeCfg message
*/
-stf_status modecfg_send_set(struct state *st)
+static stf_status
+modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
{
- pb_stream reply,rbody;
- char buf[256];
+ pb_stream msg;
+ pb_stream rbody;
+ char buf[BUF_LEN];
- /* set up reply */
- init_pbs(&reply, buf, sizeof(buf), "ModecfgR1");
+ /* set up attr */
+ init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
+
+ /* this is the beginning of a new exchange */
+ st->st_msgid = generate_msgid(st);
+ init_phase2_iv(st, &st->st_msgid);
- st->st_state = STATE_MODE_CFG_R1;
/* HDR out */
{
struct isakmp_hdr hdr;
@@ -296,503 +348,280 @@ stf_status modecfg_send_set(struct state *st)
memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
hdr.isa_msgid = st->st_msgid;
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
{
return STF_INTERNAL_ERROR;
}
}
-#define MODECFG_SET_ITEM ( LELEM(INTERNAL_IP4_ADDRESS) | LELEM(INTERNAL_IP4_SUBNET) | LELEM(INTERNAL_IP4_NBNS) | LELEM(INTERNAL_IP4_DNS) )
-
- modecfg_resp(st, MODECFG_SET_ITEM
- , &rbody
- , ISAKMP_CFG_SET
- , TRUE
- , 0/* XXX ID */);
-#undef MODECFG_SET_ITEM
+ /* ATTR out */
+ modecfg_build_msg(st, &rbody
+ , isama_type
+ , ia
+ , 0 /* XXX isama_id */
+ );
- clonetochunk(st->st_tpacket, reply.start
- , pbs_offset(&reply), "ModeCfg set");
+ clonetochunk(st->st_tpacket, msg.start, pbs_offset(&msg), "ModeCfg msg");
/* Transmit */
- send_packet(st, "ModeCfg set");
+ send_packet(st, "ModeCfg msg");
- /* RETRANSMIT if Main, SA_REPLACE if Aggressive */
- if (st->st_event->ev_type != EVENT_RETRANSMIT
- && st->st_event->ev_type != EVENT_NULL)
+ if (st->st_event->ev_type != EVENT_RETRANSMIT)
{
delete_event(st);
event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
}
-
+ st->st_modecfg.started = TRUE;
return STF_OK;
}
-/* Set MODE_CONFIG data to client.
- * Pack IP Addresses, DNS, etc... and ship
- */
-stf_status
-modecfg_start_set(struct state *st)
-{
- if (st->st_msgid == 0)
- {
- /* pick a new message id */
- st->st_msgid = generate_msgid(st);
- }
- st->st_modecfg.vars_set = TRUE;
-
- return modecfg_send_set(st);
-}
-
/*
- * Send modecfg IP address request (IP4 address)
+ * Send ModeCfg request message from client to server in pull mode
*/
stf_status
modecfg_send_request(struct state *st)
{
- pb_stream reply;
- pb_stream rbody;
- char buf[256];
- u_char *r_hash_start,*r_hashval;
+ internal_addr_t ia;
- /* set up reply */
- init_pbs(&reply, buf, sizeof(buf), "modecfg_buf");
+ init_internal_addr(&ia);
+ ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
+ | LELEM(INTERNAL_IP4_NETMASK);
plog("sending ModeCfg request");
-
- /* this is the beginning of a new exchange */
- st->st_msgid = generate_msgid(st);
st->st_state = STATE_MODE_CFG_I1;
+ return modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+}
- /* HDR out */
- {
- struct isakmp_hdr hdr;
-
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- hdr.isa_msgid = st->st_msgid;
-
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_ATTR);
-
- /* ATTR out */
- {
- struct isakmp_mode_attr attrh;
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- attrh.isama_np = ISAKMP_NEXT_NONE;
- attrh.isama_type = ISAKMP_CFG_REQUEST;
- attrh.isama_identifier = 0;
- if (!out_struct(&attrh, &isakmp_attr_desc, &rbody, &strattr))
- return STF_INTERNAL_ERROR;
- /* ISAKMP attr out (ipv4) */
- attr.isaat_af_type = INTERNAL_IP4_ADDRESS;
- attr.isaat_lv = 0;
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, NULL);
-
- /* ISAKMP attr out (netmask) */
- attr.isaat_af_type = INTERNAL_IP4_NETMASK;
- attr.isaat_lv = 0;
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, NULL);
-
- close_message(&strattr);
- }
-
- mode_cfg_hash(r_hashval,r_hash_start,rbody.cur,st);
-
- close_message(&rbody);
- close_output_pbs(&reply);
-
- init_phase2_iv(st, &st->st_msgid);
- encrypt_message(&rbody, st);
-
- clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply)
- , "modecfg: req");
-
- /* Transmit */
- send_packet(st, "modecfg: req");
+/*
+ * Send ModeCfg set message from server to client in push mode
+ */
+stf_status
+modecfg_send_set(struct state *st)
+{
+ internal_addr_t ia;
- /* RETRANSMIT if Main, SA_REPLACE if Aggressive */
- if (st->st_event->ev_type != EVENT_RETRANSMIT)
- {
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0 * 3, st);
- }
- st->st_modecfg.started = TRUE;
+ get_internal_addr(st->st_connection, &ia);
- return STF_OK;
+ plog("sending ModeCfg set");
+ st->st_state = STATE_MODE_CFG_R1;
+ return modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
}
/*
- * parse a modecfg attribute payload
+ * Parse a ModeCfg attribute payload
*/
static stf_status
-modecfg_parse_attributes(pb_stream *attrs, u_int *set)
+modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
{
struct isakmp_attribute attr;
pb_stream strattr;
- while (pbs_left(attrs) > sizeof(struct isakmp_attribute))
+ while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
{
+ u_int16_t attr_type;
+ u_int16_t attr_len;
+
if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
{
- int len = (attr.isaat_af_type & 0x8000)? 4 : attr.isaat_lv;
-
- if (len < 4)
- {
- plog("Attribute was too short: %d", len);
- return STF_FAIL;
- }
-
- attrs->cur += len;
+ return STF_FAIL;
}
+ attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
+ attr_len = attr.isaat_lv;
- switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )
+ switch (attr_type)
{
case INTERNAL_IP4_ADDRESS:
+ if (attr_len == 4)
+ {
+ initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr);
+ }
+ /* fall through to set attribute flags */
case INTERNAL_IP4_NETMASK:
case INTERNAL_IP4_DNS:
case INTERNAL_IP4_SUBNET:
case INTERNAL_IP4_NBNS:
- *set |= LELEM(attr.isaat_af_type);
+ ia->attr_set |= LELEM(attr_type);
break;
default:
- plog("unsupported mode cfg attribute %s received."
- , enum_show(&modecfg_attr_names
- , attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ));
+ plog("unsupported ModeCfg attribute %s received."
+ , enum_show(&modecfg_attr_names, attr_type));
break;
}
}
return STF_OK;
}
-/* STATE_MODE_CFG_R0:
- * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
- *
- * This state occurs both in the responder and in the initiator.
- *
- * In the responding server, it occurs when the client *asks* for an IP
- * address or other information.
- *
- * Otherwise, it occurs in the initiator when the server sends a challenge
- * a set, or has a reply to our request.
+/*
+ * Parse a ModeCfg message
*/
-stf_status
-modecfg_inR0(struct msg_digest *md)
+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;
stf_status stat;
- plog("received ModeCfg request");
-
st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md, mode_cfg_hash(hash_val
- ,hash_pbs->roof
- , md->message_pbs.roof, st)
- , "MODECFG-HASH", "MODE R0");
- /* process the MODECFG payloads therein */
+ CHECK_QUICK_HASH(md, modecfg_hash(hash_val
+ , hash_pbs->roof
+ , md->message_pbs.roof, st)
+ , "MODECFG-HASH", "ISAKMP_CFG_MSG");
+
+ /* process the ModeCfg payloads received */
for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
{
- u_int set_modecfg_attrs = LEMPTY;
-
- switch (p->payload.attribute.isama_type)
- {
- default:
- plog("Expecting ISAKMP_CFG_REQUEST, got %s instead (ignored)."
- , enum_name(&attr_msg_type_names
- , p->payload.attribute.isama_type));
-
- stat = modecfg_parse_attributes(&p->pbs, &set_modecfg_attrs);
- if (stat != STF_OK)
- return stat;
- break;
+ internal_addr_t ia_candidate;
- case ISAKMP_CFG_REQUEST:
- stat = modecfg_parse_attributes(&p->pbs, &set_modecfg_attrs);
- if (stat != STF_OK)
- return stat;
+ init_internal_addr(&ia_candidate);
- stat = modecfg_resp(st, set_modecfg_attrs
- ,&md->rbody
- ,ISAKMP_CFG_REPLY
- ,TRUE
- ,p->payload.attribute.isama_identifier);
+ if (p->payload.attribute.isama_type == isama_type)
+ {
+ *isama_id = p->payload.attribute.isama_identifier;
- if (stat != STF_OK)
+ stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
+ if (stat == STF_OK)
{
- /* notification payload - not exactly the right choice, but okay */
- md->note = CERTIFICATE_UNAVAILABLE;
- return stat;
+ /* retrun with a valid set of attributes */
+ *ia = ia_candidate;
+ return STF_OK;
}
+ }
+ else
+ {
+ plog("expected %s, got %s instead (ignored)"
+ , enum_name(&attr_msg_type_names, isama_type)
+ , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
- /* they asked us, we responded, msgid is done */
- st->st_msgid = 0;
+ stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
}
+ if (stat != STF_OK)
+ return stat;
}
- return STF_OK;
+ return STF_IGNORE;
}
-/* STATE_MODE_CFG_R2:
- * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
+/* STATE_MODE_CFG_R0:
+ * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
*
- * used in server push mode, on the client (initiator).
+ * used in ModeCfg pull mode, on the server (responder)
*/
-static stf_status
-modecfg_inI2(struct msg_digest *md)
+stf_status
+modecfg_inR0(struct msg_digest *md)
{
struct state *const st = md->st;
- pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs;
- int resp = LEMPTY;
+ u_int16_t isama_id;
+ internal_addr_t ia;
stf_status stat;
- struct payload_digest *p;
- u_int16_t isama_id = 0;
-
- st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md
- , mode_cfg_hash(hash_val
- ,hash_pbs->roof
- , md->message_pbs.roof
- , st)
- , "MODECFG-HASH", "MODE R1");
-
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- struct isakmp_attribute attr;
- pb_stream strattr;
- isama_id = p->payload.attribute.isama_identifier;
-
- if (p->payload.attribute.isama_type != ISAKMP_CFG_SET)
- {
- plog("Expecting MODE_CFG_SET, got %x instead."
- ,md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type);
- return STF_IGNORE;
- }
-
- /* CHECK that SET has been received. */
-
- while (pbs_left(attrs) > sizeof(struct isakmp_attribute))
- {
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc
- , attrs, &strattr))
- {
- int len;
-
- /* Skip unknown */
- if (attr.isaat_af_type & 0x8000)
- len = 4;
- else
- len = attr.isaat_lv;
-
- if (len < 4)
- {
- plog("Attribute was too short: %d", len);
- return STF_FAIL;
- }
-
- attrs->cur += len;
- }
-
- switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )
- {
- case INTERNAL_IP4_ADDRESS:
- {
- struct connection *c = st->st_connection;
- ip_address a;
- u_int32_t *ap = (u_int32_t *)(strattr.cur);
- a.u.v4.sin_family = AF_INET;
-
- memcpy(&a.u.v4.sin_addr.s_addr, ap
- , sizeof(a.u.v4.sin_addr.s_addr));
-
- if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
- || isanyaddr(&c->spd.this.host_srcip))
- {
- char srcip[ADDRTOT_BUF];
-
- c->spd.this.host_srcip = a;
- addrtot(&a, 0, srcip, sizeof(srcip));
- plog("setting virtual IP source address to %s", srcip);
- }
-
- /* setting client subnet as srcip/32 */
- addrtosubnet(&a, &c->spd.this.client);
- c->spd.this.has_client = TRUE;
- }
- resp |= LELEM(attr.isaat_af_type);
- break;
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- resp |= LELEM(attr.isaat_af_type);
- break;
- default:
- plog("unsupported mode cfg attribute %s received."
- , enum_show(&modecfg_attr_names, (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )));
- break;
- }
- }
- }
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
+ if (stat != STF_OK)
+ return stat;
- /* ack things */
- stat = modecfg_resp(st, resp
- ,&md->rbody
- ,ISAKMP_CFG_ACK
- ,FALSE
- ,isama_id);
+ get_internal_addr(st->st_connection, &ia);
+ /* build ISAKMP_CFG_REPLY */
+ stat = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
if (stat != STF_OK)
{
/* notification payload - not exactly the right choice, but okay */
- md->note = CERTIFICATE_UNAVAILABLE;
+ md->note = ATTRIBUTES_NOT_SUPPORTED;
return stat;
}
- /*
- * we are done with this exchange, clear things so
- * that we can start phase 2 properly
- */
st->st_msgid = 0;
-
- if (resp)
- {
- st->st_modecfg.vars_set = TRUE;
- }
return STF_OK;
}
/* STATE_MODE_CFG_R1:
- * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
+ * HDR*, HASH, ATTR(ACK,OK)
+ *
+ * used in ModeCfg push mode, on the server (responder)
*/
stf_status
modecfg_inR1(struct msg_digest *md)
{
struct state *const st = md->st;
- pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs;
- int set_modecfg_attrs = LEMPTY;
+ u_int16_t isama_id;
+ internal_addr_t ia;
stf_status stat;
- struct payload_digest *p;
- plog("parsing ModeCfg reply");
-
- st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md, mode_cfg_hash(hash_val,hash_pbs->roof, md->message_pbs.roof, st)
- , "MODECFG-HASH", "MODE R1");
+ plog("parsing ModeCfg ack");
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ if (stat != STF_OK)
+ return stat;
- /* process the MODECFG payloads therein */
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- attrs = &p->pbs;
-
- switch (p->payload.attribute.isama_type)
- {
- default:
- {
- plog("Expecting MODE_CFG_ACK, got %x instead."
- ,md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type);
- return STF_IGNORE;
- }
- break;
-
- case ISAKMP_CFG_ACK:
- /* CHECK that ACK has been received. */
- stat = modecfg_parse_attributes(attrs, &set_modecfg_attrs);
- if (stat != STF_OK)
- return stat;
- break;
+ st->st_msgid = 0;
+ return STF_OK;
+}
- case ISAKMP_CFG_REPLY:
- while (pbs_left(attrs) > sizeof(struct isakmp_attribute))
- {
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc
- , attrs, &strattr))
- {
- /* Skip unknown */
- int len;
- if (attr.isaat_af_type & 0x8000)
- len = 4;
- else
- len = attr.isaat_lv;
-
- if (len < 4)
- {
- plog("Attribute was too short: %d", len);
- return STF_FAIL;
- }
+/* STATE_MODE_CFG_I1:
+ * HDR*, HASH, ATTR(REPLY=IP)
+ *
+ * used in ModeCfg pull mode, on the client (initiator)
+ */
+stf_status
+modecfg_inI1(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
- attrs->cur += len;
- }
+ plog("parsing ModeCfg reply");
- switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )
- {
- case INTERNAL_IP4_ADDRESS:
- {
- struct connection *c = st->st_connection;
- ip_address a;
- u_int32_t *ap = (u_int32_t *)(strattr.cur);
- a.u.v4.sin_family = AF_INET;
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ if (stat != STF_OK)
+ return stat;
- memcpy(&a.u.v4.sin_addr.s_addr, ap
- , sizeof(a.u.v4.sin_addr.s_addr));
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+ st->st_msgid = 0;
+ return STF_OK;
+}
- if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
- || isanyaddr(&c->spd.this.host_srcip))
- {
- char srcip[ADDRTOT_BUF];
+/* STATE_MODE_CFG_I2:
+ * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
+ *
+ * used in ModeCfg push mode, on the client (initiator).
+ */
+stf_status
+modecfg_inI2(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ lset_t attr_set;
+ stf_status stat;
- c->spd.this.host_srcip = a;
- addrtot(&a, 0, srcip, sizeof(srcip));
- plog("setting virtual IP source address to %s", srcip);
- }
+ plog("parsing ModeCfg set");
- /* setting client subnet as srcip/32 */
- addrtosubnet(&a, &c->spd.this.client);
- setportof(0, &c->spd.this.client.addr);
- c->spd.this.has_client = TRUE;
- }
- /* fall through to set attribute flage */
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
+ if (stat != STF_OK)
+ return stat;
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- set_modecfg_attrs |= LELEM(attr.isaat_af_type);
- break;
- default:
- plog("unsupported mode cfg attribute %s received."
- , enum_show(&modecfg_attr_names
- , (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )));
- break;
- }
- }
- break;
- }
- }
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
- /* we are done with this exchange, clear things so that we can start phase 2 properly */
- st->st_msgid = 0;
+ /* prepare ModeCfg ack which sends zero length attributes */
+ attr_set = ia.attr_set;
+ init_internal_addr(&ia);
+ ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
- if (set_modecfg_attrs)
+ stat = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat != STF_OK)
{
- st->st_modecfg.vars_set = TRUE;
+ /* notification payload - not exactly the right choice, but okay */
+ md->note = ATTRIBUTES_NOT_SUPPORTED;
+ return stat;
}
+
+ st->st_msgid = 0;
return STF_OK;
}
diff --git a/programs/pluto/modecfg.h b/programs/pluto/modecfg.h
index f6856d263..1f8259ca8 100644
--- a/programs/pluto/modecfg.h
+++ b/programs/pluto/modecfg.h
@@ -12,22 +12,17 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.h,v 1.1 2005/01/06 22:10:15 as Exp $
+ * RCSID $Id: modecfg.h,v 1.3 2006/10/19 21:07:40 as Exp $
*/
struct state;
-stf_status modecfg_resp(struct state *st
- , u_int resp
- , pb_stream *s, u_int16_t cmd
- , bool hackthat, u_int16_t id);
-
-stf_status modecfg_send_set(struct state *st);
-
-extern stf_status modecfg_start_set(struct state *st);
-
-/* Mode Config States */
+/* ModeConfig starting functions */
+extern stf_status modecfg_send_request(struct state *st);
+extern stf_status modecfg_send_set(struct state *st);
+/* ModeConfig state transition functions */
extern stf_status modecfg_inR0(struct msg_digest *md);
extern stf_status modecfg_inR1(struct msg_digest *md);
-extern stf_status modecfg_send_request(struct state *st);
+extern stf_status modecfg_inI1(struct msg_digest *md);
+extern stf_status modecfg_inI2(struct msg_digest *md);
diff --git a/programs/pluto/state.c b/programs/pluto/state.c
index 0781d2eb3..8181c34b4 100644
--- a/programs/pluto/state.c
+++ b/programs/pluto/state.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: state.c,v 1.13 2006/04/29 18:16:02 as Exp $
+ * RCSID $Id: state.c,v 1.15 2006/10/20 15:02:23 as Exp $
*/
#include <stdio.h>
@@ -716,7 +716,7 @@ state_eroute_usage(ip_subnet *ours, ip_subnet *his
});
}
-void fmt_state(struct state *st, time_t n
+void fmt_state(bool all, struct state *st, time_t n
, char *state_buf, size_t state_buf_len
, char *state_buf2, size_t state_buf2_len)
{
@@ -735,20 +735,22 @@ void fmt_state(struct state *st, time_t n
/* XXX spd-enum */
const char *eo = c->spd.eroute_owner == st->st_serialno
? "; eroute owner" : "";
-
+ const char *dpd = (all && st->st_dpd && c->dpd_action != DPD_ACTION_NONE)
+ ? "; DPD active" : "";
+
passert(st->st_event != 0);
fmt_conn_instance(c, inst);
snprintf(state_buf, state_buf_len
- , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s"
+ , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s%s"
, st->st_serialno
, c->name, inst
, enum_name(&state_names, st->st_state)
, state_story[st->st_state - STATE_MAIN_R0]
, enum_name(&timer_event_names, st->st_event->ev_type)
, delta
- , np1, np2, eo);
+ , np1, np2, eo, dpd);
/* print out SPIs if SAs are established */
if (state_buf2_len != 0)
@@ -846,7 +848,7 @@ state_compare(const void *a, const void *b)
}
void
-show_states_status(const char *name)
+show_states_status(bool all, const char *name)
{
time_t n = now();
int i;
@@ -892,7 +894,8 @@ show_states_status(const char *name)
st = array[i];
- fmt_state(st, n, state_buf, sizeof(state_buf)
+ fmt_state(all, st, n
+ , state_buf, sizeof(state_buf)
, state_buf2, sizeof(state_buf2));
whack_log(RC_COMMENT, state_buf);
if (state_buf2[0] != '\0')
diff --git a/programs/pluto/state.h b/programs/pluto/state.h
index 2f30d77f1..c7212fd1a 100644
--- a/programs/pluto/state.h
+++ b/programs/pluto/state.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: state.h,v 1.11 2006/03/08 22:12:37 as Exp $
+ * RCSID $Id: state.h,v 1.12 2006/10/17 10:30:54 as Exp $
*/
#include <sys/types.h>
@@ -259,11 +259,11 @@ extern struct state
*find_phase1_state(const struct connection *c, lset_t ok_states),
*find_sender(size_t packet_len, u_char *packet);
-extern void show_states_status(const char *name);
+extern void show_states_status(bool all, const char *name);
extern void for_each_state(void *(f)(struct state *, void *data), void *data);
extern void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi);
extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st);
-extern void fmt_state(struct state *st, time_t n
+extern void fmt_state(bool all, struct state *st, time_t n
, char *state_buf, size_t state_buf_len
, char *state_buf2, size_t state_buf_len2);
extern void delete_states_by_peer(ip_address *peer);
diff --git a/programs/pluto/vendor.c b/programs/pluto/vendor.c
index a51971cde..cbb26a5ef 100644
--- a/programs/pluto/vendor.c
+++ b/programs/pluto/vendor.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.c,v 1.39 2006/07/06 12:32:41 as Exp $
+ * RCSID $Id: vendor.c,v 1.41 2006/10/19 15:21:08 as Exp $
*/
#include <stdlib.h>
@@ -200,9 +200,13 @@ static struct vid_struct _vid_tab[] = {
*/
DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0")
DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1")
- DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.2")
+ DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2")
+ DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3")
+ DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4")
+ DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5")
- DEC_MD5_VID(STRONGSWAN, "strongSwan 2.7.3")
+ DEC_MD5_VID(STRONGSWAN, "strongSwan 2.8.0")
+ DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3")
DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2")
DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1")
DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0")
diff --git a/programs/pluto/vendor.h b/programs/pluto/vendor.h
index c4ed6d294..c7f70a480 100644
--- a/programs/pluto/vendor.h
+++ b/programs/pluto/vendor.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.h,v 1.34 2006/07/06 12:32:41 as Exp $
+ * RCSID $Id: vendor.h,v 1.36 2006/10/19 15:21:08 as Exp $
*/
#ifndef _VENDOR_H_
@@ -79,10 +79,14 @@ enum known_vendorid {
VID_STRONGSWAN_2_7_0 = 58,
VID_STRONGSWAN_2_7_1 = 59,
VID_STRONGSWAN_2_7_2 = 60,
+ VID_STRONGSWAN_2_7_3 = 61,
VID_STRONGSWAN_4_0_0 = 70,
VID_STRONGSWAN_4_0_1 = 71,
VID_STRONGSWAN_4_0_2 = 72,
+ VID_STRONGSWAN_4_0_3 = 73,
+ VID_STRONGSWAN_4_0_4 = 74,
+ VID_STRONGSWAN_4_0_5 = 75,
/* 101 - 200 : NAT-Traversal */
VID_NATT_STENBERG_01 =101,
diff --git a/programs/pluto/whack.h b/programs/pluto/whack.h
index 3086f1543..755918a2c 100644
--- a/programs/pluto/whack.h
+++ b/programs/pluto/whack.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: whack.h,v 1.16 2006/04/17 10:39:14 as Exp $
+ * RCSID $Id: whack.h,v 1.17 2006/10/19 15:18:43 as Exp $
*/
#ifndef _WHACK_H
@@ -62,6 +62,7 @@ struct whack_end {
bool has_client_wildcard;
bool has_port_wildcard;
bool has_srcip;
+ bool has_natip;
bool modecfg;
bool hostaccess;
certpolicy_t sendcert;
diff --git a/programs/starter/args.c b/programs/starter/args.c
index 6f3da63eb..2b2853a20 100644
--- a/programs/starter/args.c
+++ b/programs/starter/args.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: args.c,v 1.9 2006/04/17 10:32:36 as Exp $
+ * RCSID $Id: args.c,v 1.10 2006/10/19 14:58:30 as Exp $
*/
#include <stddef.h>
@@ -191,6 +191,7 @@ static const token_info_t token_info[] =
{ ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL },
{ ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL },
{ ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
+ { ARG_MISC, 0, NULL /* KW_MODECONFIG */ },
/* ca section keywords */
{ ARG_STR, offsetof(starter_ca_t, name), NULL },
@@ -209,6 +210,7 @@ static const token_info_t token_info[] =
{ ARG_MISC, 0, NULL /* KW_SUBNETWITHIN */ },
{ ARG_MISC, 0, NULL /* KW_PROTOPORT */ },
{ 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 },
{ ARG_STR, offsetof(starter_end_t, updown), NULL },
diff --git a/programs/starter/confread.c b/programs/starter/confread.c
index af0f00877..edd041ab4 100644
--- a/programs/starter/confread.c
+++ b/programs/starter/confread.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: confread.c,v 1.38 2006/06/20 21:52:53 as Exp $
+ * RCSID $Id: confread.c,v 1.39 2006/10/19 14:58:30 as Exp $
*/
#include <stddef.h>
@@ -255,6 +255,11 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
end->has_port_wildcard = has_port_wildcard;
break;
case KW_SOURCEIP:
+ if (end->has_natip)
+ {
+ plog("# natip and sourceip cannot be defined at the same time");
+ goto err;
+ }
if (streq(value, "%modeconfig") || streq(value, "%modecfg"))
{
end->modecfg = TRUE;
@@ -272,6 +277,22 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
}
conn->policy |= POLICY_TUNNEL;
break;
+ case KW_NATIP:
+ if (end->has_srcip)
+ {
+ plog("# natip and sourceip cannot be defined at the same time");
+ goto err;
+ }
+ conn->tunnel_addr_family = ip_version(value);
+ ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &end->srcip);
+ if (ugh != NULL)
+ {
+ plog("# bad addr: %s=%s [%s]", name, value, ugh);
+ goto err;
+ }
+ end->has_natip = TRUE;
+ conn->policy |= POLICY_TUNNEL;
+ break;
default:
break;
}
@@ -430,6 +451,9 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
case KW_REKEY:
KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY)
break;
+ case KW_MODECONFIG:
+ KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH)
+ break;
default:
break;
}
diff --git a/programs/starter/confread.h b/programs/starter/confread.h
index a3b1b7379..052f5d527 100644
--- a/programs/starter/confread.h
+++ b/programs/starter/confread.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: confread.h,v 1.23 2006/04/17 10:32:36 as Exp $
+ * RCSID $Id: confread.h,v 1.24 2006/10/19 15:01:05 as Exp $
*/
#ifndef _IPSEC_CONFREAD_H_
@@ -49,15 +49,16 @@ struct starter_end {
char *cert;
char *ca;
char *groups;
- char *iface;
+ char *iface;
ip_address addr;
ip_address nexthop;
ip_address srcip;
- ip_subnet subnet;
+ ip_subnet subnet;
bool has_client;
bool has_client_wildcard;
- bool has_port_wildcard;
+ bool has_port_wildcard;
bool has_srcip;
+ bool has_natip;
bool modecfg;
certpolicy_t sendcert;
bool firewall;
diff --git a/programs/starter/keywords.c b/programs/starter/keywords.c
index 4cc5c03e8..75be0a542 100644
--- a/programs/starter/keywords.c
+++ b/programs/starter/keywords.c
@@ -44,7 +44,7 @@ error "gperf generated tables don't work with this execution character set. Plea
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.c,v 1.7 2006/04/17 10:32:48 as Exp $
+ * RCSID $Id: keywords.c,v 1.8 2006/10/19 14:58:30 as Exp $
*/
#include <string.h>
@@ -56,12 +56,12 @@ struct kw_entry {
kw_token_t token;
};
-#define TOTAL_KEYWORDS 77
+#define TOTAL_KEYWORDS 80
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 17
#define MIN_HASH_VALUE 9
-#define MAX_HASH_VALUE 146
-/* maximum key range = 138, duplicates = 0 */
+#define MAX_HASH_VALUE 156
+/* maximum key range = 148, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -77,32 +77,32 @@ hash (str, len)
{
static const unsigned char asso_values[] =
{
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 15, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 85, 147, 40,
- 25, 25, 0, 10, 5, 80, 147, 35, 60, 35,
- 60, 55, 10, 147, 15, 20, 5, 65, 147, 147,
- 147, 35, 0, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 25, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 90, 157, 60,
+ 50, 25, 0, 10, 5, 65, 157, 65, 70, 5,
+ 0, 75, 35, 157, 10, 20, 5, 70, 157, 157,
+ 157, 55, 0, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157
};
return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[len - 1]];
}
@@ -111,104 +111,113 @@ static const struct kw_entry wordlist[] =
{
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{"left", KW_LEFT},
- {""}, {""}, {""},
+ {"leftupdown", KW_LEFTUPDOWN},
+ {""}, {""},
{"leftcert", KW_LEFTCERT,},
{"auth", KW_AUTH},
{"leftsubnet", KW_LEFTSUBNET},
- {""},
+ {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
{"leftsendcert", KW_LEFTSENDCERT},
{"leftprotoport", KW_LEFTPROTOPORT},
{""},
{"right", KW_RIGHT},
- {"leftnexthop", KW_LEFTNEXTHOP},
- {"leftsourceip", KW_LEFTSOURCEIP},
- {"esp", KW_ESP},
+ {"rightupdown", KW_RIGHTUPDOWN},
+ {"dumpdir", KW_DUMPDIR},
+ {""},
{"rightcert", KW_RIGHTCERT},
{""},
{"rightsubnet", KW_RIGHTSUBNET},
- {""},
+ {"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
{"rightsendcert", KW_RIGHTSENDCERT},
{"rightprotoport", KW_RIGHTPROTOPORT},
{"leftgroups", KW_LEFTGROUPS},
- {"leftid", KW_LEFTID},
- {"rightnexthop", KW_RIGHTNEXTHOP},
- {"rightsourceip", KW_RIGHTSOURCEIP},
+ {""}, {""},
+ {"compress", KW_COMPRESS},
{"lefthostaccess", KW_LEFTHOSTACCESS},
{"interfaces", KW_INTERFACES},
+ {""}, {""}, {""}, {""}, {""},
+ {"rightgroups", KW_RIGHTGROUPS},
+ {""},
+ {"pfs", KW_PFS},
+ {"leftnatip", KW_LEFTNATIP},
+ {"righthostaccess", KW_RIGHTHOSTACCESS},
+ {"leftnexthop", KW_LEFTNEXTHOP},
+ {"leftsourceip", KW_LEFTSOURCEIP},
{""}, {""},
+ {"virtual_private", KW_VIRTUAL_PRIVATE},
+ {""}, {""},
+ {"ike", KW_IKE},
+ {""},
+ {"rightnatip", KW_RIGHTNATIP},
+ {"leftid", KW_LEFTID},
+ {"rightnexthop", KW_RIGHTNEXTHOP},
+ {"rightsourceip", KW_RIGHTSOURCEIP},
+ {"dpdaction", KW_DPDACTION},
+ {"keep_alive", KW_KEEP_ALIVE},
+ {"ikelifetime", KW_IKELIFETIME},
+ {""},
{"pfsgroup", KW_PFSGROUP},
{"type", KW_TYPE},
{"dpdtimeout", KW_DPDTIMEOUT},
- {"rightgroups", KW_RIGHTGROUPS},
- {"rightid", KW_RIGHTID},
- {"pfs", KW_PFS},
- {"rekeyfuzz", KW_REKEYFUZZ},
- {"righthostaccess", KW_RIGHTHOSTACCESS},
{"authby", KW_AUTHBY},
- {""},
+ {"rightid", KW_RIGHTID},
{"leftrsasigkey", KW_LEFTRSASIGKEY},
- {""}, {""},
+ {""},
+ {"modeconfig", KW_MODECONFIG},
{"cacert", KW_CACERT},
- {"hidetos", KW_HIDETOS},
- {"ike", KW_IKE},
{""},
- {"virtual_private", KW_VIRTUAL_PRIVATE},
+ {"esp", KW_ESP},
+ {"rekeyfuzz", KW_REKEYFUZZ},
{""},
- {"dumpdir", KW_DUMPDIR},
+ {"rekeymargin", KW_REKEYMARGIN},
+ {"hidetos", KW_HIDETOS},
{"packetdefault", KW_PACKETDEFAULT},
{"rightrsasigkey", KW_RIGHTRSASIGKEY},
- {"keep_alive", KW_KEEP_ALIVE},
- {"ikelifetime", KW_IKELIFETIME},
+ {"strictcrlpolicy", KW_STRICTCRLPOLICY},
+ {""},
+ {"leftfirewall", KW_LEFTFIREWALL},
{""},
- {"compress", KW_COMPRESS},
{"auto", KW_AUTO},
- {"strictcrlpolicy", KW_STRICTCRLPOLICY},
+ {"klipsdebug", KW_KLIPSDEBUG},
{"keyingtries", KW_KEYINGTRIES},
{"keylife", KW_KEYLIFE},
- {"dpddelay", KW_DPDDELAY},
+ {"nat_traversal", KW_NAT_TRAVERSAL},
{"cachecrls", KW_CACHECRLS},
- {"leftupdown", KW_LEFTUPDOWN},
+ {"plutodebug", KW_PLUTODEBUG},
{"keyexchange", KW_KEYEXCHANGE},
- {"leftfirewall", KW_LEFTFIREWALL},
- {"nocrsend", KW_NOCRSEND},
+ {"ocspuri", KW_OCSPURI},
+ {"rightfirewall", KW_RIGHTFIREWALL},
+ {"uniqueids", KW_UNIQUEIDS},
{""},
- {"rekey", KW_REKEY},
- {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
+ {"leftca", KW_LEFTCA},
{"pkcs11module", KW_PKCS11MODULE},
- {"nat_traversal", KW_NAT_TRAVERSAL},
+ {""},
{"also", KW_ALSO},
{"pkcs11keepstate", KW_PKCS11KEEPSTATE},
- {"rightupdown", KW_RIGHTUPDOWN},
+ {""},
{"crluri2", KW_CRLURI2},
- {"rightfirewall", KW_RIGHTFIREWALL},
- {"postpluto", KW_POSTPLUTO},
- {"plutodebug", KW_PLUTODEBUG},
- {"pkcs11proxy", KW_PKCS11PROXY},
- {"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
- {"prepluto", KW_PREPLUTO},
- {""}, {""},
- {"leftca", KW_LEFTCA},
- {""}, {""},
- {"dpdaction", KW_DPDACTION},
- {""}, {""}, {""},
{"ldaphost", KW_LDAPHOST},
+ {"postpluto", KW_POSTPLUTO},
{""},
- {"klipsdebug", KW_KLIPSDEBUG},
{"overridemtu", KW_OVERRIDEMTU},
{"rightca", KW_RIGHTCA},
- {"fragicmp", KW_FRAGICMP},
- {""}, {""},
- {"rekeymargin", KW_REKEYMARGIN},
- {"ocspuri", KW_OCSPURI},
- {""},
- {"uniqueids", KW_UNIQUEIDS},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {"prepluto", KW_PREPLUTO},
+ {""}, {""}, {""}, {""},
+ {"dpddelay", KW_DPDDELAY},
+ {""}, {""}, {""}, {""},
+ {"nocrsend", KW_NOCRSEND},
+ {""}, {""}, {""}, {""},
{"ldapbase", KW_LDAPBASE},
+ {""},
+ {"rekey", KW_REKEY},
+ {"pkcs11proxy", KW_PKCS11PROXY},
+ {""}, {""}, {""}, {""}, {""}, {""},
+ {"fragicmp", KW_FRAGICMP},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {"crluri", KW_CRLURI},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"crlcheckinterval", KW_CRLCHECKINTERVAL},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"crluri", KW_CRLURI}
+ {""}, {""}, {""}, {""}, {""},
+ {"crlcheckinterval", KW_CRLCHECKINTERVAL}
};
#ifdef __GNUC__
diff --git a/programs/starter/keywords.h b/programs/starter/keywords.h
index 6542ae1be..be3aabf3b 100644
--- a/programs/starter/keywords.h
+++ b/programs/starter/keywords.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.h,v 1.8 2006/04/17 10:30:27 as Exp $
+ * RCSID $Id: keywords.h,v 1.9 2006/10/19 14:57:56 as Exp $
*/
#ifndef _KEYWORDS_H_
@@ -76,9 +76,10 @@ typedef enum {
KW_DPDDELAY,
KW_DPDTIMEOUT,
KW_DPDACTION,
+ KW_MODECONFIG,
#define KW_CONN_FIRST KW_CONN_SETUP
-#define KW_CONN_LAST KW_DPDACTION
+#define KW_CONN_LAST KW_MODECONFIG
/* ca section keywords */
KW_CA_NAME,
@@ -100,6 +101,7 @@ typedef enum {
KW_SUBNETWITHIN,
KW_PROTOPORT,
KW_SOURCEIP,
+ KW_NATIP,
KW_FIREWALL,
KW_HOSTACCESS,
KW_UPDOWN,
@@ -121,6 +123,7 @@ typedef enum {
KW_LEFTSUBNETWITHIN,
KW_LEFTPROTOPORT,
KW_LEFTSOURCEIP,
+ KW_LEFTNATIP,
KW_LEFTFIREWALL,
KW_LEFTHOSTACCESS,
KW_LEFTUPDOWN,
@@ -141,6 +144,7 @@ typedef enum {
KW_RIGHTSUBNETWITHIN,
KW_RIGHTPROTOPORT,
KW_RIGHTSOURCEIP,
+ KW_RIGHTNATIP,
KW_RIGHTFIREWALL,
KW_RIGHTHOSTACCESS,
KW_RIGHTUPDOWN,
diff --git a/programs/starter/keywords.txt b/programs/starter/keywords.txt
index dcfdafc98..fc9e49e47 100644
--- a/programs/starter/keywords.txt
+++ b/programs/starter/keywords.txt
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.txt,v 1.6 2006/04/17 10:30:27 as Exp $
+ * RCSID $Id: keywords.txt,v 1.7 2006/10/19 14:57:56 as Exp $
*/
#include <string.h>
@@ -65,6 +65,7 @@ pfsgroup, KW_PFSGROUP
dpddelay, KW_DPDDELAY
dpdtimeout, KW_DPDTIMEOUT
dpdaction, KW_DPDACTION
+modeconfig, KW_MODECONFIG
cacert, KW_CACERT
ldaphost, KW_LDAPHOST
ldapbase, KW_LDAPBASE
@@ -77,6 +78,7 @@ leftsubnet, KW_LEFTSUBNET
leftsubnetwithin, KW_LEFTSUBNETWITHIN
leftprotoport, KW_LEFTPROTOPORT
leftsourceip, KW_LEFTSOURCEIP
+leftnatip, KW_LEFTNATIP
leftfirewall, KW_LEFTFIREWALL
lefthostaccess, KW_LEFTHOSTACCESS
leftupdown, KW_LEFTUPDOWN
@@ -92,6 +94,7 @@ rightsubnet, KW_RIGHTSUBNET
rightsubnetwithin, KW_RIGHTSUBNETWITHIN
rightprotoport, KW_RIGHTPROTOPORT
rightsourceip, KW_RIGHTSOURCEIP
+rightnatip, KW_RIGHTNATIP
rightfirewall, KW_RIGHTFIREWALL
righthostaccess, KW_RIGHTHOSTACCESS
rightupdown, KW_RIGHTUPDOWN
diff --git a/programs/starter/starterwhack.c b/programs/starter/starterwhack.c
index 0d7a3715e..b4bf2fb9d 100644
--- a/programs/starter/starterwhack.c
+++ b/programs/starter/starterwhack.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starterwhack.c,v 1.18 2006/06/20 21:52:53 as Exp $
+ * RCSID $Id: starterwhack.c,v 1.19 2006/10/19 15:02:46 as Exp $
*/
#include <sys/types.h>
@@ -171,6 +171,7 @@ set_whack_end(whack_end_t *w, starter_end_t *end)
w->has_client_wildcard = end->has_client_wildcard;
w->has_port_wildcard = end->has_port_wildcard;
w->has_srcip = end->has_srcip;
+ w->has_natip = end->has_natip;
w->modecfg = end->modecfg;
w->hostaccess = end->hostaccess;
w->sendcert = end->sendcert;