diff -urNp openswan-2.6.37/programs/pluto/connections.c openswan-2.6.37-patched/programs/pluto/connections.c --- openswan-2.6.37/programs/pluto/connections.c 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/connections.c 2011-10-28 19:57:49.413033232 -0400 @@ -222,7 +222,7 @@ delete_end(struct connection *c UNUSED, pfreeany(e->host_addr_name); } -static void +void delete_sr(struct connection *c, struct spd_route *sr) { delete_end(c, sr, &sr->this); diff -urNp openswan-2.6.37/programs/pluto/connections.h openswan-2.6.37-patched/programs/pluto/connections.h --- openswan-2.6.37/programs/pluto/connections.h 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/connections.h 2011-10-28 19:57:49.414033232 -0400 @@ -304,6 +304,7 @@ extern void release_connection(struct co extern void delete_connection(struct connection *c, bool relations); extern void delete_connections_by_name(const char *name, bool strict); extern void delete_every_connection(void); +extern void delete_sr(struct connection *c, struct spd_route *sr); extern char *add_group_instance(struct connection *group, const ip_subnet *target); extern void remove_group_instance(const struct connection *group, const char *name); extern void release_dead_interfaces(void); diff -urNp openswan-2.6.37/programs/pluto/ikev1_aggr.c openswan-2.6.37-patched/programs/pluto/ikev1_aggr.c --- openswan-2.6.37/programs/pluto/ikev1_aggr.c 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/ikev1_aggr.c 2011-10-28 19:57:49.416033232 -0400 @@ -1183,7 +1183,7 @@ aggr_outI1_tail(struct pluto_crypto_req_ } #endif - if (!nat_traversal_insert_vid(np, &md->rbody)) { + if (!nat_traversal_insert_vid(np, &md->rbody, st)) { reset_cur_state(); return STF_INTERNAL_ERROR; } diff -urNp openswan-2.6.37/programs/pluto/ikev1_main.c openswan-2.6.37-patched/programs/pluto/ikev1_main.c --- openswan-2.6.37/programs/pluto/ikev1_main.c 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/ikev1_main.c 2011-10-28 19:57:49.418033230 -0400 @@ -216,7 +216,7 @@ main_outI1(int whack_sock int np = --numvidtosend > 0 ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE; /* Add supported NAT-Traversal VID */ - if (!nat_traversal_insert_vid(np, &md.rbody)) { + if (!nat_traversal_insert_vid(np, &md.rbody, st)) { reset_cur_state(); return STF_INTERNAL_ERROR; } diff -urNp openswan-2.6.37/programs/pluto/kernel.c openswan-2.6.37-patched/programs/pluto/kernel.c --- openswan-2.6.37/programs/pluto/kernel.c 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/kernel.c 2011-10-28 19:57:49.419033230 -0400 @@ -436,6 +436,7 @@ fmt_common_shell_out(char *buf, int blen #endif "%s " /* PLUTO_MY_SRCIP - if any */ #ifdef XAUTH + "PLUTO_IS_PEER_CISCO='%u' " "PLUTO_CISCO_DNS_INFO='%s' " "PLUTO_CISCO_DOMAIN_INFO='%s' " "PLUTO_PEER_BANNER='%s' " @@ -472,6 +473,7 @@ fmt_common_shell_out(char *buf, int blen #endif , srcip_str #ifdef XAUTH + , c->remotepeertype , c->cisco_dns_info ? c->cisco_dns_info : "" , c->cisco_domain_info ? c->cisco_domain_info : "" , c->cisco_banner ? c->cisco_banner : "" diff -urNp openswan-2.6.37/programs/pluto/nat_traversal.c openswan-2.6.37-patched/programs/pluto/nat_traversal.c --- openswan-2.6.37/programs/pluto/nat_traversal.c 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/nat_traversal.c 2011-10-28 19:57:49.420033230 -0400 @@ -199,7 +199,7 @@ static void _natd_hash(const struct hash * * Used when we're Initiator */ -bool nat_traversal_insert_vid(u_int8_t np, pb_stream *outs) +bool nat_traversal_insert_vid(u_int8_t np, pb_stream *outs, struct state *st) { bool r = TRUE; DBG(DBG_NATT @@ -208,6 +208,9 @@ bool nat_traversal_insert_vid(u_int8_t n , nat_traversal_support_non_ike)); if (nat_traversal_support_port_floating) { + if (st->st_connection->remotepeertype == CISCO) { + if (r) r = out_vid(np, outs, VID_NATT_RFC); + } else { if (r) r = out_vid(ISAKMP_NEXT_VID, outs, VID_NATT_RFC); if (r) r = out_vid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_05); if (r) r = out_vid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_03); @@ -215,8 +218,9 @@ bool nat_traversal_insert_vid(u_int8_t n if (r) r = out_vid(nat_traversal_support_non_ike ? ISAKMP_NEXT_VID : np, outs, VID_NATT_IETF_02); + } } - if (nat_traversal_support_non_ike) { + if (nat_traversal_support_non_ike && st->st_connection->remotepeertype != CISCO) { if (r) r = out_vid(np, outs, VID_NATT_IETF_00); } return r; diff -urNp openswan-2.6.37/programs/pluto/nat_traversal.h openswan-2.6.37-patched/programs/pluto/nat_traversal.h --- openswan-2.6.37/programs/pluto/nat_traversal.h 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/nat_traversal.h 2011-10-28 19:57:49.420033230 -0400 @@ -129,7 +129,7 @@ extern int nat_traversal_espinudp_socket */ #ifndef PB_STREAM_UNDEFINED bool nat_traversal_add_vid(u_int8_t np, pb_stream *outs); -bool nat_traversal_insert_vid(u_int8_t np, pb_stream *outs); +bool nat_traversal_insert_vid(u_int8_t np, pb_stream *outs, struct state *st); #endif u_int32_t nat_traversal_vid_to_method(unsigned short nat_t_vid); diff -urNp openswan-2.6.37/programs/pluto/spdb_v1_struct.c openswan-2.6.37-patched/programs/pluto/spdb_v1_struct.c --- openswan-2.6.37/programs/pluto/spdb_v1_struct.c 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/spdb_v1_struct.c 2011-10-28 19:57:49.421033230 -0400 @@ -1527,7 +1527,7 @@ parse_ipsec_transform(struct isakmp_tran case SA_LIFE_TYPE_SECONDS: /* silently limit duration to our maximum */ attrs->life_seconds = val <= SA_LIFE_DURATION_MAXIMUM - ? val : SA_LIFE_DURATION_MAXIMUM; + ? (val < st->st_connection->sa_ipsec_life_seconds ? val : st->st_connection->sa_ipsec_life_seconds) : SA_LIFE_DURATION_MAXIMUM; break; case SA_LIFE_TYPE_KBYTES: attrs->life_kilobytes = val; @@ -1593,7 +1593,13 @@ parse_ipsec_transform(struct isakmp_tran loglog(RC_LOG_SERIOUS, "%s must only be used with old IETF drafts", enum_name(&enc_mode_names, val)); + if(st->st_connection->remotepeertype == CISCO) { + DBG_log( "Allowing, as this may be due to rekey"); + attrs->encapsulation = val - ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS + ENCAPSULATION_MODE_TUNNEL; + } + else { return FALSE; + } } else if (st->hidden_variables.st_nat_traversal & NAT_T_DETECTED) { attrs->encapsulation = val - ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS + ENCAPSULATION_MODE_TUNNEL; diff -urNp openswan-2.6.37/programs/pluto/xauth.c openswan-2.6.37-patched/programs/pluto/xauth.c --- openswan-2.6.37/programs/pluto/xauth.c 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/pluto/xauth.c 2011-10-28 19:57:49.424033229 -0400 @@ -1782,7 +1782,9 @@ modecfg_inR1(struct msg_digest *md) , caddr); if(addrbytesptr(&c->spd.this.host_srcip, NULL) == 0 - || isanyaddr(&c->spd.this.host_srcip)) { + || isanyaddr(&c->spd.this.host_srcip) + || c->remotepeertype == CISCO ) { + /*with remotepeertype == CISCO, overwrite the previous address with the new received address*/ openswan_log("setting ip source address to %s" , caddr); c->spd.this.host_srcip = a; @@ -1832,7 +1834,11 @@ modecfg_inR1(struct msg_digest *md) { /* concatenate new IP address string on end of * existing string, separated by ' '. + * concatenate only if the received DNS is not + * already present in the current string. */ + + if( !strstr(c->cisco_dns_info, caddr) ) { size_t sz_old = strlen(old); size_t sz_added = strlen(caddr) + 1; char *new = alloc_bytes(sz_old + 1 + sz_added, "cisco_dns_info+"); @@ -1842,6 +1848,7 @@ modecfg_inR1(struct msg_digest *md) memcpy(new + sz_old + 1, caddr, sz_added); c->cisco_dns_info = new; pfree(old); + } } } @@ -1857,18 +1864,22 @@ modecfg_inR1(struct msg_digest *md) break; case CISCO_BANNER: + /*if received again, free the previous and create the new one*/ + pfreeany(st->st_connection->cisco_banner); st->st_connection->cisco_banner = cisco_stringify(&strattr,"Cisco Banner"); resp |= LELEM(attr.isaat_af_type); break; case CISCO_DEF_DOMAIN: + /*if received again, free the previous one and create the new one*/ + pfreeany(st->st_connection->cisco_domain_info); st->st_connection->cisco_domain_info = cisco_stringify(&strattr,"Cisco Domain"); resp |= LELEM(attr.isaat_af_type); break; case CISCO_SPLIT_INC: { - struct spd_route *tmp_spd; + struct spd_route *tmp_spd, *tmp_spd1; ip_address a; char caddr[SUBNETTOT_BUF]; size_t len = pbs_left(&strattr); @@ -1881,6 +1892,18 @@ modecfg_inR1(struct msg_digest *md) tmp_spd2->that.has_client_wildcard = FALSE; } + /* receiving remote subnets information again + * free the previous ones before proceeding. + */ + tmp_spd = tmp_spd2->next; + tmp_spd2->next = NULL; + while(tmp_spd ) { + delete_sr(c, tmp_spd); + tmp_spd1 = tmp_spd->next; + pfree(tmp_spd); + tmp_spd = tmp_spd1; + } + while (len > 0) { u_int32_t *ap; tmp_spd = clone_thing(c->spd, "remote subnets policies"); @@ -1932,13 +1955,13 @@ modecfg_inR1(struct msg_digest *md) tmp_spd->that.cert.type = 0; tmp_spd->this.ca.ptr = NULL; - tmp_spd->this.ca.ptr = NULL; + tmp_spd->that.ca.ptr = NULL; tmp_spd->this.groups = NULL; - tmp_spd->this.groups = NULL; + tmp_spd->that.groups = NULL; tmp_spd->this.virt = NULL; - tmp_spd->this.virt = NULL; + tmp_spd->that.virt = NULL; tmp_spd->next = NULL; tmp_spd2->next = tmp_spd; diff -urNp openswan-2.6.37/programs/_updown.netkey/_updown.netkey.in openswan-2.6.37-patched/programs/_updown.netkey/_updown.netkey.in --- openswan-2.6.37/programs/_updown.netkey/_updown.netkey.in 2011-10-28 17:11:53.000000000 -0400 +++ openswan-2.6.37-patched/programs/_updown.netkey/_updown.netkey.in 2011-10-28 19:57:49.426033229 -0400 @@ -188,6 +188,14 @@ downroute() { ip route flush cache } +downrule() { + if [ -n "$PLUTO_MY_SOURCEIP" ] + then + doroute del + ip route flush cache + fi +} + updateresolvconf() { if [ -z "$PLUTO_NM_CONFIGURED" -o "$PLUTO_NM_CONFIGURED" = 0 ]; then @@ -320,6 +328,32 @@ addsource() { return $st } +delsource() { + st=0 + # check if given sourceip is local and add as alias if not + if ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local; then + it="ip addr del ${PLUTO_MY_SOURCEIP%/*}/32 dev ${PLUTO_INTERFACE%:*}" + + oops="`eval $it 2>&1`" + st=$? + if [ " $oops" = " " -a " $st" != " 0" ]; then + oops="silent error, exit status $st" + fi + case "$oops" in + 'RTNETLINK answers: File exists'*) + # should not happen, but ... ignore if the + # address was already assigned on interface + oops="" + st=0 + ;; + esac + if [ " $oops" != " " -o " $st" != " 0" ]; then + echo "$0: delsource \`$it' failed ($oops)" >&2 + fi + fi + return $st +} + doroute() { if [ -z "$PLUTO_MY_SOURCEIP" ] && [ -n "$DEFAULTSOURCE" ] @@ -359,6 +393,12 @@ doroute() { parms2="$parms2 src ${PLUTO_MY_SOURCEIP%/*}" fi + if [ -z "$PLUTO_IS_PEER_CISCO" -o "$PLUTO_IS_PEER_CISCO" = 1 ]; then + if [ "$1" = "del" -a -n "$PLUTO_MY_SOURCEIP" ]; then + delsource + fi + fi + case "$PLUTO_PEER_CLIENT" in "0.0.0.0/0") # opportunistic encryption work around @@ -402,6 +442,7 @@ case "$PLUTO_VERB" in ;; down-host) # connection to me going down + downrule # If you are doing a custom version, firewall commands go here. ;; up-client) @@ -410,6 +451,7 @@ case "$PLUTO_VERB" in ;; down-client) # connection to my client subnet going down + downrule # If you are doing a custom version, firewall commands go here. ;; updateresolvconf-host|updateresolvconf-client)