diff options
Diffstat (limited to 'programs/pluto')
-rw-r--r-- | programs/pluto/connections.c | 9 | ||||
-rw-r--r-- | programs/pluto/connections.h | 3 | ||||
-rw-r--r-- | programs/pluto/constants.c | 7 | ||||
-rw-r--r-- | programs/pluto/constants.h | 28 | ||||
-rw-r--r-- | programs/pluto/demux.c | 47 | ||||
-rw-r--r-- | programs/pluto/log.c | 4 | ||||
-rw-r--r-- | programs/pluto/modecfg.c | 779 | ||||
-rw-r--r-- | programs/pluto/modecfg.h | 19 | ||||
-rw-r--r-- | programs/pluto/state.c | 17 | ||||
-rw-r--r-- | programs/pluto/state.h | 6 | ||||
-rw-r--r-- | programs/pluto/vendor.c | 10 | ||||
-rw-r--r-- | programs/pluto/vendor.h | 6 | ||||
-rw-r--r-- | programs/pluto/whack.h | 3 |
13 files changed, 399 insertions, 539 deletions
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; |