From: Apple Date: Thu, 27 Aug 2009 17:56:23 +0000 (+0000) Subject: ipsec-92.tar.gz X-Git-Tag: mac-os-x-106^0 X-Git-Url: https://git.saurik.com/apple/ipsec.git/commitdiff_plain/d1e348cfd503b08e7d34b7683d23aae209af0a71 ipsec-92.tar.gz --- diff --git a/entitlements.plist b/entitlements.plist new file mode 100644 index 0000000..93abc34 --- /dev/null +++ b/entitlements.plist @@ -0,0 +1,10 @@ + + + + + keychain-access-groups + + apple + + + diff --git a/ipsec-tools/Common/config.h b/ipsec-tools/Common/config.h index be2c9ed..05028df 100644 --- a/ipsec-tools/Common/config.h +++ b/ipsec-tools/Common/config.h @@ -1,4 +1,6 @@ +#include +#define __IPSEC_BUILD__ 1 /* If printf doesn't support %zu. */ #undef BROKEN_PRINTF @@ -61,7 +63,7 @@ #undef ENABLE_SAMODE_UNSPECIFIED /* Enable statictics */ -//#define ENABLE_STATS 1 +/* #define ENABLE_STATS 1*/ /* causes too many logs to syslog */ /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 @@ -76,7 +78,8 @@ #define HAVE_GETTIMEOFDAY 1 /* Enable GSS API */ -#define HAVE_GSSAPI 1 +/* %%%%%%% change this back when conflict fixed */ +#undef HAVE_GSSAPI /* Have iconv using const */ #define HAVE_ICONV_2ND_CONST 1 @@ -88,7 +91,8 @@ #undef HAVE_IPSEC_POLICY_T /* Hybrid authentication uses PAM */ -#define HAVE_LIBPAM 1 +//#define HAVE_LIBPAM 1 +#undef HAVE_LIBPAM /* Hybrid authentication uses RADIUS */ #undef HAVE_LIBRADIUS @@ -99,7 +103,34 @@ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 -/* Use */ +/* Define to 1 if keychain is used */ +#if TARGET_OS_EMBEDDED +#undef HAVE_KEYCHAIN +#else +#define HAVE_KEYCHAIN 1 +#endif + +/* Define to 1 if keychain is used */ +#if TARGET_OS_EMBEDDED +#undef HAVE_SECURITY_FRAMEWORK +#else +#define HAVE_SECURITY_FRAMEWORK 1 +#endif + + +/* Define to 1 if Open Dir available */ +#if TARGET_OS_EMBEDDED +#undef HAVE_OPENDIR +#else +#define HAVE_OPENDIR 1 +#endif + +#if TARGET_OS_EMBEDDED +#undef HAVE_LIBLDAP +#else +#define HAVE_LIBLDAP 1 +#endif + #define HAVE_NETINET6_IPSEC 1 #define HAVE_GETIFADDRS 1 @@ -117,7 +148,11 @@ #define HAVE_OPENSSL_RC5_H 1 /* Define to 1 if you have the `pam_start' function. */ +#if TARGET_OS_EMBEDDED +#undef HAVE_PAM_START +#else #define HAVE_PAM_START 1 +#endif /* Are PF_KEY policy priorities supported? */ #undef HAVE_PFKEY_POLICY_PRIORITY @@ -254,3 +289,7 @@ /* Define to `unsigned' if does not define. */ #undef size_t + +#ifdef __APPLE__ +#define USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS 1 +#endif diff --git a/ipsec-tools/Common/ipsecMessageTracer.h b/ipsec-tools/Common/ipsecMessageTracer.h new file mode 100644 index 0000000..14bafba --- /dev/null +++ b/ipsec-tools/Common/ipsecMessageTracer.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IPSECMESSAGETRACER_H +#define _IPSECMESSAGETRACER_H + +#define CONSTSTR(str) (const char *)str + +#define L2TPIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.disconnect.l2tpipsec") +#define CISCOIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.disconnect.ciscoipsec") +#define BTMMIPSEC_CONNECTION_ESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.disconnect.btmm") +#define PLAINIPSEC_CONNECTION_ESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.disconnect.plain") +#define L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.connect.l2tpipsec") +#define CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.connect.ciscoipsec") +#define BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.connect.btmm") +#define PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN CONSTSTR("com.apple.Networking.ipsec.connect.plain") +#define L2TPIPSECVPN_PHASE_DOMAIN CONSTSTR("com.apple.Networking.ipsec.phasestats.l2tpipsec") +#define CISCOIPSECVPN_PHASE_DOMAIN CONSTSTR("com.apple.Networking.ipsec.phasestats.ciscoipsec") +#define BTMMIPSEC_PHASE_DOMAIN CONSTSTR("com.apple.Networking.ipsec.phasestats.btmm") +#define PLAINIPSEC_PHASE_DOMAIN CONSTSTR("com.apple.Networking.ipsec.phasestats.plain") +#define PLAINIPSECDOMAIN CONSTSTR("com.apple.Networking.ipsec.main") + +#define IPSECCONFIGTRACEREVENT(config, eventCode, message, failure_reason) ipsecConfigTracerEvent(config, eventCode, message, failure_reason) + +#define IPSECPOLICYTRACEREVENT(policy, eventCode, message, failure_reason) ipsecPolicyTracerEvent(policy, eventCode, message, failure_reason) + +#define IPSECSESSIONTRACERSTART(session) ipsecSessionTracerStart(session) +#define IPSECSESSIONTRACEREVENT(session, eventCode, message, failure_reason) ipsecSessionTracerEvent(session, eventCode, message, failure_reason) +#define IPSECSESSIONTRACERSTOP(session, is_failure, reason) ipsecSessionTracerStop(session, is_failure, reason) +#define IPSECSESSIONTRACERESTABLISHED(session) ipsecSessionTracerLogEstablished(session) + +static inline double get_percentage (double numerator, double denominator) +{ + if (numerator >= denominator || denominator == 0) { + return((double)100); + } + return((numerator/denominator)*100); +} + +#endif /* _IPSECMESSAGETRACER_H */ diff --git a/ipsec-tools/Common/key_debug.c b/ipsec-tools/Common/key_debug.c index 06a9d4b..dca4d89 100644 --- a/ipsec-tools/Common/key_debug.c +++ b/ipsec-tools/Common/key_debug.c @@ -77,6 +77,8 @@ static void kdebug_sadb_sa __P((struct sadb_ext *)); static void kdebug_sadb_address __P((struct sadb_ext *)); static void kdebug_sadb_key __P((struct sadb_ext *)); static void kdebug_sadb_x_sa2 __P((struct sadb_ext *)); +static void kdebug_sadb_session_id __P((struct sadb_ext *)); +static void kdebug_sadb_sastat __P((struct sadb_ext *)); static void kdebug_sadb_x_policy __P((struct sadb_ext *ext)); static void kdebug_sockaddr __P((struct sockaddr *addr)); @@ -171,6 +173,12 @@ kdebug_sadb(base) case SADB_X_EXT_SA2: kdebug_sadb_x_sa2(ext); break; + case SADB_EXT_SESSION_ID: + kdebug_sadb_session_id(ext); + break; + case SADB_EXT_SASTAT: + kdebug_sadb_sastat(ext); + break; #ifdef SADB_X_EXT_NAT_T_TYPE case SADB_X_EXT_NAT_T_TYPE: kdebug_sadb_x_nat_t_type(ext); @@ -423,6 +431,47 @@ kdebug_sadb_x_sa2(ext) return; } +static void +kdebug_sadb_session_id(ext) +struct sadb_ext *ext; +{ + struct sadb_session_id *p = (__typeof__(p))ext; + + /* sanity check */ + if (ext == NULL) { + printf("kdebug_sadb_session_id: NULL pointer was passed.\n"); + return; + } + + printf("sadb_session_id{ id0=%llx, id1=%llx}\n", + p->sadb_session_id_v[0], + p->sadb_session_id_v[1]); +} + +static void +kdebug_sadb_sastat(ext) +struct sadb_ext *ext; +{ + struct sadb_sastat *p = (__typeof__(p))ext; + struct sastat *stats; + int i; + + /* sanity check */ + if (ext == NULL) { + printf("kdebug_sadb_sastat: NULL pointer was passed.\n"); + return; + } + + printf("sadb_sastat{ dir=%u num=%u\n", + p->sadb_sastat_dir, p->sadb_sastat_list_len); + stats = (__typeof__(stats))(p + 1); + for (i = 0; i < p->sadb_sastat_list_len; i++) { + printf(" spi=%x,\n", + stats[i].spi); + } + printf("}\n"); +} + void kdebug_sadb_x_policy(ext) struct sadb_ext *ext; diff --git a/ipsec-tools/Common/libpfkey.h b/ipsec-tools/Common/libpfkey.h index 628c835..ef41d0b 100644 --- a/ipsec-tools/Common/libpfkey.h +++ b/ipsec-tools/Common/libpfkey.h @@ -154,6 +154,7 @@ struct sadb_msg *pfkey_recv __P((int)); int pfkey_send __P((int, struct sadb_msg *, int)); int pfkey_align __P((struct sadb_msg *, caddr_t *)); int pfkey_check __P((caddr_t *)); +int pfkey_send_getsastats __P((int, u_int32_t, u_int64_t [], u_int32_t, u_int8_t, struct sastat [], u_int32_t)); #ifndef __SYSDEP_SA_LEN__ #define __SYSDEP_SA_LEN__ diff --git a/ipsec-tools/Common/pfkey.c b/ipsec-tools/Common/pfkey.c index 0e566a4..f4bcb4f 100644 --- a/ipsec-tools/Common/pfkey.c +++ b/ipsec-tools/Common/pfkey.c @@ -2250,6 +2250,8 @@ pfkey_align(msg, mhp) case SADB_EXT_SPIRANGE: case SADB_X_EXT_POLICY: case SADB_X_EXT_SA2: + case SADB_EXT_SESSION_ID: + case SADB_EXT_SASTAT: #ifdef SADB_X_EXT_NAT_T_TYPE case SADB_X_EXT_NAT_T_TYPE: case SADB_X_EXT_NAT_T_SPORT: @@ -2737,3 +2739,118 @@ pfkey_set_natt_frag(buf, lim, type, l_natt_frag) return(buf + len); } #endif + +static caddr_t +pfkey_setsadbsession_id (caddr_t buf, + caddr_t lim, + u_int64_t session_ids[], + u_int32_t max_session_ids) +{ + struct sadb_session_id *p; + u_int len; + + if (!max_session_ids) + return NULL; + + p = (void *)buf; + len = sizeof(*p); + + if (buf + len > lim) + return NULL; + + bzero(p, len); + p->sadb_session_id_len = PFKEY_UNIT64(len); + p->sadb_session_id_exttype = SADB_EXT_SESSION_ID; + p->sadb_session_id_v[0] = session_ids[0]; + if (max_session_ids > 1) + p->sadb_session_id_v[1] = session_ids[1]; + + return(buf + len); +} + +static caddr_t +pfkey_setsadbsastats (caddr_t buf, + caddr_t lim, + u_int32_t dir, + struct sastat *stats, + u_int32_t max_stats) +{ + struct sadb_sastat *p; + u_int len, list_len; + + if (!stats || !max_stats) + return NULL; + + p = (__typeof__(p))buf; + list_len = sizeof(*stats) * max_stats; + len = sizeof(*p) + PFKEY_ALIGN8(list_len); + + if (buf + len > lim) + return NULL; + + bzero(p, len); + p->sadb_sastat_len = PFKEY_UNIT64(len); + p->sadb_sastat_exttype = SADB_EXT_SASTAT; + p->sadb_sastat_dir = dir; + p->sadb_sastat_list_len = max_stats; + bcopy(stats, p + 1, list_len); + + return(buf + len); +} + +int +pfkey_send_getsastats (int so, + u_int32_t seq, + u_int64_t *session_ids, + u_int32_t max_session_ids, + u_int8_t dir, + struct sastat *stats, + u_int32_t max_stats) +{ + struct sadb_msg *newmsg; + caddr_t ep; + int list_len, out_len, len; + caddr_t p; + + if (!session_ids || !stats || !max_stats) { + return -1; + } + + list_len = sizeof(*stats) * max_stats; + /* create new sadb_msg to send. */ + out_len = sizeof(struct sadb_msg) + sizeof(struct sadb_session_id) + sizeof(struct sadb_sastat) + PFKEY_ALIGN8(list_len); + + if ((newmsg = CALLOC((size_t)out_len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + ep = ((caddr_t)(void *)newmsg) + out_len; + + p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_GETSASTAT, (u_int)out_len, SADB_SATYPE_UNSPEC, seq, getpid()); + if (!p) { + free(newmsg); + return -1; + } + + p = pfkey_setsadbsession_id(p, ep, session_ids, max_session_ids); + if (!p) { + free(newmsg); + return -1; + } + + p = pfkey_setsadbsastats(p, ep, dir, stats, max_stats); + if (!p) { + free(newmsg); + return -1; + } + + /* send message */ + len = pfkey_send(so, newmsg, out_len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} diff --git a/ipsec-tools/libipsec/policy_parse.y b/ipsec-tools/libipsec/policy_parse.y index 51fb115..74d1e35 100644 --- a/ipsec-tools/libipsec/policy_parse.y +++ b/ipsec-tools/libipsec/policy_parse.y @@ -400,26 +400,30 @@ parse_sockaddr(addrbuf, portbuf) char *serv = NULL; int error; struct sockaddr *newaddr = NULL; + int addr_len; + int serv_len; - if ((addr = malloc(addrbuf->len + 1)) == NULL) { + addr_len = addrbuf->len + 1; + if ((addr = malloc(addr_len)) == NULL) { yyerror("malloc failed"); __ipsec_set_strerror(strerror(errno)); return NULL; } - - if (portbuf && ((serv = malloc(portbuf->len + 1)) == NULL)) { - free(addr); - yyerror("malloc failed"); - __ipsec_set_strerror(strerror(errno)); - return NULL; + + if (portbuf) { + serv_len = portbuf->len + 1; + if ((serv = malloc(serv_len)) == NULL) { + free(addr); + yyerror("malloc failed"); + __ipsec_set_strerror(strerror(errno)); + return NULL; + } } - strncpy(addr, addrbuf->buf, addrbuf->len); - addr[addrbuf->len] = '\0'; + strlcpy(addr, addrbuf->buf, addr_len); if (portbuf) { - strncpy(serv, portbuf->buf, portbuf->len); - serv[portbuf->len] = '\0'; + strlcpy(serv, portbuf->buf, serv_len); } memset(&hints, 0, sizeof(hints)); diff --git a/ipsec-tools/racoon/Sample/Embedded/racoon.conf b/ipsec-tools/racoon/Sample/Embedded/racoon.conf new file mode 100644 index 0000000..6625e1e --- /dev/null +++ b/ipsec-tools/racoon/Sample/Embedded/racoon.conf @@ -0,0 +1,139 @@ +# $KAME: racoon.conf.in,v 1.17 2001/08/14 12:10:22 sakane Exp $ + +# "path" must be placed before it is used. +# You can overwrite what you defined, but it should not be used due to confusion. +path include "/etc/racoon" ; + +# search this file for pre_shared_key with various ID key. +path pre_shared_key "/etc/racoon/psk.txt" ; + +# racoon will look for certificate file in the directory, +# if the certificate/certificate request payload is received. +path certificate "/etc/cert" ; + +# "log" specifies logging level. It is followed by either "notify", "debug" +# or "debug2". +#log debug; + +# "padding" defines some parameter of padding. You should not touch these. +padding +{ + maximum_length 20; # maximum padding length. + randomize off; # enable randomize length. + strict_check off; # enable strict check. + exclusive_tail off; # extract last one octet. +} + +# if no listen directive is specified, racoon will listen to all +# available interface addresses. +listen +{ + #isakmp ::1 [7000]; + #isakmp 202.249.11.124 [500]; + #admin [7002]; # administrative's port by kmpstat. + #strict_address; # required all addresses must be bound. +} + +# Specification of default various timer. +timer +{ + # These value can be changed per remote node. + counter 10; # maximum trying count to send. + interval 3 sec; # interval to resend (retransmit) + persend 1; # the number of packets per a send. + + # timer for waiting to complete each phase. + phase1 30 sec; + phase2 30 sec; + + # Auto exit delay timer - for use when controlled by VPN socket + auto_exit_delay 3 sec; +} + +# +# anonymous entry is defined in /etc/racoon/remote/anonymous.conf +# +#remote anonymous +#{ +# #exchange_mode main,aggressive; +# exchange_mode aggressive,main; +# doi ipsec_doi; +# situation identity_only; +# +# #my_identifier address; +# my_identifier user_fqdn "macuser@localhost"; +# peers_identifier user_fqdn "macuser@localhost"; +# #certificate_type x509 "mycert" "mypriv"; +# +# nonce_size 16; +# lifetime time 1 min; # sec,min,hour +# initial_contact on; +# support_mip6 on; +# proposal_check obey; # obey, strict or claim +# +# proposal { +# encryption_algorithm 3des; +# hash_algorithm sha1; +# authentication_method pre_shared_key ; +# dh_group 2 ; +# } +#} + +#remote ::1 [8000] +#{ +# #exchange_mode main,aggressive; +# exchange_mode aggressive,main; +# doi ipsec_doi; +# situation identity_only; +# +# my_identifier user_fqdn "macuser@localhost"; +# peers_identifier user_fqdn "macuser@localhost"; +# #certificate_type x509 "mycert" "mypriv"; +# +# nonce_size 16; +# lifetime time 1 min; # sec,min,hour +# +# proposal { +# encryption_algorithm 3des; +# hash_algorithm sha1; +# authentication_method pre_shared_key ; +# dh_group 2 ; +# } +#} + +# +# anonymous entry is defined in /etc/racoon/remote/anonymous.conf +# +#sainfo anonymous +#{ +# pfs_group 1; +# lifetime time 30 sec; +# encryption_algorithm aes, 3des ; +# authentication_algorithm hmac_sha1; +# compression_algorithm deflate ; +#} + +# sainfo address 203.178.141.209 any address 203.178.141.218 any +# { +# pfs_group 1; +# lifetime time 30 sec; +# encryption_algorithm des ; +# authentication_algorithm hmac_md5; +# compression_algorithm deflate ; +# } + +#sainfo address ::1 icmp6 address ::1 icmp6 +#{ +# pfs_group 1; +# lifetime time 60 sec; +# encryption_algorithm 3des, cast128, blowfish 448, des ; +# authentication_algorithm hmac_sha1, hmac_md5 ; +# compression_algorithm deflate ; +#} + +# Allow third parties the ability to specify remote and sainfo entries +# by including all files matching /var/run/racoon/*.conf +# This line should be added at the end of the racoon.conf file +# so that settings such as timer values will be appropriately applied. +include "/var/run/racoon/*.conf" ; + diff --git a/ipsec-tools/racoon/Sample/racoon.conf b/ipsec-tools/racoon/Sample/racoon.conf index 2a6112b..8b01645 100644 --- a/ipsec-tools/racoon/Sample/racoon.conf +++ b/ipsec-tools/racoon/Sample/racoon.conf @@ -1,13 +1,9 @@ # $KAME: racoon.conf.in,v 1.17 2001/08/14 12:10:22 sakane Exp $ -# "path" must be placed before it should be used. -# You can overwrite which you defined, but it should not use due to confusing. +# "path" must be placed before it is used. +# You can overwrite what you defined, but it should not be used due to confusion. path include "/etc/racoon" ; -# Allow third parties the ability to specify remote and sainfo entries -# by including all files matching /etc/racoon/remote/*.conf -include "/etc/racoon/remote/*.conf" ; - # search this file for pre_shared_key with various ID key. path pre_shared_key "/etc/racoon/psk.txt" ; @@ -135,3 +131,8 @@ sainfo address ::1 icmp6 address ::1 icmp6 compression_algorithm deflate ; } +# Allow third parties the ability to specify remote and sainfo entries +# by including all files matching /var/run/racoon/*.conf +# This line should be added at the end of the racoon.conf file +# so that settings such as timer values will be appropriately applied. +include "/var/run/racoon/*.conf" ; diff --git a/ipsec-tools/racoon/admin.c b/ipsec-tools/racoon/admin.c index 344e2f4..ea11b4e 100644 --- a/ipsec-tools/racoon/admin.c +++ b/ipsec-tools/racoon/admin.c @@ -1,4 +1,6 @@ -/* $Id: admin.c,v 1.17.2.4 2005/07/12 11:49:44 manubsd Exp $ */ +/* $NetBSD: admin.c,v 1.17.6.1 2007/08/01 11:52:19 vanhu Exp $ */ + +/* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -60,6 +62,9 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -82,9 +87,13 @@ #include "admin.h" #include "admin_var.h" #include "isakmp_inf.h" +#ifdef ENABLE_HYBRID +#include "isakmp_cfg.h" +#endif #include "session.h" #include "gcmalloc.h" + #ifdef ENABLE_ADMINPORT char *adminsock_path = ADMINSOCK_PATH; uid_t adminsock_owner = 0; @@ -103,7 +112,6 @@ admin_handler() socklen_t fromlen = sizeof(from); struct admin_com com; char *combuf = NULL; - pid_t pid = -1; int len, error = -1; so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen); @@ -150,7 +158,7 @@ admin_handler() if (com.ac_cmd == ADMIN_RELOAD_CONF) { /* reload does not work at all! */ - signal_handler(SIGHUP); + signal_handler(SIGUSR1); goto end; } @@ -161,10 +169,6 @@ admin_handler() if (combuf) racoon_free(combuf); - /* exit if child's process. */ - if (pid == 0 && !f_foreground) - exit(error); - return error; } @@ -181,7 +185,7 @@ admin_process(so2, combuf) vchar_t *id = NULL; vchar_t *key = NULL; int idtype = 0; - int error = 0; + int error = -1; com->ac_errno = 0; @@ -189,21 +193,28 @@ admin_process(so2, combuf) case ADMIN_RELOAD_CONF: /* don't entered because of proccessing it in other place. */ plog(LLV_ERROR, LOCATION, NULL, "should never reach here\n"); - goto bad; + goto out; case ADMIN_SHOW_SCHED: { - caddr_t p; + caddr_t p = NULL; int len; + + com->ac_errno = -1; + if (sched_dump(&p, &len) == -1) - com->ac_errno = -1; - buf = vmalloc(len); - if (buf == NULL) - com->ac_errno = -1; - else - memcpy(buf->v, p, len); - } + goto out2; + + if ((buf = vmalloc(len)) == NULL) + goto out2; + + memcpy(buf->v, p, len); + + com->ac_errno = 0; +out2: + racoon_free(p); break; + } case ADMIN_SHOW_EVT: /* It's not really an error, don't force racoonctl to quit */ @@ -223,7 +234,7 @@ admin_process(so2, combuf) com->ac_errno = -1; break; case ADMIN_FLUSH_SA: - flushph1(); + flushph1(false); break; } break; @@ -236,7 +247,7 @@ admin_process(so2, combuf) u_int p; p = admin2pfkey_proto(com->ac_proto); if (p == -1) - goto bad; + goto out; buf = pfkey_dump_sadb(p); if (buf == NULL) com->ac_errno = -1; @@ -256,7 +267,7 @@ admin_process(so2, combuf) com->ac_errno = error; break; case ADMIN_FLUSH_SA: - /*XXX flushph2();*/ + /*XXX flushph2(false);*/ com->ac_errno = 0; break; } @@ -282,16 +293,10 @@ admin_process(so2, combuf) &((struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)))->dst; - if ((loc = strdup(saddrwop2str(src))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } - if ((rem = strdup(saddrwop2str(dst))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } + loc = racoon_strdup(saddrwop2str(src)); + rem = racoon_strdup(saddrwop2str(dst)); + STRDUP_FATAL(loc); + STRDUP_FATAL(rem); if ((iph1 = getph1byaddrwop(src, dst)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -308,6 +313,27 @@ admin_process(so2, combuf) break; } +#ifdef ENABLE_HYBRID + case ADMIN_LOGOUT_USER: { + struct ph1handle *iph1; + char *user; + int found = 0; + + if (com->ac_len > sizeof(com) + LOGINLEN + 1) { + plog(LLV_ERROR, LOCATION, NULL, + "malformed message (login too long)\n"); + break; + } + + user = (char *)(com + 1); + found = purgeph1bylogin(user); + plog(LLV_INFO, LOCATION, NULL, + "deleted %d SA for user \"%s\"\n", found, user); + + break; + } +#endif + case ADMIN_DELETE_ALL_SA_DST: { struct ph1handle *iph1; struct sockaddr *dst; @@ -317,21 +343,15 @@ admin_process(so2, combuf) &((struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)))->dst; - if ((rem = strdup(saddrwop2str(dst))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } + rem = racoon_strdup(saddrwop2str(dst)); + STRDUP_FATAL(rem); plog(LLV_INFO, LOCATION, NULL, "Flushing all SAs for peer %s\n", rem); while ((iph1 = getph1bydstaddrwop(dst)) != NULL) { - if ((loc = strdup(saddrwop2str(iph1->local))) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot allocate memory\n"); - break; - } + loc = racoon_strdup(saddrwop2str(iph1->local)); + STRDUP_FATAL(loc); if (iph1->status == PHASE1ST_ESTABLISHED) isakmp_info_send_d1(iph1); @@ -345,6 +365,75 @@ admin_process(so2, combuf) break; } + //%%%%%% test code + case ADMIN_ESTABLISH_SA_VPNCONTROL: + { + struct admin_com_psk *acp; + char *data; + struct sockaddr *dst; + struct bound_addr *target; + + com->ac_errno = -1; + + acp = (struct admin_com_psk *) + ((char *)com + sizeof(*com) + + sizeof(struct admin_com_indexes)); + + target = (struct bound_addr *)racoon_malloc(sizeof(struct bound_addr)); + if (target == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory: %s\n", + strerror(errno)); + break; + } + + if ((id = vmalloc(acp->id_len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory: %s\n", + strerror(errno)); + goto outofhere; + } + data = (char *)(acp + 1); + memcpy(id->v, data, id->l); + + if ((key = vmalloc(acp->key_len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot allocate memory: %s\n", + strerror(errno)); + vfree(id); + id = NULL; + goto outofhere; + } + data = (char *)(data + acp->id_len); + memcpy(key->v, data, key->l); + + dst = (struct sockaddr *) + &((struct admin_com_indexes *) + ((caddr_t)com + sizeof(*com)))->dst; + + // assume IPv4 + target->address = ((struct sockaddr_in *)dst)->sin_addr.s_addr; + +#ifdef ENABLE_HYBRID + /* Set the id and key */ + if (id && key) { + + target->user_id = id; + target->user_pw = key; + } +#endif + vpn_connect(target); + com->ac_errno = 0; +outofhere: + if (target->user_id != NULL) + vfree(target->user_id); + if (target->user_pw != NULL) + vfree(target->user_pw); + if (target != NULL) + racoon_free(target); + break; + } + case ADMIN_ESTABLISH_SA_PSK: { struct admin_com_psk *acp; char *data; @@ -371,6 +460,7 @@ admin_process(so2, combuf) "cannot allocate memory: %s\n", strerror(errno)); vfree(id); + id = NULL; break; } data = (char *)(data + acp->id_len); @@ -389,11 +479,13 @@ admin_process(so2, combuf) ((caddr_t)com + sizeof(*com)))->dst; switch (com->ac_proto) { - case ADMIN_PROTO_ISAKMP: - { + case ADMIN_PROTO_ISAKMP: { struct remoteconf *rmconf; - struct sockaddr *remote; - struct sockaddr *local; + struct sockaddr *remote = NULL; + struct sockaddr *local = NULL; + u_int16_t port; + + com->ac_errno = -1; /* search appropreate configuration */ rmconf = getrmconf(dst); @@ -401,16 +493,13 @@ admin_process(so2, combuf) plog(LLV_ERROR, LOCATION, NULL, "no configuration found " "for %s\n", saddrwop2str(dst)); - com->ac_errno = -1; - break; + goto out1; } /* get remote IP address and port number. */ - remote = dupsaddr(dst); - if (remote == NULL) { - com->ac_errno = -1; - break; - } + if ((remote = dupsaddr(dst)) == NULL) + goto out1; + switch (remote->sa_family) { case AF_INET: ((struct sockaddr_in *)remote)->sin_port = @@ -430,58 +519,54 @@ admin_process(so2, combuf) break; } +// port = extract_port(rmconf->remote); +// if (set_port(remote, port) == NULL) +// goto out1; + /* get local address */ - local = dupsaddr(src); - if (local == NULL) { - com->ac_errno = -1; - break; - } - switch (local->sa_family) { - case AF_INET: - ((struct sockaddr_in *)local)->sin_port = - getmyaddrsport(local); - break; -#ifdef INET6 - case AF_INET6: - ((struct sockaddr_in6 *)local)->sin6_port = - getmyaddrsport(local); - break; -#endif - default: - plog(LLV_ERROR, LOCATION, NULL, - "invalid family: %d\n", - local->sa_family); - com->ac_errno = -1; - break; - } + if ((local = dupsaddr(src)) == NULL) + goto out1; + port = ntohs(getmyaddrsport(local)); + if (set_port(local, port) == NULL) + goto out1; + +#ifdef ENABLE_HYBRID /* Set the id and key */ if (id && key) { - if (rmconf->idv != NULL) { - vfree(rmconf->idv); - rmconf->idv = NULL; + if (xauth_rmconf_used(&rmconf->xauth) == -1) + goto out1; + + if (rmconf->xauth->login != NULL) { + vfree(rmconf->xauth->login); + rmconf->xauth->login = NULL; } - if (rmconf->key != NULL) { - vfree(rmconf->key); - rmconf->key = NULL; + if (rmconf->xauth->pass != NULL) { + vfree(rmconf->xauth->pass); + rmconf->xauth->pass = NULL; } - rmconf->idvtype = idtype; - rmconf->idv = id; - rmconf->key = key; + rmconf->xauth->login = id; + rmconf->xauth->pass = key; } +#endif plog(LLV_INFO, LOCATION, NULL, "accept a request to establish IKE-SA: " "%s\n", saddrwop2str(remote)); /* begin ident mode */ - if (isakmp_ph1begin_i(rmconf, remote, local) < 0) { - com->ac_errno = -1; - break; - } - } + if (isakmp_ph1begin_i(rmconf, remote, local, 0) < 0) + goto out1; + + com->ac_errno = 0; +out1: + if (local != NULL) + racoon_free(local); + if (remote != NULL) + racoon_free(remote); break; + } case ADMIN_PROTO_AH: case ADMIN_PROTO_ESP: break; @@ -498,18 +583,15 @@ admin_process(so2, combuf) com->ac_errno = -1; } - if (admin_reply(so2, com, buf) < 0) - goto bad; + if ((error = admin_reply(so2, com, buf)) != 0) + goto out; + error = 0; +out: if (buf != NULL) vfree(buf); - return 0; - - bad: - if (buf != NULL) - vfree(buf); - return -1; + return error; } static int diff --git a/ipsec-tools/racoon/admin.h b/ipsec-tools/racoon/admin.h index e07616d..d6ec706 100644 --- a/ipsec-tools/racoon/admin.h +++ b/ipsec-tools/racoon/admin.h @@ -1,4 +1,6 @@ -/* $Id: admin.h,v 1.10 2004/12/30 13:45:49 manubsd Exp $ */ +/* $NetBSD: admin.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: admin.h,v 1.11 2005/06/19 22:37:47 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -75,6 +77,14 @@ struct admin_com { */ #define ADMIN_ESTABLISH_SA_PSK 0x0203 +/* + * user login follows + */ +#define ADMIN_LOGOUT_USER 0x0205 /* Delete SA for a given Xauth user */ + +//%%%% for test +#define ADMIN_ESTABLISH_SA_VPNCONTROL 0x0206 + /* * Range 0x08xx is reserved for privilege separation, see privsep.h */ diff --git a/ipsec-tools/racoon/algorithm.c b/ipsec-tools/racoon/algorithm.c index 1af0150..1fdd9e7 100644 --- a/ipsec-tools/racoon/algorithm.c +++ b/ipsec-tools/racoon/algorithm.c @@ -213,22 +213,46 @@ static struct misc_algorithm ipsec_compdef[] = { { "lzs", algtype_lzs, IPSECDOI_IPCOMP_LZS, }, }; +/* + * In case of asymetric modes (hybrid xauth), what's racoon mode of + * operations ; it seems that the proposal should always use the + * initiator half (unless a server initiates a connection, which is + * not handled, and probably not useful). + */ static struct misc_algorithm oakley_authdef[] = { -{ "pre_shared_key", algtype_psk, OAKLEY_ATTR_AUTH_METHOD_PSKEY, }, -{ "dsssig", algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, }, -{ "rsasig", algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, }, -{ "rsaenc", algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, }, -{ "rsarev", algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, }, -{ "gssapi_krb", algtype_gssapikrb, OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, }, +{ "pre_shared_key", algtype_psk, OAKLEY_ATTR_AUTH_METHOD_PSKEY, }, +{ "dsssig", algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, }, +{ "rsasig", algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, }, +{ "rsaenc", algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, }, +{ "rsarev", algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, }, + +{ "gssapi_krb", algtype_gssapikrb, + OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, }, + #ifdef ENABLE_HYBRID -{ "hybrid_rsa_server", algtype_hybrid_rsa_s, - OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, }, -{ "hybrid_dss_server", algtype_hybrid_dss_s, - OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, }, -{ "hybrid_rsa_client", algtype_hybrid_rsa_c, - OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, }, -{ "hybrid_dss_client", algtype_hybrid_dss_c, - OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, }, +{ "hybrid_rsa_server", algtype_hybrid_rsa_s, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, }, + +{ "hybrid_dss_server", algtype_hybrid_dss_s, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, }, + +{ "xauth_psk_server", algtype_xauth_psk_s, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R, }, + +{ "xauth_rsa_server", algtype_xauth_rsa_s, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R, }, + +{ "hybrid_rsa_client", algtype_hybrid_rsa_c, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, }, + +{ "hybrid_dss_client", algtype_hybrid_dss_c, + OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, }, + +{ "xauth_psk_client", algtype_xauth_psk_c, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I, }, + +{ "xauth_rsa_client", algtype_xauth_rsa_c, + OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I, }, #endif }; @@ -394,7 +418,7 @@ alg_oakley_hmacdef_one(doi, key, buf) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s size=%d): %8.6f", __func__, + syslog(LOG_NOTICE, "%s(%s size=%zu): %8.6f", __func__, f->name, buf->l, timedelta(&start, &end)); #endif @@ -506,7 +530,7 @@ alg_oakley_encdef_decrypt(doi, buf, key, iv) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__, + syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__, f->name, key->l << 3, buf->l, timedelta(&start, &end)); #endif return res; @@ -535,7 +559,7 @@ alg_oakley_encdef_encrypt(doi, buf, key, iv) #ifdef ENABLE_STATS gettimeofday(&end, NULL); - syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__, + syslog(LOG_NOTICE, "%s(%s klen=%zu size=%zu): %8.6f", __func__, f->name, key->l << 3, buf->l, timedelta(&start, &end)); #endif return res; @@ -594,7 +618,7 @@ alg_ipsec_hmacdef(doi) for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++) if (doi == ipsec_hmacdef[i].doi) { plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n", - oakley_hmacdef[i].name); + ipsec_hmacdef[i].name); return &ipsec_hmacdef[i]; } return NULL; diff --git a/ipsec-tools/racoon/algorithm.h b/ipsec-tools/racoon/algorithm.h index e4fc1fe..3d1d51b 100644 --- a/ipsec-tools/racoon/algorithm.h +++ b/ipsec-tools/racoon/algorithm.h @@ -33,91 +33,8 @@ #define _ALGORITHM_H #include +#include "Algorithm_types.h" -/* algorithm class */ -enum { - algclass_ipsec_enc, - algclass_ipsec_auth, - algclass_ipsec_comp, - algclass_isakmp_enc, - algclass_isakmp_hash, - algclass_isakmp_dh, - algclass_isakmp_ameth, /* authentication method. */ -#define MAXALGCLASS 7 -}; - -#define ALG_DEFAULT_KEYLEN 64 - -#define ALGTYPE_NOTHING 0 - -/* algorithm type */ -enum algtype { - algtype_nothing = 0, - - /* enc */ - algtype_des_iv64, - algtype_des, - algtype_3des, - algtype_rc5, - algtype_idea, - algtype_cast128, - algtype_blowfish, - algtype_3idea, - algtype_des_iv32, - algtype_rc4, - algtype_null_enc, - algtype_aes, - algtype_twofish, - - /* ipsec auth */ - algtype_hmac_md5, - algtype_hmac_sha1, - algtype_des_mac, - algtype_kpdk, - algtype_non_auth, - algtype_hmac_sha2_256, - algtype_hmac_sha2_384, - algtype_hmac_sha2_512, - - /* ipcomp */ - algtype_oui, - algtype_deflate, - algtype_lzs, - - /* hash */ - algtype_md5, - algtype_sha1, - algtype_tiger, - algtype_sha2_256, - algtype_sha2_384, - algtype_sha2_512, - - /* dh_group */ - algtype_modp768, - algtype_modp1024, - algtype_ec2n155, - algtype_ec2n185, - algtype_modp1536, - algtype_modp2048, - algtype_modp3072, - algtype_modp4096, - algtype_modp6144, - algtype_modp8192, - - /* authentication method. */ - algtype_psk, - algtype_dsssig, - algtype_rsasig, - algtype_rsaenc, - algtype_rsarev, - algtype_gssapikrb, -#ifdef ENABLE_HYBRID - algtype_hybrid_rsa_s, - algtype_hybrid_dss_s, - algtype_hybrid_rsa_c, - algtype_hybrid_dss_c, -#endif -}; struct hmac_algorithm { char *name; diff --git a/ipsec-tools/racoon/algorithm_types.h b/ipsec-tools/racoon/algorithm_types.h new file mode 100644 index 0000000..aca2f18 --- /dev/null +++ b/ipsec-tools/racoon/algorithm_types.h @@ -0,0 +1,125 @@ +/* $Id: algorithm.h,v 1.8 2004/11/18 15:14:44 ludvigm Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ALGORITHM_TYPES_H +#define _ALGORITHM_TYPES_H + + +/* algorithm class */ +enum { + algclass_ipsec_enc, + algclass_ipsec_auth, + algclass_ipsec_comp, + algclass_isakmp_enc, + algclass_isakmp_hash, + algclass_isakmp_dh, + algclass_isakmp_ameth, /* authentication method. */ +#define MAXALGCLASS 7 +}; + +#define ALG_DEFAULT_KEYLEN 64 + +#define ALGTYPE_NOTHING 0 + +/* algorithm type */ +enum algtype { + algtype_nothing = 0, + + /* enc */ + algtype_des_iv64, + algtype_des, + algtype_3des, + algtype_rc5, + algtype_idea, + algtype_cast128, + algtype_blowfish, + algtype_3idea, + algtype_des_iv32, + algtype_rc4, + algtype_null_enc, + algtype_aes, + algtype_twofish, + + /* ipsec auth */ + algtype_hmac_md5, + algtype_hmac_sha1, + algtype_des_mac, + algtype_kpdk, + algtype_non_auth, + algtype_hmac_sha2_256, + algtype_hmac_sha2_384, + algtype_hmac_sha2_512, + + /* ipcomp */ + algtype_oui, + algtype_deflate, + algtype_lzs, + + /* hash */ + algtype_md5, + algtype_sha1, + algtype_tiger, + algtype_sha2_256, + algtype_sha2_384, + algtype_sha2_512, + + /* dh_group */ + algtype_modp768, + algtype_modp1024, + algtype_ec2n155, + algtype_ec2n185, + algtype_modp1536, + algtype_modp2048, + algtype_modp3072, + algtype_modp4096, + algtype_modp6144, + algtype_modp8192, + + /* authentication method. */ + algtype_psk, + algtype_dsssig, + algtype_rsasig, + algtype_rsaenc, + algtype_rsarev, + algtype_gssapikrb, +#ifdef ENABLE_HYBRID + algtype_hybrid_rsa_s, + algtype_hybrid_dss_s, + algtype_hybrid_rsa_c, + algtype_hybrid_dss_c, + algtype_xauth_psk_s, + algtype_xauth_psk_c, + algtype_xauth_rsa_s, + algtype_xauth_rsa_c, +#endif +}; + +#endif \ No newline at end of file diff --git a/ipsec-tools/racoon/cfparse.y b/ipsec-tools/racoon/cfparse.y index e19032a..ce041c4 100644 --- a/ipsec-tools/racoon/cfparse.y +++ b/ipsec-tools/racoon/cfparse.y @@ -1,4 +1,6 @@ -/* $Id: cfparse.y,v 1.37.2.7 2006/02/02 14:37:17 vanhu Exp $ */ +/* $NetBSD: cfparse.y,v 1.18.4.3 2007/08/01 11:52:19 vanhu Exp $ */ + +/* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */ %{ /* @@ -55,6 +57,7 @@ #include #include #include +#include #include "var.h" #include "misc.h" @@ -80,7 +83,11 @@ #include "isakmp_var.h" #include "handler.h" #include "isakmp.h" +#include "nattraversal.h" +#include "isakmp_frag.h" #ifdef ENABLE_HYBRID +#include "resolv.h" +#include "isakmp_unity.h" #include "isakmp_xauth.h" #include "isakmp_cfg.h" #endif @@ -92,6 +99,8 @@ #endif #include "vendorid.h" #include "rsalist.h" +#include "ipsecConfigTracer.h" +#include "ipsecMessageTracer.h" static int num2dhgroup[] = { @@ -120,6 +129,7 @@ static struct remoteconf *cur_rmconf; static int tmpalgtype[MAXALGCLASS]; static struct sainfo *cur_sainfo; static int cur_algclass; +static int oldloglevel = LLV_BASE; static struct proposalspec *newprspec __P((void)); static void insprspec __P((struct proposalspec *, struct proposalspec **)); @@ -164,9 +174,10 @@ static int fix_lifebyte __P((u_long)); /* listen */ %token LISTEN X_ISAKMP X_ISAKMP_NATT X_ADMIN STRICT_ADDRESS ADMINSOCK DISABLED /* modecfg */ -%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 -%token CFG_AUTH_SOURCE CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LOCAL CFG_NONE -%token CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE +%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN +%token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE +%token CFG_GROUP_SOURCE CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE +%token CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL CFG_SPLIT_INCLUDE CFG_SPLIT_DNS %token CFG_PFS_GROUP CFG_SAVE_PASSWD /* timer */ %token RETRY RETRY_COUNTER RETRY_INTERVAL RETRY_PERSEND @@ -180,48 +191,54 @@ static int fix_lifebyte __P((u_long)); %token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE %token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE %token VERIFY_CERT SEND_CERT SEND_CR -%token IDENTIFIERTYPE MY_IDENTIFIER PEERS_IDENTIFIER VERIFY_IDENTIFIER +%token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER +%token PEERS_IDENTIFIER VERIFY_IDENTIFIER %token SHARED_SECRET SECRETTYPE %token OPEN_DIR_AUTH_GROUP IN_KEYCHAIN %token CERTIFICATE_VERIFICATION VERIFICATION_MODULE VERIFICATION_OPTION %token DNSSEC CERT_X509 CERT_PLAINRSA %token NONCE_SIZE DH_GROUP KEEPALIVE PASSIVE INITIAL_CONTACT -%token NAT_TRAVERSAL NAT_TRAVERSAL_LEVEL NAT_TRAVERSAL_MULTI_USER +%token NAT_TRAVERSAL REMOTE_FORCE_LEVEL NAT_TRAVERSAL_LEVEL NAT_TRAVERSAL_MULTI_USER NAT_TRAVERSAL_KEEPALIVE %token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL -%token GENERATE_POLICY SUPPORT_PROXY +%token GENERATE_POLICY GENERATE_LEVEL SUPPORT_PROXY %token PROPOSAL %token EXEC_PATH EXEC_COMMAND EXEC_SUCCESS EXEC_FAILURE %token GSS_ID GSS_ID_ENC GSS_ID_ENCTYPE %token COMPLEX_BUNDLE -%token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL -%token XAUTH_LOGIN +%token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL DPD_ALGORITHM +%token DISCONNECT_ON_IDLE IDLE_TIMEOUT IDLE_DIRECTION +%token XAUTH_LOGIN WEAK_PHASE1_CHECK %token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG -%token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH +%token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID %token SCRIPT PHASE1_UP PHASE1_DOWN %token NUMBER SWITCH BOOLEAN -%token HEXSTRING QUOTEDSTRING ADDRSTRING +%token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE %token UNITTYPE_BYTE UNITTYPE_KBYTES UNITTYPE_MBYTES UNITTYPE_TBYTES %token UNITTYPE_SEC UNITTYPE_MIN UNITTYPE_HOUR %token EOS BOC EOC COMMA +%token DPD_ALGO_TYPE_DEFAULT DPD_ALGO_TYPE_INBOUND DPD_ALGO_TYPE_BLACKHOLE +%token IDLE_DIRECTION_IN IDLE_DIRECTION_OUT IDLE_DIRECTION_ANY %type NUMBER BOOLEAN SWITCH keylength -%type PATHTYPE IDENTIFIERTYPE LOGLEV GSS_ID_ENCTYPE +%type PATHTYPE IDENTIFIERTYPE IDENTIFIERQUAL LOGLEV GSS_ID_ENCTYPE %type SECRETTYPE %type ALGORITHM_CLASS dh_group_num %type ALGORITHMTYPE STRENGTHTYPE %type PREFIX prefix PORT port ike_port %type ul_proto UL_PROTO %type EXCHANGETYPE DOITYPE SITUATIONTYPE -%type CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL NAT_TRAVERSAL_LEVEL +%type CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL NAT_TRAVERSAL_LEVEL GENERATE_LEVEL %type VERIFICATION_MODULE VERIFICATION_OPTION %type unittype_time unittype_byte -%type QUOTEDSTRING HEXSTRING ADDRSTRING sainfo_id +%type QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id %type identifierstring %type remote_index ike_addrinfo_port %type algorithm +%type dpd_algo_type +%type idle_dir_type %% @@ -259,7 +276,7 @@ privsep_stmt struct passwd *pw; if ((pw = getpwnam($2->v)) == NULL) { - yyerror("unkown user \"%s\"", $2->v); + yyerror("unknown user \"%s\"", $2->v); return -1; } lcconf->uid = pw->pw_uid; @@ -271,7 +288,7 @@ privsep_stmt struct group *gr; if ((gr = getgrnam($2->v)) == NULL) { - yyerror("unkown group \"%s\"", $2->v); + yyerror("unknown group \"%s\"", $2->v); return -1; } lcconf->gid = gr->gr_gid; @@ -295,7 +312,8 @@ path_statement racoon_free(lcconf->pathinfo[$2]); /* set new pathinfo */ - lcconf->pathinfo[$2] = strdup($3->v); + lcconf->pathinfo[$2] = racoon_strdup($3->v); + STRDUP_FATAL(lcconf->pathinfo[$2]); vfree($3); } EOS @@ -332,7 +350,7 @@ gssenc_statement } ; - /* self infomation */ + /* self information */ identifier_statement : IDENTIFIER identifier_stmt ; @@ -373,11 +391,12 @@ log_level | LOGLEV { /* - * set the loglevel by configuration file only when - * the command line did not specify any loglevel. + * set the loglevel to the value specified + * in the configuration file plus the number + * of -d options specified on the command line */ - if (loglevel <= LLV_BASE) - loglevel += $1; + loglevel += $1 - oldloglevel; + oldloglevel = $1; } ; @@ -482,9 +501,10 @@ modecfg_stmt : CFG_NET4 ADDRSTRING { #ifdef ENABLE_HYBRID - if (inet_pton(AF_INET, $2->v, - &isakmp_cfg_config.network4) != 1) - yyerror("bad IPv4 network address."); + if (inet_pton(AF_INET, $2->v, + &isakmp_cfg_config.network4) != 1) + yyerror("bad IPv4 network address."); + vfree($2); #else yyerror("racoon not configured with --enable-hybrid"); #endif @@ -496,28 +516,47 @@ modecfg_stmt if (inet_pton(AF_INET, $2->v, &isakmp_cfg_config.netmask4) != 1) yyerror("bad IPv4 netmask address."); + vfree($2); #else yyerror("racoon not configured with --enable-hybrid"); #endif } EOS - | CFG_DNS4 ADDRSTRING + | CFG_DNS4 addrdnslist + EOS + | CFG_NBNS4 addrwinslist + EOS + | CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist { #ifdef ENABLE_HYBRID - if (inet_pton(AF_INET, $2->v, - &isakmp_cfg_config.dns4) != 1) - yyerror("bad IPv4 DNS address."); + isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN; #else yyerror("racoon not configured with --enable-hybrid"); #endif } EOS - | CFG_NBNS4 ADDRSTRING + | CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist { #ifdef ENABLE_HYBRID - if (inet_pton(AF_INET, $2->v, - &isakmp_cfg_config.nbns4) != 1) - yyerror("bad IPv4 WINS address."); + isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_SPLIT_DNS splitdnslist + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_DEFAULT_DOMAIN QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + strlcpy(&isakmp_cfg_config.default_domain[0], + $2->v, sizeof(isakmp_cfg_config.default_domain)); + vfree($2); #else yyerror("racoon not configured with --enable-hybrid"); #endif @@ -553,6 +592,48 @@ modecfg_stmt #else /* HAVE_LIBPAM */ yyerror("racoon not configured with --with-libpam"); #endif /* HAVE_LIBPAM */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_AUTH_SOURCE CFG_LDAP + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_AUTH_GROUPS authgrouplist + { +#ifndef ENABLE_HYBRID + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_GROUP_SOURCE CFG_SYSTEM + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_GROUP_SOURCE CFG_LDAP + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ #else /* ENABLE_HYBRID */ yyerror("racoon not configured with --enable-hybrid"); #endif /* ENABLE_HYBRID */ @@ -564,6 +645,15 @@ modecfg_stmt isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE; #else yyerror("racoon not configured with --enable-hybrid"); +#endif + } + EOS + | CFG_ACCOUNTING CFG_SYSTEM + { +#ifdef ENABLE_HYBRID + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM; +#else + yyerror("racoon not configured with --enable-hybrid"); #endif } EOS @@ -596,15 +686,8 @@ modecfg_stmt | CFG_POOL_SIZE NUMBER { #ifdef ENABLE_HYBRID - size_t len; - - isakmp_cfg_config.pool_size = $2; - - len = $2 * sizeof(*isakmp_cfg_config.port_pool); - isakmp_cfg_config.port_pool = racoon_malloc(len); - if (isakmp_cfg_config.port_pool == NULL) + if (isakmp_cfg_resize_pool($2) != 0) yyerror("cannot allocate memory for pool"); - bzero(isakmp_cfg_config.port_pool, len); #else /* ENABLE_HYBRID */ yyerror("racoon not configured with --enable-hybrid"); #endif /* ENABLE_HYBRID */ @@ -654,6 +737,19 @@ modecfg_stmt #else /* HAVE_LIBRADIUS */ yyerror("racoon not configured with --with-libradius"); #endif /* HAVE_LIBRADIUS */ +#else /* ENABLE_HYBRID */ + yyerror("racoon not configured with --enable-hybrid"); +#endif /* ENABLE_HYBRID */ + } + EOS + | CFG_CONF_SOURCE CFG_LDAP + { +#ifdef ENABLE_HYBRID +#ifdef HAVE_LIBLDAP + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LDAP; +#else /* HAVE_LIBLDAP */ + yyerror("racoon not configured with --with-libldap"); +#endif /* HAVE_LIBLDAP */ #else /* ENABLE_HYBRID */ yyerror("racoon not configured with --enable-hybrid"); #endif /* ENABLE_HYBRID */ @@ -662,8 +758,7 @@ modecfg_stmt | CFG_MOTD QUOTEDSTRING { #ifdef ENABLE_HYBRID - strncpy(&isakmp_cfg_config.motd[0], $2->v, MAXPATHLEN); - isakmp_cfg_config.motd[MAXPATHLEN] = '\0'; + strlcpy(&isakmp_cfg_config.motd[0], $2->v, sizeof(isakmp_cfg_config.motd)); vfree($2); #else yyerror("racoon not configured with --enable-hybrid"); @@ -672,6 +767,150 @@ modecfg_stmt EOS ; +addrdnslist + : addrdns + | addrdns COMMA addrdnslist + ; +addrdns + : ADDRSTRING + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (icc->dns4_index > MAXNS) + yyerror("No more than %d DNS", MAXNS); + if (inet_pton(AF_INET, $1->v, + &icc->dns4[icc->dns4_index++]) != 1) + yyerror("bad IPv4 DNS address."); + + vfree($1); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +addrwinslist + : addrwins + | addrwins COMMA addrwinslist + ; +addrwins + : ADDRSTRING + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (icc->nbns4_index > MAXWINS) + yyerror("No more than %d WINS", MAXWINS); + if (inet_pton(AF_INET, $1->v, + &icc->nbns4[icc->nbns4_index++]) != 1) + yyerror("bad IPv4 WINS address."); + + vfree($1); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +splitnetlist + : splitnet + | splitnetlist COMMA splitnet + ; +splitnet + : ADDRSTRING PREFIX + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + struct unity_network network; + + if (inet_pton(AF_INET, $1->v, &network.addr4) != 1) + yyerror("bad IPv4 SPLIT address."); + + /* Turn $2 (the prefix) into a subnet mask */ + network.mask4.s_addr = ($2) ? htonl(~((1 << (32 - $2)) - 1)) : 0; + + /* add the network to our list */ + if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count)) + yyerror("Unable to allocate split network"); + + vfree($1); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +authgrouplist + : authgroup + | authgroup COMMA authgrouplist + ; +authgroup + : QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + char * groupname = NULL; + char ** grouplist = NULL; + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + grouplist = racoon_realloc(icc->grouplist, + sizeof(char**)*(icc->groupcount+1)); + if (grouplist == NULL) + yyerror("unable to allocate auth group list"); + + groupname = racoon_malloc($1->l+1); + if (groupname == NULL) + yyerror("unable to allocate auth group name"); + + memcpy(groupname,$1->v,$1->l); + groupname[$1->l]=0; + grouplist[icc->groupcount]=groupname; + icc->grouplist = grouplist; + icc->groupcount++; + + vfree($1); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + +splitdnslist + : splitdns + | splitdns COMMA splitdnslist + ; +splitdns + : QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + struct isakmp_cfg_config *icc = &isakmp_cfg_config; + + if (!icc->splitdns_len) + { + icc->splitdns_list = racoon_malloc($1->l); + if(icc->splitdns_list == NULL) + yyerror("error allocating splitdns list buffer"); + memcpy(icc->splitdns_list,$1->v,$1->l); + icc->splitdns_len = $1->l; + } + else + { + int len = icc->splitdns_len + $1->l + 1; + icc->splitdns_list = racoon_realloc(icc->splitdns_list,len); + if(icc->splitdns_list == NULL) + yyerror("error allocating splitdns list buffer"); + icc->splitdns_list[icc->splitdns_len] = ','; + memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l); + icc->splitdns_len = len; + } + vfree($1); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif + } + ; + + /* timer */ timer_statement : RETRY BOC timer_stmts EOC @@ -734,7 +973,7 @@ sainfo_statement return -1; } } - sainfo_name sainfo_peer BOC sainfo_specs + sainfo_name sainfo_param BOC sainfo_specs { struct sainfo *check; @@ -774,6 +1013,16 @@ sainfo_name cur_sainfo->idsrc = NULL; cur_sainfo->iddst = NULL; } + | ANONYMOUS sainfo_id + { + cur_sainfo->idsrc = NULL; + cur_sainfo->iddst = $2; + } + | sainfo_id ANONYMOUS + { + cur_sainfo->idsrc = $1; + cur_sainfo->iddst = NULL; + } | sainfo_id sainfo_id { cur_sainfo->idsrc = $1; @@ -806,14 +1055,8 @@ sainfo_id return -1; } $$ = ipsecdoi_sockaddr2id(saddr, -#if 0 - $3 == (sizeof(struct in_addr) << 3) && - $1 == IDTYPE_ADDRESS - ? ~0 : $3, -#else - $3 == ~0 ? (sizeof(struct in_addr) << 3): $3, -#endif - $5); + $3 == ~0 ? (sizeof(struct in_addr) << 3): $3, + $5); break; #ifdef INET6 case AF_INET6: @@ -822,15 +1065,9 @@ sainfo_id racoon_free(saddr); return -1; } - $$ = ipsecdoi_sockaddr2id(saddr, -#if 0 - $3 == (sizeof(struct in6_addr) << 3) && - $1 == IDTYPE_ADDRESS - ? ~0 : $3, -#else - $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3, -#endif - $5); + $$ = ipsecdoi_sockaddr2id(saddr, + $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3, + $5); break; #endif default: @@ -842,6 +1079,71 @@ sainfo_id if ($$ == NULL) return -1; } + | IDENTIFIERTYPE ADDRSTRING ADDRRANGE prefix port ul_proto + { + char portbuf[10]; + struct sockaddr *laddr = NULL, *haddr = NULL; + char *cur = NULL; + + if (($6 == IPPROTO_ICMP || $6 == IPPROTO_ICMPV6) + && ($5 != IPSEC_PORT_ANY || $5 != IPSEC_PORT_ANY)) { + yyerror("port number must be \"any\"."); + return -1; + } + + snprintf(portbuf, sizeof(portbuf), "%lu", $5); + + laddr = str2saddr($2->v, portbuf); + if (laddr == NULL) { + return -1; + } + vfree($2); + haddr = str2saddr($3->v, portbuf); + if (haddr == NULL) { + racoon_free(laddr); + return -1; + } + vfree($3); + + switch (laddr->sa_family) { + case AF_INET: + if ($6 == IPPROTO_ICMPV6) { + yyerror("upper layer protocol mismatched.\n"); + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + return -1; + } + $$ = ipsecdoi_sockrange2id(laddr, haddr, + $6); + break; +#ifdef INET6 + case AF_INET6: + if ($6 == IPPROTO_ICMP) { + yyerror("upper layer protocol mismatched.\n"); + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + return -1; + } + $$ = ipsecdoi_sockrange2id(laddr, haddr, + $6); + break; +#endif + default: + yyerror("invalid family: %d", laddr->sa_family); + $$ = NULL; + break; + } + if (laddr) + racoon_free(laddr); + if (haddr) + racoon_free(haddr); + if ($$ == NULL) + return -1; + } | IDENTIFIERTYPE QUOTEDSTRING { struct ipsecdoi_id_b *id_b; @@ -869,7 +1171,7 @@ sainfo_id memcpy($$->v + sizeof(*id_b), $2->v, $2->l); } ; -sainfo_peer +sainfo_param : /* nothing */ { cur_sainfo->id_i = NULL; @@ -900,6 +1202,18 @@ sainfo_peer idv->v, idv->l); vfree(idv); } + | GROUP QUOTEDSTRING + { +#ifdef ENABLE_HYBRID + if ((cur_sainfo->group = vdup($2)) == NULL) { + yyerror("failed to set sainfo xauth group.\n"); + return -1; + } +#else + yyerror("racoon not configured with --enable-hybrid"); + return -1; +#endif + } ; sainfo_specs : /* nothing */ @@ -1201,7 +1515,11 @@ remote_spec yywarn("This directive without certtype will be removed!\n"); yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v); cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE; - cur_rmconf->peerscertfile = strdup($2->v); + + if (cur_rmconf->peerscertfile != NULL) + racoon_free(cur_rmconf->peerscertfile); + cur_rmconf->peerscertfile = racoon_strdup($2->v); + STRDUP_FATAL(cur_rmconf->peerscertfile); vfree($2); } EOS @@ -1209,14 +1527,20 @@ remote_spec { cur_rmconf->cacerttype = $2; cur_rmconf->getcacert_method = ISAKMP_GETCERT_LOCALFILE; - cur_rmconf->cacertfile = strdup($3->v); + if (cur_rmconf->cacertfile != NULL) + racoon_free(cur_rmconf->cacertfile); + cur_rmconf->cacertfile = racoon_strdup($3->v); + STRDUP_FATAL(cur_rmconf->cacertfile); vfree($3); } EOS | PEERS_CERTFILE CERT_X509 QUOTEDSTRING { cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE; - cur_rmconf->peerscertfile = strdup($3->v); + if (cur_rmconf->peerscertfile != NULL) + racoon_free(cur_rmconf->peerscertfile); + cur_rmconf->peerscertfile = racoon_strdup($3->v); + STRDUP_FATAL(cur_rmconf->peerscertfile); vfree($3); } EOS @@ -1278,7 +1602,7 @@ remote_spec EOS | OPEN_DIR_AUTH_GROUP QUOTEDSTRING { -#ifdef __APPLE__ +#if defined(__APPLE__) && HAVE_OPENDIR cur_rmconf->open_dir_auth_group = $2; #else yyerror("Apple specific features not compiled in."); @@ -1296,16 +1620,28 @@ remote_spec cur_rmconf->idvtype = $2; } EOS + | MY_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring + { + if (set_identifier_qual(&cur_rmconf->idv, $2, $4, $3) != 0) { + yyerror("failed to set identifer.\n"); + return -1; + } + cur_rmconf->idvtype = $2; + } + EOS | XAUTH_LOGIN identifierstring { #ifdef ENABLE_HYBRID /* formerly identifier type login */ - cur_rmconf->idvtype = IDTYPE_LOGIN; - if (set_identifier(&cur_rmconf->idv, IDTYPE_LOGIN, $2) != 0) { + if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) { + yyerror("failed to allocate xauth state\n"); + return -1; + } + if ((cur_rmconf->xauth->login = vdup($2)) == NULL) { yyerror("failed to set identifer.\n"); return -1; } - /* cur_rmconf->use_xauth = 1; */ + vfree($2); //%%% BUG FIX - memory leak #else yyerror("racoon not configured with --enable-hybrid"); #endif @@ -1330,6 +1666,23 @@ remote_spec genlist_append (cur_rmconf->idvl_p, id); } EOS + | PEERS_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring + { + struct idspec *id; + id = newidspec(); + if (id == NULL) { + yyerror("failed to allocate idspec"); + return -1; + } + if (set_identifier_qual(&id->id, $2, $4, $3) != 0) { + yyerror("failed to set identifer.\n"); + racoon_free(id); + return -1; + } + id->idtype = $2; + genlist_append (cur_rmconf->idvl_p, id); + } + EOS | VERIFY_IDENTIFIER SWITCH { cur_rmconf->verify_identifier = $2; } EOS | SHARED_SECRET SECRETTYPE QUOTEDSTRING { @@ -1364,23 +1717,37 @@ remote_spec dh_group_num EOS | PASSIVE SWITCH { cur_rmconf->passive = $2; } EOS | IKE_FRAG SWITCH { cur_rmconf->ike_frag = $2; } EOS + | IKE_FRAG REMOTE_FORCE_LEVEL { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } EOS | ESP_FRAG NUMBER { #ifdef SADB_X_EXT_NAT_T_FRAG - cur_rmconf->esp_frag = $2; + if (libipsec_opt & LIBIPSEC_OPT_FRAG) + cur_rmconf->esp_frag = $2; + else + yywarn("libipsec lacks IKE frag support"); #else yywarn("Your kernel does not support esp_frag"); #endif } EOS | SCRIPT QUOTEDSTRING PHASE1_UP { + if (cur_rmconf->script[SCRIPT_PHASE1_UP] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_UP]); + cur_rmconf->script[SCRIPT_PHASE1_UP] = script_path_add(vdup($2)); } EOS | SCRIPT QUOTEDSTRING PHASE1_DOWN { + if (cur_rmconf->script[SCRIPT_PHASE1_DOWN] != NULL) + vfree(cur_rmconf->script[SCRIPT_PHASE1_DOWN]); + cur_rmconf->script[SCRIPT_PHASE1_DOWN] = script_path_add(vdup($2)); } EOS | MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS + | WEAK_PHASE1_CHECK SWITCH { + cur_rmconf->weak_phase1_check = $2; + } EOS | GENERATE_POLICY SWITCH { cur_rmconf->gen_policy = $2; } EOS + | GENERATE_POLICY GENERATE_LEVEL { cur_rmconf->gen_policy = $2; } EOS | SUPPORT_PROXY SWITCH { cur_rmconf->support_proxy = $2; } EOS | INITIAL_CONTACT SWITCH { cur_rmconf->ini_contact = $2; } EOS | NAT_TRAVERSAL SWITCH @@ -1411,7 +1778,19 @@ remote_spec yyerror("NAT-T support not compiled in."); #endif } EOS - | DPD SWITCH + | NAT_TRAVERSAL_KEEPALIVE SWITCH + { +#ifdef ENABLE_NATT +#ifdef __APPLE__ + cur_rmconf->natt_keepalive = $2; +#else + yyerror("Apple specific features not compiled in."); +#endif +#else + yyerror("NAT-T support not compiled in."); +#endif + } EOS +| DPD SWITCH { #ifdef ENABLE_DPD cur_rmconf->dpd = $2; @@ -1446,6 +1825,21 @@ remote_spec #endif } EOS + | DPD_ALGORITHM dpd_algo_type + { +#ifdef ENABLE_DPD + cur_rmconf->dpd_algo = $2; +#else + yyerror("DPD support not compiled in."); +#endif + } + EOS + | DISCONNECT_ON_IDLE IDLE_TIMEOUT NUMBER IDLE_DIRECTION idle_dir_type + { + cur_rmconf->idle_timeout = $3; + cur_rmconf->idle_timeout_dir = $5; + } + EOS | LIFETIME LIFETYPE_TIME NUMBER unittype_time { cur_rmconf->prhead->lifetime = $3 * $4; @@ -1484,7 +1878,7 @@ exchange_types struct etypes *new; new = racoon_malloc(sizeof(struct etypes)); if (new == NULL) { - yyerror("filed to allocate etypes"); + yyerror("failed to allocate etypes"); return -1; } new->type = $2; @@ -1505,9 +1899,15 @@ cert_spec : CERT_X509 QUOTEDSTRING QUOTEDSTRING { cur_rmconf->certtype = $1; - cur_rmconf->mycertfile = strdup($2->v); + if (cur_rmconf->mycertfile != NULL) + racoon_free(cur_rmconf->mycertfile); + cur_rmconf->mycertfile = racoon_strdup($2->v); + STRDUP_FATAL(cur_rmconf->mycertfile); vfree($2); - cur_rmconf->myprivfile = strdup($3->v); + if (cur_rmconf->myprivfile != NULL) + racoon_free(cur_rmconf->myprivfile); + cur_rmconf->myprivfile = racoon_strdup($3->v); + STRDUP_FATAL(cur_rmconf->myprivfile); vfree($3); } EOS @@ -1615,7 +2015,11 @@ isakmpproposal_spec yyerror("wrong Vendor ID for gssapi_id"); return -1; } - cur_rmconf->prhead->spspec->gssid = strdup($2->v); + if (cur_rmconf->prhead->spspec->gssid != NULL) + racoon_free(cur_rmconf->prhead->spspec->gssid); + cur_rmconf->prhead->spspec->gssid = + racoon_strdup($2->v); + STRDUP_FATAL(cur_rmconf->prhead->spspec->gssid); } EOS | ALGORITHM_CLASS ALGORITHMTYPE keylength @@ -1726,6 +2130,16 @@ unittype_byte | UNITTYPE_MBYTES { $$ = (1024 * 1024); } | UNITTYPE_TBYTES { $$ = (1024 * 1024 * 1024); } ; +dpd_algo_type + : DPD_ALGO_TYPE_DEFAULT { $$ = DPD_ALGO_DEFAULT; } + | DPD_ALGO_TYPE_INBOUND { $$ = DPD_ALGO_INBOUND_DETECT; } + | DPD_ALGO_TYPE_BLACKHOLE { $$ = DPD_ALGO_BLACKHOLE_DETECT; } + ; +idle_dir_type + : IDLE_DIRECTION_ANY { $$ = IPSEC_DIR_ANY; } + | IDLE_DIRECTION_IN { $$ = IPSEC_DIR_INBOUND; } + | IDLE_DIRECTION_OUT { $$ = IPSEC_DIR_OUTBOUND; } + ; %% static struct proposalspec * @@ -1962,7 +2376,11 @@ expand_isakmpspec(prop_no, trns_no, types, #ifdef HAVE_GSSAPI if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { if (gssid != NULL) { - new->gssid = vmalloc(strlen(gssid)); + if ((new->gssid = vmalloc(strlen(gssid))) == NULL) { + racoon_free(new); + yyerror("failed to allocate gssid"); + return -1; + } memcpy(new->gssid->v, gssid, new->gssid->l); racoon_free(gssid); } else { @@ -2039,8 +2457,16 @@ cfparse() yycf_init_buffer(); - if (yycf_switch_buffer(lcconf->racoon_conf) != 0) + if (yycf_switch_buffer(lcconf->racoon_conf) != 0) { + IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf), + IPSECCONFIGEVENTCODE_PARSE_ERROR, + CONSTSTR("could not read configuration file"), + CONSTSTR("cfparse: yycf_switch_buffer erred")); + plog(LLV_ERROR, LOCATION, NULL, + "could not read configuration file \"%s\"\n", + lcconf->racoon_conf); return -1; + } error = yyparse(); if (error != 0) { @@ -2052,6 +2478,11 @@ cfparse() plog(LLV_ERROR, LOCATION, NULL, "fatal parse failure.\n"); } + IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf), + IPSECCONFIGEVENTCODE_PARSE_ERROR, + CONSTSTR("fatal parse failure"), + CONSTSTR("cfparse: yyparse erred")); + yycf_clean_buffer(); return -1; } @@ -2059,6 +2490,11 @@ cfparse() plog(LLV_ERROR, LOCATION, NULL, "parse error is nothing, but yyerrorcount is %d.\n", yyerrorcount); + IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf), + IPSECCONFIGEVENTCODE_PARSE_ERROR, + CONSTSTR("ambivalent error code"), + CONSTSTR("cfparse: error == 0 && yerrorcount")); + yycf_clean_buffer(); exit(1); } @@ -2070,14 +2506,28 @@ cfparse() } int -cfreparse() +cfreparse(int sig) { - plog(LLV_DEBUG, LOCATION, NULL, "==== Got HUP signal - re-parsing.\n"); - flushph2(); - flushph1(); + int ignore_established_handles = (sig == SIGUSR1); + + if (sig >= 0 && sig < NSIG) { + plog(LLV_DEBUG, LOCATION, NULL, "==== Got %s signal - re-parsing.\n", sys_signame[sig]); + } else { + plog(LLV_ERROR, LOCATION, NULL, "==== Got Unknown signal - re-parsing.\n"); + IPSECCONFIGTRACEREVENT(CONSTSTR("reparse"), + IPSECCONFIGEVENTCODE_REPARSE_ERROR, + CONSTSTR("Unknown signal"), + CONSTSTR("cfreparse: triggered by unknown signal")); + } + + flushph2(ignore_established_handles); + flushph1(ignore_established_handles); flushrmconf(); flushsainfo(); flushlcconf(); +#ifdef HAVE_LIBLDAP + xauth_ldap_flush(); +#endif check_auto_exit(); /* check/change state of auto exit */ clean_tmpalgtype(); diff --git a/ipsec-tools/racoon/cfparse_proto.h b/ipsec-tools/racoon/cfparse_proto.h index 73c824e..010cdcd 100644 --- a/ipsec-tools/racoon/cfparse_proto.h +++ b/ipsec-tools/racoon/cfparse_proto.h @@ -35,6 +35,6 @@ /* cfparse.y */ extern int yyparse __P((void)); extern int cfparse __P((void)); -extern int cfreparse __P((void)); +extern int cfreparse __P((int)); #endif /* _CFPARSE_PROTO_H */ diff --git a/ipsec-tools/racoon/cftoken.l b/ipsec-tools/racoon/cftoken.l index 861e836..4d82599 100644 --- a/ipsec-tools/racoon/cftoken.l +++ b/ipsec-tools/racoon/cftoken.l @@ -1,4 +1,6 @@ -/* $Id: cftoken.l,v 1.31.2.7 2005/11/06 17:18:26 monas Exp $ */ +/* $NetBSD: cftoken.l,v 1.11.4.1 2007/08/01 11:52:20 vanhu Exp $ */ + +/* Id: cftoken.l,v 1.53 2006/08/22 18:17:17 manubsd Exp */ %option noyywrap %{ /* @@ -75,7 +77,9 @@ #include "isakmp_var.h" #include "isakmp.h" #include "ipsec_doi.h" +#include "policy.h" #include "proposal.h" +#include "remoteconf.h" #include "nattraversal.h" #ifdef GC #include "gcmalloc.h" @@ -131,6 +135,7 @@ bcl \{ ecl \} blcl \[ elcl \] +hyphen \- percent \% semi \; comment \#.* @@ -172,7 +177,7 @@ hexstring 0x{hexdigit}+ return(PATHTYPE); } certificate { YYD; yylval.num = LC_PATHTYPE_CERT; return(PATHTYPE); } -script { YYD; yylval.num = LC_PATHTYPE_SCRIPT; +script { YYD; yylval.num = LC_PATHTYPE_SCRIPT; return(PATHTYPE); } backupsa { YYD; yylval.num = LC_PATHTYPE_BACKUPSA; return(PATHTYPE); } @@ -194,12 +199,14 @@ hexstring 0x{hexdigit}+ /* logging */ log { BEGIN S_LOG; YYDB; return(LOGGING); } -info { YYD; yywarn("it is obsoleted. use \"notify\""); yylval.num = 0; return(LOGLEV); } -notify { YYD; yylval.num = 0; return(LOGLEV); } -debug { YYD; yylval.num = 1; return(LOGLEV); } -debug2 { YYD; yylval.num = 2; return(LOGLEV); } -debug3 { YYD; yywarn("it is osboleted. use \"debug2\""); yylval.num = 2; return(LOGLEV); } -debug4 { YYD; yywarn("it is obsoleted. use \"debug2\""); yylval.num = 2; return(LOGLEV); } +error { YYD; yylval.num = LLV_ERROR; return(LOGLEV); } +warning { YYD; yylval.num = LLV_WARNING; return(LOGLEV); } +notify { YYD; yylval.num = LLV_NOTIFY; return(LOGLEV); } +info { YYD; yylval.num = LLV_INFO; return(LOGLEV); } +debug { YYD; yylval.num = LLV_DEBUG; return(LOGLEV); } +debug2 { YYD; yylval.num = LLV_DEBUG2; return(LOGLEV); } +debug3 { YYD; yywarn("it is obsoleted. use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); } +debug4 { YYD; yywarn("it is obsoleted. use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); } {semi} { BEGIN S_INI; return(EOS); } /* padding */ @@ -230,7 +237,10 @@ hexstring 0x{hexdigit}+ netmask4 { YYD; return(CFG_MASK4); } dns4 { YYD; return(CFG_DNS4); } wins4 { YYD; return(CFG_NBNS4); } +default_domain { YYD; return(CFG_DEFAULT_DOMAIN); } auth_source { YYD; return(CFG_AUTH_SOURCE); } +auth_groups { YYD; return(CFG_AUTH_GROUPS); } +group_source { YYD; return(CFG_GROUP_SOURCE); } conf_source { YYD; return(CFG_CONF_SOURCE); } accounting { YYD; return(CFG_ACCOUNTING); } system { YYD; return(CFG_SYSTEM); } @@ -241,8 +251,13 @@ hexstring 0x{hexdigit}+ pool_size { YYD; return(CFG_POOL_SIZE); } banner { YYD; return(CFG_MOTD); } auth_throttle { YYD; return(CFG_AUTH_THROTTLE); } +split_network { YYD; return(CFG_SPLIT_NETWORK); } +local_lan { YYD; return(CFG_SPLIT_LOCAL); } +include { YYD; return(CFG_SPLIT_INCLUDE); } +split_dns { YYD; return(CFG_SPLIT_DNS); } pfs_group { YYD; return(CFG_PFS_GROUP); } save_passwd { YYD; return(CFG_SAVE_PASSWD); } +{comma} { YYD; return(COMMA); } {ecl} { BEGIN S_INI; return(EOC); } /* timer */ @@ -263,11 +278,13 @@ hexstring 0x{hexdigit}+ {blcl}any{elcl} { YYD; return(PORTANY); } any { YYD; return(ANY); } from { YYD; return(FROM); } +group { YYD; return(GROUP); } /* sainfo spec */ {bcl} { BEGIN S_SAINFS; return(BOC); } {semi} { BEGIN S_INI; return(EOS); } {ecl} { BEGIN S_INI; return(EOC); } pfs_group { YYD; return(PFS_GROUP); } +remoteid { YYD; return(REMOTEID); } identifier { YYD; yywarn("it is obsoleted. use \"my_identifier\"."); return(IDENTIFIER); } my_identifier { YYD; return(MY_IDENTIFIER); } lifetime { YYD; return(LIFETIME); } @@ -306,7 +323,7 @@ hexstring 0x{hexdigit}+ x509 { YYD; yylval.num = ISAKMP_CERT_X509SIGN; return(CERT_X509); } plain_rsa { YYD; yylval.num = ISAKMP_CERT_PLAINRSA; return(CERT_PLAINRSA); } open_dir_auth_group { -#ifdef __APPLE__ +#if defined(__APPLE__) && HAVE_OPENDIR YYD; return(OPEN_DIR_AUTH_GROUP); #else @@ -358,6 +375,14 @@ hexstring 0x{hexdigit}+ yyerror("Apple specific features not compiled in."); #endif } +nat_traversal_keepalive { +#ifdef __APPLE__ + YYD; + return(NAT_TRAVERSAL_KEEPALIVE); +#else + yyerror("Apple specific features not compiled in."); +#endif +} proposal_check { YYD; return(PROPOSAL_CHECK); } obey { YYD; yylval.num = PROP_CHECK_OBEY; return(PROPOSAL_CHECK_LEVEL); } strict { YYD; yylval.num = PROP_CHECK_STRICT; return(PROPOSAL_CHECK_LEVEL); } @@ -372,12 +397,17 @@ hexstring 0x{hexdigit}+ dpd_delay { YYD; return(DPD_DELAY); } dpd_retry { YYD; return(DPD_RETRY); } dpd_maxfail { YYD; return(DPD_MAXFAIL); } +dpd_algorithm { YYD; return(DPD_ALGORITHM); } +disconnect_on_idle { YYD; return(DISCONNECT_ON_IDLE); } +idle_timeout { YYD; return(IDLE_TIMEOUT); } +idle_direction { YYD; return(IDLE_DIRECTION); } ike_frag { YYD; return(IKE_FRAG); } esp_frag { YYD; return(ESP_FRAG); } script { YYD; return(SCRIPT); } phase1_up { YYD; return(PHASE1_UP); } phase1_down { YYD; return(PHASE1_DOWN); } mode_cfg { YYD; return(MODE_CFG); } +weak_phase1_check { YYD; return(WEAK_PHASE1_CHECK); } /* remote proposal */ proposal { BEGIN S_RMTP; YYDB; return(PROPOSAL); } {bcl} { return(BOC); } @@ -423,6 +453,19 @@ off { YYD; yylval.num = FALSE; return(SWITCH); } return(PORT); } + /* address range */ +{hyphen}{addrstring} { + YYD; + yytext++; + yylval.val = vmalloc(yyleng + 1); + if (yylval.val == NULL) { + yyerror("vmalloc failed"); + return -1; + } + memcpy(yylval.val->v, yytext, yylval.val->l); + return(ADDRRANGE); + } + /* upper protocol */ esp { YYD; yylval.num = IPPROTO_ESP; return(UL_PROTO); } ah { YYD; yylval.num = IPPROTO_AH; return(UL_PROTO); } @@ -516,6 +559,36 @@ hybrid_dss_client { #endif } +xauth_psk_server { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_psk_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +xauth_psk_client { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_psk_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +xauth_rsa_server { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_rsa_s; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} +xauth_rsa_client { +#ifdef ENABLE_HYBRID + YYD; yylval.num = algtype_xauth_rsa_c; return(ALGORITHMTYPE); +#else + yyerror("racoon not configured with --enable-hybrid"); +#endif +} + + /* identifier type */ vendor_id { YYD; yywarn("it is obsoleted."); return(VENDORID); } @@ -556,7 +629,7 @@ key { #endif } keychain { -#ifdef __APPLE__ +#if defined(__APPLE__) && HAVE_KEYCHAIN YYD; yylval.num = SECRETTYPE_KEYCHAIN; return(SECRETTYPE); @@ -612,6 +685,10 @@ use_peers_identifier { #endif } + /* identifier qualifier */ +tag { YYD; yylval.num = IDQUAL_TAG; return(IDENTIFIERQUAL); } +file { YYD; yylval.num = IDQUAL_FILE; return(IDENTIFIERQUAL); } + /* units */ B|byte|bytes { YYD; return(UNITTYPE_BYTE); } KB { YYD; return(UNITTYPE_KBYTES); } @@ -621,6 +698,14 @@ sec|secs|second|seconds { YYD; return(UNITTYPE_SEC); } min|mins|minute|minutes { YYD; return(UNITTYPE_MIN); } hour|hours { YYD; return(UNITTYPE_HOUR); } +dpd_default { YYD; return(DPD_ALGO_TYPE_DEFAULT); } +dpd_inbound_detect { YYD; return(DPD_ALGO_TYPE_INBOUND); } +dpd_blackhole_detect { YYD; return(DPD_ALGO_TYPE_BLACKHOLE); } + +idle_any { YYD; return(IDLE_DIRECTION_ANY); } +idle_inbound { YYD; return(IDLE_DIRECTION_IN); } +idle_outbound { YYD; return(IDLE_DIRECTION_OUT); } + /* boolean */ yes { YYD; yylval.num = TRUE; return(BOOLEAN); } no { YYD; yylval.num = FALSE; return(BOOLEAN); } @@ -687,7 +772,6 @@ no { YYD; yylval.num = FALSE; return(BOOLEAN); } <> { yy_delete_buffer(YY_CURRENT_BUFFER); - yycf_free_buffer(incstackp); incstackp--; nextfile: if (incstack[incstackp].matchon < @@ -733,7 +817,7 @@ yyerror(char *s, ...) snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n", incstack[incstackp].path, incstack[incstackp].lineno, yytext, s); - plogv(LLV_ERROR, LOCATION, NULL, fmt, ap); + plogv(LLV_ERROR, LOCATION, NULL, fmt, &ap); va_end(ap); yyerrorcount++; @@ -753,7 +837,7 @@ yywarn(char *s, ...) snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n", incstack[incstackp].path, incstack[incstackp].lineno, yytext, s); - plogv(LLV_WARNING, LOCATION, NULL, fmt, ap); + plogv(LLV_WARNING, LOCATION, NULL, fmt, &ap); va_end(ap); } @@ -772,9 +856,9 @@ yycf_switch_buffer(path) if (glob(path, GLOB_TILDE, NULL, &incstack[incstackp].matches) != 0 || incstack[incstackp].matches.gl_pathc == 0) { - plog(LLV_ERROR, LOCATION, NULL, - "glob found no matches for path"); - return -1; + plog(LLV_WARNING, LOCATION, NULL, + "glob found no matches for path \"%s\"\n", path); + return 0; } incstack[incstackp].matchon = 0; incstack[incstackp].prevstate = YY_CURRENT_BUFFER; @@ -814,8 +898,13 @@ yycf_set_buffer(path) } /* initialize */ + if (incstack[incstackp].path != NULL) { + fclose(incstack[incstackp].fp); + racoon_free(incstack[incstackp].path); + } incstack[incstackp].fp = yyin; - incstack[incstackp].path = strdup(path); + incstack[incstackp].path = racoon_strdup(path); + STRDUP_FATAL(incstack[incstackp].path); incstack[incstackp].lineno = 1; plog(LLV_DEBUG, LOCATION, NULL, "reading config file %s\n", path); @@ -833,22 +922,17 @@ yycf_init_buffer() incstackp = 0; } -void -yycf_free_buffer(index) - int index; -{ - fclose(incstack[index].fp); - racoon_free(incstack[index].path); - incstack[index].path = NULL; -} - void yycf_clean_buffer() { int i; - for (i = 0; i < MAX_INCLUDE_DEPTH; i++) - if (incstack[i].path != NULL) - yycf_free_buffer(i); + for (i = 0; i < MAX_INCLUDE_DEPTH; i++) { + if (incstack[i].path != NULL) { + fclose(incstack[i].fp); + racoon_free(incstack[i].path); + incstack[i].path = NULL; + } + } } diff --git a/ipsec-tools/racoon/cftoken_proto.h b/ipsec-tools/racoon/cftoken_proto.h index 76156a6..41cb939 100644 --- a/ipsec-tools/racoon/cftoken_proto.h +++ b/ipsec-tools/racoon/cftoken_proto.h @@ -1,4 +1,6 @@ -/* $Id: cftoken_proto.h,v 1.3 2004/06/11 16:00:15 ludvigm Exp $ */ +/* $NetBSD: cftoken_proto.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: cftoken_proto.h,v 1.3 2004/06/11 16:00:15 ludvigm Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -42,6 +44,5 @@ extern int yycf_switch_buffer __P((char *)); extern int yycf_set_buffer __P((char *)); extern void yycf_init_buffer __P((void)); extern void yycf_clean_buffer __P((void)); -extern void yycf_free_buffer __P((int)); #endif /* _CFTOKEN_PROTO_H */ diff --git a/ipsec-tools/racoon/com.apple.racoon.plist b/ipsec-tools/racoon/com.apple.racoon.plist new file mode 100644 index 0000000..69412ba --- /dev/null +++ b/ipsec-tools/racoon/com.apple.racoon.plist @@ -0,0 +1,30 @@ + + + + + Label + com.apple.racoon + Program + /usr/sbin/racoon + RunAtLoad + + KeepAlive + + UserName + root + Sockets + + Listeners + + SockFamily + Unix + SockPathMode + 384 + SockPathName + /var/run/vpncontrol.sock + + + EnableTransactions + + + diff --git a/ipsec-tools/racoon/com.apple.racoonembedded.plist b/ipsec-tools/racoon/com.apple.racoonembedded.plist new file mode 100644 index 0000000..bf9ad81 --- /dev/null +++ b/ipsec-tools/racoon/com.apple.racoonembedded.plist @@ -0,0 +1,28 @@ + + + + + Label + com.apple.racoon + Program + /usr/sbin/racoon + RunAtLoad + + KeepAlive + + UserName + root + Sockets + + Listeners + + SockFamily + Unix + SockPathMode + 384 + SockPathName + /tmp/racoon/vpncontrol.sock + + + + diff --git a/ipsec-tools/racoon/crypto_cssm.c b/ipsec-tools/racoon/crypto_cssm.c index 9b0e349..e5b35d6 100644 --- a/ipsec-tools/racoon/crypto_cssm.c +++ b/ipsec-tools/racoon/crypto_cssm.c @@ -27,47 +27,58 @@ * Framework and CSSM */ -#include #include #include +#include +#include #include + +#include +#if TARGET_OS_EMBEDDED +#include +#else +#include #include #include #include #include #include -#include + #include -#include #include #include #include +#endif + #include #include #include "plog.h" #include "debug.h" #include "misc.h" -#include "crypto_cssm.h" +#include "crypto_cssm.h" -static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef); static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef); -static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef); static const char *GetSecurityErrorString(OSStatus err); - +#if !TARGET_OS_EMBEDDED +static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef); +static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef); +#endif /* * Verify cert using security framework */ -int crypto_cssm_check_x509cert(vchar_t *cert) +int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname) { OSStatus status; - SecCertificateRef certRef = 0; + SecCertificateRef certRef = NULL; + SecPolicyRef policyRef = NULL; + +#if !TARGET_OS_EMBEDDED CSSM_DATA certData; CSSM_OID ourPolicyOID = CSSMOID_APPLE_TP_IP_SEC; - SecPolicyRef policyRef = 0; // create cert ref certData.Length = cert->l; @@ -81,15 +92,47 @@ int crypto_cssm_check_x509cert(vchar_t *cert) status = FindPolicy(&ourPolicyOID, &policyRef); if (status != noErr) goto end; - - // setup policy options ??? // no options used at present - verification of subjectAltName fields, etc. // are done elsewhere in racoon in oakley_check_certid() + +#else + CFDataRef cert_data = CFDataCreateWithBytesNoCopy(NULL, cert->v, cert->l, kCFAllocatorNull); + if (cert_data) { + certRef = SecCertificateCreateWithData(NULL, cert_data); + CFRelease(cert_data); + } + + if (certRef == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to create a certRef.\n"); + status = -1; + goto end; + } + + if (hostname) { + policyRef = SecPolicyCreateSSL(FALSE, hostname); + if (policyRef == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to create a SSL policyRef.\n"); + status = -1; + goto end; + } + } else + { + policyRef = SecPolicyCreateBasicX509(); + if (policyRef == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to create a Basic X509 policyRef.\n"); + status = -1; + goto end; + } + } + +#endif // evaluate cert status = EvaluateCert(certRef, policyRef); - end: if (certRef) @@ -114,27 +157,29 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash) { OSStatus status; - SecCertificateRef certificateRef = NULL; SecIdentityRef identityRef = NULL; + SecKeyRef privateKeyRef = NULL; + vchar_t *sig = NULL; + +#if !TARGET_OS_EMBEDDED + u_int32_t bytesEncrypted = 0; + SecCertificateRef certificateRef = NULL; SecIdentitySearchRef idSearchRef = NULL; SecKeychainRef keychainRef = NULL; - SecKeyRef privateKeyRef = NULL; const CSSM_KEY *cssmKey = NULL; CSSM_CSP_HANDLE cspHandle = nil; CSSM_CC_HANDLE cssmContextHandle = nil; const CSSM_ACCESS_CREDENTIALS *credentials = NULL; //CSSM_SIZE bytesEncrypted = 0; //%%%%HWR fix this - need new headers on Leopard - uint32 bytesEncrypted = 0; CSSM_DATA clearData; CSSM_DATA cipherData; CSSM_DATA remData; CSSM_CONTEXT_ATTRIBUTE newAttr; - vchar_t *sig = NULL; remData.Length = 0; remData.Data = 0; - if (persistentCertRef) { + if (persistentCertRef) { // get cert from keychain status = SecKeychainItemCopyFromPersistentReference(persistentCertRef, (SecKeychainItemRef*)&certificateRef); if (status != noErr) @@ -151,6 +196,7 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash) goto end; } else { + // copy system keychain status = CopySystemKeychain(&keychainRef); if (status != noErr) @@ -171,7 +217,6 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash) goto end; } - // get private key from identity status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef); if (status != noErr) @@ -231,20 +276,60 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash) sig->l = cipherData.Length; sig->v = (caddr_t)cipherData.Data; + +#else + + CFDictionaryRef persistFind = NULL; + const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef }; + const void *values_persist[] = { kCFBooleanTrue, persistentCertRef }; + + #define SIG_BUF_SIZE 1024 + + /* find identity by persistent ref */ + persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist, + (sizeof(keys_persist) / sizeof(*keys_persist)), NULL, NULL); + if (persistFind == NULL) + goto end; + + status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef); + if (status != noErr) + goto end; + + status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef); + if (status != noErr) + goto end; + + // alloc buffer for result + sig = vmalloc(SIG_BUF_SIZE); + if (sig == NULL) + goto end; + + status = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1, hash->v, + hash->l, sig->v, &sig->l); + +#endif + end: - if (certificateRef) - CFRelease(certificateRef); - if (keychainRef) - CFRelease(keychainRef); if (identityRef) CFRelease(identityRef); if (privateKeyRef) CFRelease(privateKeyRef); + +#if !TARGET_OS_EMBEDDED + if (certificateRef) + CFRelease(certificateRef); + if (keychainRef) + CFRelease(keychainRef); if (idSearchRef) CFRelease(idSearchRef); if (cssmContextHandle) CSSM_DeleteContext(cssmContextHandle); +#else + if (persistFind) + CFRelease(persistFind); +#endif + if (status != noErr) { if (sig) { vfree(sig); @@ -269,13 +354,14 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef) { OSStatus status; - CSSM_DATA cssmData; vchar_t *cert = NULL; SecIdentityRef identityRef = NULL; - SecIdentitySearchRef idSearchRef = NULL; - SecKeychainRef keychainRef = NULL; SecCertificateRef certificateRef = NULL; +#if !TARGET_OS_EMBEDDED + CSSM_DATA cssmData; + SecIdentitySearchRef idSearchRef = NULL; + SecKeychainRef keychainRef = NULL; // get cert ref if (persistentCertRef) { @@ -303,7 +389,7 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef) goto end; } - + // get certificate data cssmData.Length = 0; cssmData.Data = NULL; @@ -321,17 +407,62 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef) // cssmData struct just points to the data // data must be copied to be returned memcpy(cert->v, cssmData.Data, cssmData.Length); + +#else + + CFDictionaryRef persistFind = NULL; + const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef }; + const void *values_persist[] = { kCFBooleanTrue, persistentCertRef }; + size_t dataLen; + CFDataRef certData = NULL; + + /* find identity by persistent ref */ + persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist, + (sizeof(keys_persist) / sizeof(*keys_persist)), NULL, NULL); + if (persistFind == NULL) + goto end; + + status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef); + if (status != noErr) + goto end; + + status = SecIdentityCopyCertificate(identityRef, &certificateRef); + if (status != noErr) + goto end; + + certData = SecCertificateCopyData(certificateRef); + if (certData == NULL) + goto end; + + dataLen = CFDataGetLength(certData); + if (dataLen == 0) + goto end; + + cert = vmalloc(dataLen); + if (cert == NULL) + goto end; + + CFDataGetBytes(certData, CFRangeMake(0, dataLen), cert->v); + +#endif end: if (certificateRef) CFRelease(certificateRef); if (identityRef) CFRelease(identityRef); +#if !TARGET_OS_EMBEDDED if (idSearchRef) CFRelease(idSearchRef); if (keychainRef) CFRelease(keychainRef); - +#else + if (persistFind) + CFRelease(persistFind); + if (certData) + CFRelease(certData); +#endif + if (status != noErr && status != -1) { plog(LLV_ERROR, LOCATION, NULL, "error %d %s.\n", status, GetSecurityErrorString(status)); @@ -341,7 +472,7 @@ end: } - +#if !TARGET_OS_EMBEDDED /* * Find a policy ref by OID */ @@ -368,7 +499,7 @@ end: } return status; } - +#endif /* * Evaluate the trust of a cert using the policy provided @@ -381,8 +512,8 @@ static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef) SecCertificateRef evalCertArray[1] = { cert }; - CFArrayRef cfCertRef = CFArrayCreate((CFAllocatorRef) NULL, (void*)evalCertArray, 1, - &kCFTypeArrayCallBacks); + CFArrayRef cfCertRef = CFArrayCreate((CFAllocatorRef) NULL, (void*)evalCertArray, 1, + &kCFTypeArrayCallBacks); if (!cfCertRef) { plog(LLV_ERROR, LOCATION, NULL, @@ -419,7 +550,7 @@ end: return status; } - +#if !TARGET_OS_EMBEDDED /* * Copy the system keychain */ @@ -444,7 +575,7 @@ end: return status; } - +#endif /* * Return string representation of Security-related OSStatus. @@ -465,6 +596,7 @@ GetSecurityErrorString(OSStatus err) /* SecBase.h: */ case errSecNotAvailable: return "errSecNotAvailable"; +#if !TARGET_OS_EMBEDDED case errSecReadOnly: return "errSecReadOnly"; case errSecAuthFailed: @@ -479,10 +611,6 @@ GetSecurityErrorString(OSStatus err) return "errSecDuplicateCallback"; case errSecInvalidCallback: return "errSecInvalidCallback"; - case errSecDuplicateItem: - return "errSecDuplicateItem"; - case errSecItemNotFound: - return "errSecItemNotFound"; case errSecBufferTooSmall: return "errSecBufferTooSmall"; case errSecDataTooLarge: @@ -529,6 +657,11 @@ GetSecurityErrorString(OSStatus err) return "errSecNoAccessForItem"; case errSecInvalidOwnerEdit: return "errSecInvalidOwnerEdit"; +#endif + case errSecDuplicateItem: + return "errSecDuplicateItem"; + case errSecItemNotFound: + return "errSecItemNotFound"; default: return ""; } diff --git a/ipsec-tools/racoon/crypto_cssm.h b/ipsec-tools/racoon/crypto_cssm.h index 6152770..e7c94c3 100644 --- a/ipsec-tools/racoon/crypto_cssm.h +++ b/ipsec-tools/racoon/crypto_cssm.h @@ -30,9 +30,10 @@ */ #include "vmbuf.h" +#include -extern int crypto_cssm_check_x509cert(vchar_t *cert); +extern int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname); extern vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash); extern vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef); diff --git a/ipsec-tools/racoon/crypto_openssl.c b/ipsec-tools/racoon/crypto_openssl.c index 39e96b7..ae184d7 100644 --- a/ipsec-tools/racoon/crypto_openssl.c +++ b/ipsec-tools/racoon/crypto_openssl.c @@ -1,4 +1,6 @@ -/* $Id: crypto_openssl.c,v 1.40.4.5 2005/07/12 11:50:15 manubsd Exp $ */ +/* $NetBSD: crypto_openssl.c,v 1.11.6.1 2006/12/18 10:18:10 vanhu Exp $ */ + +/* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -60,6 +62,7 @@ #ifdef __APPLE__ #include #include +#include #else #include #include @@ -141,7 +144,7 @@ eay_str2asn1dn(str, len) char *buf; char *field, *value; int i, j; - vchar_t *ret; + vchar_t *ret = NULL; caddr_t p; if (len == -1) @@ -149,7 +152,7 @@ eay_str2asn1dn(str, len) buf = racoon_malloc(len + 1); if (!buf) { - printf("failed to allocate buffer\n"); + plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n"); return NULL; } memcpy(buf, str, len); @@ -226,6 +229,8 @@ eay_str2asn1dn(str, len) racoon_free(buf); if (name) X509_NAME_free(name); + if (ret) + vfree(ret); return NULL; } @@ -253,7 +258,7 @@ eay_hex2asn1dn(const char *hex, int len) binlen = BN_num_bytes(bn); ret = vmalloc(binlen); if (!ret) { - printf("failed to allocate buffer\n"); + plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n"); return NULL; } binbuf = ret->v; @@ -502,7 +507,7 @@ eay_check_x509cert(cert, CApath, CAfile, local) end: if (error) - printf("%s\n", eay_strerror()); + plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror()); if (cert_ctx != NULL) X509_STORE_free(cert_ctx); if (x509 != NULL) @@ -606,37 +611,36 @@ eay_get_x509asn1subjectname(cert) u_char *bp; vchar_t *name = NULL; int len; - int error = -1; bp = (unsigned char *) cert->v; x509 = mem2x509(cert); if (x509 == NULL) - goto end; + goto error; /* get the length of the name */ len = i2d_X509_NAME(x509->cert_info->subject, NULL); name = vmalloc(len); if (!name) - goto end; + goto error; /* get the name */ bp = (unsigned char *) name->v; len = i2d_X509_NAME(x509->cert_info->subject, &bp); - error = 0; + X509_free(x509); - end: - if (error) { - plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); - if (name) { - vfree(name); - name = NULL; - } - } - if (x509) + return name; + +error: + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + + if (name != NULL) + vfree(name); + + if (x509 != NULL) X509_free(x509); - return name; + return NULL; } #ifdef __APPLE__ @@ -689,7 +693,7 @@ eay_get_x509subjectaltname(cert, altname, type, pos, len) { X509 *x509 = NULL; int i; - GENERAL_NAMES *gens; + GENERAL_NAMES *gens = NULL; GENERAL_NAME *gen; int error = -1; @@ -763,6 +767,9 @@ eay_get_x509subjectaltname(cert, altname, type, pos, len) printf("%s\n", eay_strerror()); #endif } + if (gens) + /* free the whole stack. */ + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); if (x509) X509_free(x509); @@ -1042,12 +1049,14 @@ eay_check_x509sign(source, sig, cert) evp = X509_get_pubkey(x509); if (! evp) { plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror()); + X509_free(x509); return -1; } res = eay_rsa_verify(source, sig, evp->pkey.rsa); EVP_PKEY_free(evp); + X509_free(x509); return res; } @@ -1389,6 +1398,45 @@ evp_keylen(int len, const EVP_CIPHER *e) return EVP_CIPHER_key_length(e) << 3; } +vchar_t * +eay_CCCrypt(CCOperation oper, + CCAlgorithm algo, + CCOptions opts, + vchar_t *data, + vchar_t *key, + vchar_t *iv) +{ + vchar_t *res; + size_t res_len = 0; + CCCryptorStatus status; + + /* allocate buffer for result */ + if ((res = vmalloc(data->l)) == NULL) + return NULL; + + status = CCCrypt(oper, + algo, + opts, + key->v, key->l, + iv->v, + data->v, data->l, + res->v, res->l, &res_len); + if (status == kCCSuccess) { + if (res->l != res_len) { + plog(LLV_ERROR, LOCATION, NULL, + "crypt %d %d length mismatch. expected: %zd. got: %zd.\n", + oper, algo, res->l, res_len); + } + return res; + } else { + plog(LLV_ERROR, LOCATION, NULL, + "crypt %d %d error. status %d.\n", + oper, algo, (int)status); + } + vfree(res); + return NULL; +} + /* * DES-CBC */ @@ -1396,14 +1444,22 @@ vchar_t * eay_des_encrypt(data, key, iv) vchar_t *data, *key, *iv; { +#ifdef __APPLE__ + return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv)); +#else return evp_crypt(data, key, iv, EVP_des_cbc(), 1); +#endif /* __APPLE__ */ } vchar_t * eay_des_decrypt(data, key, iv) vchar_t *data, *key, *iv; { +#ifdef __APPLE__ + return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv)); +#else return evp_crypt(data, key, iv, EVP_des_cbc(), 0); +#endif /* __APPLE__ */ } int @@ -1421,7 +1477,17 @@ int eay_des_keylen(len) int len; { +#ifdef __APPLE__ + /* CommonCrypto return lengths in bytes, ipsec-tools + * uses lengths in bits, therefore conversion is required. + */ + if (len != 0 && len != (kCCKeySizeDES << 3)) + return -1; + + return kCCKeySizeDES << 3; +#else return evp_keylen(len, EVP_des_cbc()); +#endif /* __APPLE__ */ } #ifdef HAVE_OPENSSL_IDEA_H @@ -1594,14 +1660,22 @@ vchar_t * eay_3des_encrypt(data, key, iv) vchar_t *data, *key, *iv; { +#ifdef __APPLE__ + return(eay_CCCrypt(kCCEncrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv)); +#else return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1); +#endif /* __APPLE__ */ } vchar_t * eay_3des_decrypt(data, key, iv) vchar_t *data, *key, *iv; { +#ifdef __APPLE__ + return(eay_CCCrypt(kCCDecrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv)); +#else return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0); +#endif /* __APPLE__ */ } int @@ -1626,9 +1700,19 @@ int eay_3des_keylen(len) int len; { +#ifdef __APPLE__ + /* CommonCrypto return lengths in bytes, ipsec-tools + * uses lengths in bits, therefore conversion is required. + */ + if (len != 0 && len != (kCCKeySize3DES << 3)) + return -1; + + return kCCKeySize3DES << 3; +#else if (len != 0 && len != 192) return -1; return 192; +#endif /* __APPLE__ */ } /* @@ -1669,6 +1753,41 @@ eay_cast_keylen(len) /* * AES(RIJNDAEL)-CBC */ +#ifdef __APPLE__ +vchar_t * +eay_aes_encrypt(data, key, iv) +vchar_t *data, *key, *iv; +{ + return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv)); +} + +vchar_t * +eay_aes_decrypt(data, key, iv) +vchar_t *data, *key, *iv; +{ + return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv)); +} + +int +eay_aes_keylen(len) +int len; +{ + /* CommonCrypto return lengths in bytes, ipsec-tools + * uses lengths in bits, therefore conversion is required. + */ + if (len != 0) { + if (len != (kCCKeySizeAES128 << 3) && + len != (kCCKeySizeAES192 << 3) && + len != (kCCKeySizeAES256 << 3)) + return -1; + } else { + return kCCKeySizeAES128 << 3; + } + return len; +} + +#else + #ifndef HAVE_OPENSSL_AES_H vchar_t * eay_aes_encrypt(data, key, iv) @@ -1761,14 +1880,7 @@ eay_aes_decrypt(data, key, iv) { return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0); } -#endif - -int -eay_aes_weakkey(key) - vchar_t *key; -{ - return 0; -} +#endif /* HAVE_OPENSSL_AES_H */ int eay_aes_keylen(len) @@ -1780,6 +1892,14 @@ eay_aes_keylen(len) return -1; return len; } +#endif /* __APPLE__ */ + +int +eay_aes_weakkey(key) + vchar_t *key; +{ + return 0; +} /* for ipsec part */ int @@ -2740,15 +2860,18 @@ base64_decode(char *in, long inlen) { BIO *bio=NULL, *b64=NULL; vchar_t *res = NULL; - char out[inlen*2]; + char *outb; long outlen; + outb = malloc(inlen * 2); + if (outb == NULL) + goto out; bio = BIO_new_mem_buf(in, inlen); b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bio = BIO_push(b64, bio); - outlen = BIO_read(bio, out, inlen * 2); + outlen = BIO_read(bio, outb, inlen * 2); if (outlen <= 0) { plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); goto out; @@ -2758,9 +2881,11 @@ base64_decode(char *in, long inlen) if (!res) goto out; - memcpy(res->v, out, outlen); + memcpy(res->v, outb, outlen); out: + if (outb) + free(outb); if (bio) BIO_free_all(bio); diff --git a/ipsec-tools/racoon/debugrm.h b/ipsec-tools/racoon/debugrm.h index 3dec6cd..960c3a5 100644 --- a/ipsec-tools/racoon/debugrm.h +++ b/ipsec-tools/racoon/debugrm.h @@ -47,6 +47,9 @@ #ifndef racoon_free #define racoon_free(p) free((p)) #endif +#ifndef racoon_strdup +#define racoon_strdup(p) strdup((p)) +#endif #else /*!NONEED_DRM*/ #ifndef racoon_malloc #define racoon_malloc(sz) \ @@ -64,6 +67,10 @@ #define racoon_free(p) \ DRM_free(__FILE__, __LINE__, __func__, (p)) #endif +#ifndef racoon_strdup +#define racoon_strdup(p) \ + DRM_strdup(__FILE__, __LINE__, __func__, (p)) +#endif #endif /*NONEED_DRM*/ extern void DRM_init __P((void)); @@ -72,6 +79,7 @@ extern void *DRM_malloc __P((char *, int, char *, size_t)); extern void *DRM_calloc __P((char *, int, char *, size_t, size_t)); extern void *DRM_realloc __P((char *, int, char *, void *, size_t)); extern void DRM_free __P((char *, int, char *, void *)); +extern char *DRM_strdup __P((char *, int, char *, const char *)); #ifndef NONEED_DRM #define vmalloc(sz) \ diff --git a/ipsec-tools/racoon/dnssec.c b/ipsec-tools/racoon/dnssec.c index 2f1dc25..bd4cd00 100644 --- a/ipsec-tools/racoon/dnssec.c +++ b/ipsec-tools/racoon/dnssec.c @@ -1,3 +1,5 @@ +/* $NetBSD: dnssec.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + /* $KAME: dnssec.c,v 1.2 2001/08/05 18:46:07 itojun Exp $ */ /* @@ -94,7 +96,7 @@ dnssec_getcert(id) "impropper ID type passed %s " "though getcert method is dnssec.\n", s_ipsecdoi_ident(id_b->type)); - return NULL; + goto err; } /* check response */ @@ -143,7 +145,10 @@ end: err: if (name) racoon_free(name); - if (cert) + if (cert) { oakley_delcert(cert); + cert = NULL; + } + goto end; } diff --git a/ipsec-tools/racoon/evt.c b/ipsec-tools/racoon/evt.c index e21a82b..fc65b20 100644 --- a/ipsec-tools/racoon/evt.c +++ b/ipsec-tools/racoon/evt.c @@ -1,4 +1,6 @@ -/* $Id: evt.c,v 1.2.4.1 2005/09/26 17:49:38 manubsd Exp $ */ +/* $NetBSD: evt.c,v 1.5 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -43,10 +45,11 @@ #include "vmbuf.h" #include "plog.h" #include "misc.h" +#include "admin.h" #include "gcmalloc.h" #include "evt.h" - +#ifdef ENABLE_ADMINPORT struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist); int evtlist_len = 0; @@ -61,6 +64,10 @@ evt_push(src, dst, type, optdata) struct evt *evt; size_t len; + /* If admin socket is disabled, silently discard anything */ + if (adminsock_path == NULL) + return; + /* If we are above the limit, don't record anything */ if (evtlist_len > EVTLIST_MAX) { plog(LLV_DEBUG, LOCATION, NULL, @@ -147,3 +154,5 @@ evt_dump(void) { return buf; } + +#endif /* ENABLE_ADMINPORT */ diff --git a/ipsec-tools/racoon/evt.h b/ipsec-tools/racoon/evt.h index 209c854..88ee366 100644 --- a/ipsec-tools/racoon/evt.h +++ b/ipsec-tools/racoon/evt.h @@ -1,4 +1,6 @@ -/* $Id: evt.h,v 1.3 2004/11/29 23:30:39 manubsd Exp $ */ +/* $NetBSD: evt.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: evt.h,v 1.5 2006/01/19 10:24:09 fredsen Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -59,6 +61,8 @@ struct evtdump { #define EVTT_XAUTH_FAILED 11 #define EVTT_OVERFLOW 12 /* Event queue overflowed */ #define EVTT_PEERPH1AUTH_FAILED 13 +#define EVTT_PEERPH1_NOPROP 14 /* NO_PROPOSAL_CHOSEN & friends */ +#define EVTT_NO_ISAKMP_CFG 15 /* no need to wait for mode_cfg */ struct evt { struct evtdump *dump; diff --git a/ipsec-tools/racoon/gcmalloc.h b/ipsec-tools/racoon/gcmalloc.h index ca08528..acdf7fa 100644 --- a/ipsec-tools/racoon/gcmalloc.h +++ b/ipsec-tools/racoon/gcmalloc.h @@ -1,3 +1,5 @@ +/* $NetBSD: gcmalloc.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + /* $KAME: gcmalloc.h,v 1.4 2001/11/16 04:34:57 sakane Exp $ */ /* @@ -77,12 +79,20 @@ free(void *ptr) GC_FREE(ptr); } + +char * +strdup(const char *str) +{ + + return (GC_STRDUP(str)); +} #endif /* RACOON_MAIN_PROGRAM */ #define racoon_malloc(sz) GC_debug_malloc(sz, GC_EXTRAS) #define racoon_calloc(cnt, sz) GC_debug_malloc(cnt * sz, GC_EXTRAS) #define racoon_realloc(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS) #define racoon_free(p) GC_debug_free(p) +#define racoon_strdup(str) GC_debug_strdup(str) #endif /* GC */ @@ -109,6 +119,9 @@ free(void *ptr) #ifndef racoon_free #define racoon_free(p) free((p)) #endif +#ifndef racoon_strdup +#define racoon_strdup(s) strdup((s)) +#endif #endif /* DEBUG_RECORD_MALLOCATION */ #endif /* _GCMALLOC_H_DEFINED */ diff --git a/ipsec-tools/racoon/getcertsbyname.c b/ipsec-tools/racoon/getcertsbyname.c index 890f067..6ce6be1 100644 --- a/ipsec-tools/racoon/getcertsbyname.c +++ b/ipsec-tools/racoon/getcertsbyname.c @@ -29,9 +29,6 @@ * SUCH DAMAGE. */ -//%%%HWR Do we need this? -#define BIND_8_COMPAT - #include "config.h" #include @@ -39,7 +36,7 @@ #include #include -#include +#include #include #ifdef HAVE_LWRES_GETRRSETBYNAME #include diff --git a/ipsec-tools/racoon/grabmyaddr.c b/ipsec-tools/racoon/grabmyaddr.c index 98f2d4c..6afc4ef 100644 --- a/ipsec-tools/racoon/grabmyaddr.c +++ b/ipsec-tools/racoon/grabmyaddr.c @@ -86,11 +86,7 @@ #ifndef HAVE_GETIFADDRS static unsigned int if_maxindex __P((void)); #endif -#ifdef __APPLE__ -static struct myaddrs *find_myaddr __P((struct myaddrs *, struct sockaddr *, int)); -#else -static struct myaddrs *find_myaddr __P((struct myaddrs *, struct myaddrs *)); -#endif + static int suitable_ifaddr __P((const char *, const struct sockaddr *)); #ifdef INET6 static int suitable_ifaddr6 __P((const char *, const struct sockaddr *)); @@ -300,9 +296,7 @@ clear_myaddr() for (p = lcconf->myaddrs; p; p = next) { next = p->next; - if (p->addr) - racoon_free(p->addr); - racoon_free(p); + delmyaddr(p); } lcconf->myaddrs = NULL; @@ -310,9 +304,8 @@ clear_myaddr() } -static struct myaddrs * -find_myaddr(db, addr, udp_encap) - struct myaddrs *db; +struct myaddrs * +find_myaddr(addr, udp_encap) struct sockaddr *addr; int udp_encap; { @@ -323,7 +316,7 @@ find_myaddr(db, addr, udp_encap) NI_NUMERICHOST | niflags) != 0) return NULL; - for (q = db; q; q = q->next) { + for (q = lcconf->myaddrs; q; q = q->next) { if (!q->addr) continue; if (q->udp_encap && !udp_encap @@ -379,18 +372,18 @@ grab_myaddrs() continue; if (!suitable_ifaddr(ifap->ifa_name, ifap->ifa_addr)) { - plog(LLV_ERROR, LOCATION, NULL, + plog(LLV_DEBUG2, LOCATION, NULL, "unsuitable address: %s %s\n", ifap->ifa_name, saddrwop2str(ifap->ifa_addr)); continue; } - p = find_myaddr(lcconf->myaddrs, ifap->ifa_addr, 0); + p = find_myaddr(ifap->ifa_addr, 0); if (p) { p->in_use = 1; #ifdef ENABLE_NATT - q = find_myaddr(lcconf->myaddrs, ifap->ifa_addr, 1); + q = find_myaddr(ifap->ifa_addr, 1); if (q) q->in_use = 1; #endif @@ -409,6 +402,14 @@ grab_myaddrs() exit(1); /*NOTREACHED*/ } + p->ifname = racoon_strdup(ifap->ifa_name); + if (p->ifname == NULL) { + plog(LLV_ERROR2, LOCATION, NULL, + "unable to duplicate ifname.\n"); + exit(1); + /*NOTREACHED*/ + } + p->sock = -1; p->in_use = 1; @@ -497,7 +498,7 @@ suitable_ifaddr6(ifname, ifaddr) } memset(&ifr6, 0, sizeof(ifr6)); - strncpy(ifr6.ifr_name, ifname, strlen(ifname)); + strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name)); ifr6.ifr_addr = *(const struct sockaddr_in6 *)ifaddr; @@ -678,6 +679,9 @@ newmyaddr() new->next = NULL; new->addr = NULL; +#ifdef __APPLE_ + new->ifname = NULL; +#endif return new; } @@ -703,6 +707,17 @@ dupmyaddr(struct myaddrs *old) racoon_free(new); return NULL; } + if (old->ifname) { + new->ifname = racoon_strdup(old->ifname); + if (new->ifname == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer for duplicate ifname.\n"); + racoon_free(new->addr); + racoon_free(new); + return NULL; + } + } + new->next = old->next; old->next = new; @@ -724,6 +739,10 @@ delmyaddr(myaddr) { if (myaddr->addr) racoon_free(myaddr->addr); +#ifdef __APPLE__ + if (myaddr->ifname) + racoon_free(myaddr->ifname); +#endif racoon_free(myaddr); } diff --git a/ipsec-tools/racoon/grabmyaddr.h b/ipsec-tools/racoon/grabmyaddr.h index a237cb5..22fc0a2 100644 --- a/ipsec-tools/racoon/grabmyaddr.h +++ b/ipsec-tools/racoon/grabmyaddr.h @@ -39,6 +39,7 @@ struct myaddrs { int udp_encap; #ifdef __APPLE__ int in_use; + char *ifname; #endif }; @@ -53,5 +54,7 @@ extern void insmyaddr __P((struct myaddrs *, struct myaddrs **)); extern void delmyaddr __P((struct myaddrs *)); extern int initmyaddr __P((void)); extern int getsockmyaddr __P((struct sockaddr *)); +extern struct myaddrs *find_myaddr __P((struct sockaddr *, int)); + #endif /* _GRABMYADDR_H */ diff --git a/ipsec-tools/racoon/gssapi.c b/ipsec-tools/racoon/gssapi.c index 0a11f83..a2cce3c 100644 --- a/ipsec-tools/racoon/gssapi.c +++ b/ipsec-tools/racoon/gssapi.c @@ -79,7 +79,7 @@ gssapi_error(OM_uint32 status_code, const char *where, va_list ap; va_start(ap, fmt); - plogv(LLV_ERROR, where, NULL, fmt, ap); + plogv(LLV_ERROR, where, NULL, fmt, &ap); va_end(ap); message_context = 0; @@ -153,6 +153,7 @@ gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service) { char name[NI_MAXHOST]; struct sockaddr *sa; + char* buf = NULL; gss_buffer_desc name_token; OM_uint32 min_stat, maj_stat; @@ -161,8 +162,9 @@ gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service) if (getnameinfo(sa, sysdep_sa_len(sa), name, NI_MAXHOST, NULL, 0, 0) != 0) return -1; - name_token.length = asprintf((char **)&name_token.value, - "%s@%s", GSSAPI_DEF_NAME, name); + name_token.length = asprintf(&buf, "%s@%s", GSSAPI_DEF_NAME, name); + name_token.value = buf; + maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, service); if (GSS_ERROR(maj_stat)) { @@ -288,7 +290,7 @@ gssapi_get_itoken(struct ph1handle *iph1, int *lenp) if (iph1->approval != NULL && iph1->approval->gssid != NULL) { plog(LLV_DEBUG, LOCATION, NULL, "using provided service '%.*s'\n", - iph1->approval->gssid->l, iph1->approval->gssid->v); + (int)iph1->approval->gssid->l, iph1->approval->gssid->v); name_token.length = iph1->approval->gssid->l; name_token.value = iph1->approval->gssid->v; maj_stat = gss_import_name(&min_stat, &name_token, @@ -466,7 +468,7 @@ gssapi_get_itokens(struct ph1handle *iph1, vchar_t **tokens) *tokens = toks; plog(LLV_DEBUG, LOCATION, NULL, - "%d itokens of length %d\n", gps->gsscnt, (*tokens)->l); + "%d itokens of length %zu\n", gps->gsscnt, (*tokens)->l); return 0; } @@ -547,7 +549,7 @@ gssapi_wraphash(struct ph1handle *iph1) return NULL; } - plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %d olen %d\n", + plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %zu olen %zu\n", hash_in->length, hash_out->length); maj_stat = gss_release_buffer(&min_stat, hash_in); @@ -589,7 +591,7 @@ gssapi_unwraphash(struct ph1handle *iph1) hashbuf.length = ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash); hashbuf.value = (char *)(iph1->pl_hash + 1); - plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %d\n", + plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %zu\n", hashbuf.length); maj_stat = gss_unwrap(&min_stat, gps->gss_context, hash_in, hash_out, diff --git a/ipsec-tools/racoon/handler.c b/ipsec-tools/racoon/handler.c index 4082bb5..a070970 100644 --- a/ipsec-tools/racoon/handler.c +++ b/ipsec-tools/racoon/handler.c @@ -1,4 +1,6 @@ -/* $Id: handler.c,v 1.13.4.4 2005/07/14 12:00:36 vanhu Exp $ */ +/* $NetBSD: handler.c,v 1.9.6.6 2007/06/06 09:20:12 vanhu Exp $ */ + +/* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -48,6 +50,10 @@ #include "sockmisc.h" #include "debug.h" +#ifdef ENABLE_HYBRID +#include +#endif + #include "schedule.h" #include "grabmyaddr.h" #include "algorithm.h" @@ -68,6 +74,9 @@ #include "handler.h" #include "gcmalloc.h" #include "nattraversal.h" +#include "ike_session.h" + +#include "sainfo.h" #ifdef HAVE_GSSAPI #include "gssapi.h" @@ -138,14 +147,24 @@ getph1byaddr(local, remote) { struct ph1handle *p; + plog(LLV_DEBUG2, LOCATION, NULL, "getph1byaddr: start\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "local: %s\n", saddr2str(local)); + plog(LLV_DEBUG2, LOCATION, NULL, "remote: %s\n", saddr2str(remote)); + LIST_FOREACH(p, &ph1tree, chain) { if (p->status == PHASE1ST_EXPIRED) continue; + plog(LLV_DEBUG2, LOCATION, NULL, "p->local: %s\n", saddr2str(p->local)); + plog(LLV_DEBUG2, LOCATION, NULL, "p->remote: %s\n", saddr2str(p->remote)); if (CMPSADDR(local, p->local) == 0 - && CMPSADDR(remote, p->remote) == 0) + && CMPSADDR(remote, p->remote) == 0){ + plog(LLV_DEBUG2, LOCATION, NULL, "matched\n"); return p; + } } + plog(LLV_DEBUG2, LOCATION, NULL, "no match\n"); + return NULL; } @@ -187,6 +206,24 @@ getph1bydstaddrwop(remote) return NULL; } +int +islast_ph1(ph1) + struct ph1handle *ph1; +{ + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->status == PHASE1ST_EXPIRED) + continue; + if (CMPSADDR(ph1->remote, p->remote) == 0) { + if (p == ph1) + continue; + return 0; + } + } + return 1; +} + /* * dump isakmp-sa */ @@ -246,9 +283,13 @@ newph1() iph1->dpd_lastack = 0; iph1->dpd_seq = 0; iph1->dpd_fails = 0; + iph1->peer_sent_ike = 0; iph1->dpd_r_u = NULL; #endif - +#ifdef ENABLE_VPNCONTROL_PORT + iph1->ping_sched = NULL; +#endif + iph1->is_dying = 0; return iph1; } @@ -259,9 +300,11 @@ void delph1(iph1) struct ph1handle *iph1; { + if (iph1 == NULL) + return; + /* SA down shell script hook */ - if (iph1 != NULL) - script_hook(iph1, SCRIPT_PHASE1_DOWN); + script_hook(iph1, SCRIPT_PHASE1_DOWN); EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL); @@ -276,10 +319,20 @@ delph1(iph1) } #endif +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg) + isakmp_cfg_rmstate(iph1); + VPTRINIT(iph1->xauth_awaiting_userinput_msg); +#endif + #ifdef ENABLE_DPD if (iph1->dpd_r_u != NULL) SCHED_KILL(iph1->dpd_r_u); #endif +#ifdef ENABLE_VPNCONTROL_PORT + if (iph1->ping_sched != NULL) + SCHED_KILL(iph1->ping_sched); +#endif if (iph1->remote) { racoon_free(iph1->remote); @@ -295,15 +348,11 @@ delph1(iph1) iph1->approval = NULL; } -#ifdef ENABLE_HYBRID - if (iph1->mode_cfg) - isakmp_cfg_rmstate(iph1); -#endif - VPTRINIT(iph1->authstr); sched_scrub_param(iph1); iph1->sce = NULL; + iph1->sce_rekey = NULL; iph1->scr = NULL; VPTRINIT(iph1->sendbuf); @@ -333,6 +382,9 @@ delph1(iph1) VPTRINIT(iph1->id); VPTRINIT(iph1->id_p); + if(iph1->approval != NULL) + delisakmpsa(iph1->approval); + if (iph1->ivm) { oakley_delivm(iph1->ivm); iph1->ivm = NULL; @@ -348,6 +400,16 @@ delph1(iph1) gssapi_free_state(iph1); #endif +#ifdef __APPLE__ + if (iph1->parent_session) { + ike_session_unlink_ph1_from_session(iph1); + } + if (iph1->rmconf) { + unlink_rmconf_from_ph1(iph1->rmconf); + iph1->rmconf = NULL; + } +#endif + racoon_free(iph1); } @@ -380,17 +442,30 @@ remph1(iph1) * flush isakmp-sa */ void -flushph1() +flushph1(int ignore_established_handles) { struct ph1handle *p, *next; - + for (p = LIST_FIRST(&ph1tree); p; p = next) { next = LIST_NEXT(p, chain); - + /* send delete information */ - if (p->status == PHASE1ST_ESTABLISHED) + if (p->status == PHASE1ST_ESTABLISHED) { + if (ignore_established_handles && + (ike_session_has_negoing_ph2(p->parent_session) || + p->mode_cfg->flags)) { + plog(LLV_DEBUG2, LOCATION, NULL, + "skipping ph1 handler that's established... because it's needed by children phase2s\n"); + continue; + } + /* send delete information */ + plog(LLV_DEBUG2, LOCATION, NULL, + "got a ph1 handler to flush...\n"); isakmp_info_send_d1(p); + } + ike_session_stopped_by_controller(p->parent_session, + ike_session_stopped_by_flush); remph1(p); delph1(p); } @@ -469,8 +544,21 @@ getph2byid(src, dst, spid) LIST_FOREACH(p, &ph2tree, chain) { if (spid == p->spid && CMPSADDR(src, p->src) == 0 && - CMPSADDR(dst, p->dst) == 0) - return p; + CMPSADDR(dst, p->dst) == 0){ + /* Sanity check to detect zombie handlers + * XXX Sould be done "somewhere" more interesting, + * because we have lots of getph2byxxxx(), but this one + * is called by pk_recvacquire(), so is the most important. + */ + if(p->status < PHASE2ST_ESTABLISHED && + p->retry_counter == 0 + && p->sce == NULL && p->scr == NULL){ + plog(LLV_DEBUG, LOCATION, NULL, + "Zombie ph2 found, expiring it\n"); + isakmp_ph2expire(p); + }else + return p; + } } return NULL; @@ -542,6 +630,7 @@ newph2() return NULL; iph2->status = PHASE1ST_SPAWN; + iph2->is_dying = 0; return iph2; } @@ -635,6 +724,16 @@ delph2(iph2) iph2->proposal = NULL; } +#ifdef __APPLE__ + if (iph2->parent_session) { + ike_session_unlink_ph2_from_session(iph2); + } + if (iph2->sainfo) { + unlink_sainfo_from_ph2(iph2->sainfo); + iph2->sainfo = NULL; + } +#endif + racoon_free(iph2); } @@ -664,17 +763,33 @@ initph2tree() } void -flushph2() +flushph2(int ignore_established_handles) { struct ph2handle *p, *next; + plog(LLV_DEBUG2, LOCATION, NULL, + "flushing all ph2 handlers...\n"); + for (p = LIST_FIRST(&ph2tree); p; p = next) { next = LIST_NEXT(p, chain); - - /* send delete information */ - if (p->status == PHASE2ST_ESTABLISHED) + + if (p->status == PHASE2ST_ESTABLISHED){ + if (ignore_established_handles) { + plog(LLV_DEBUG2, LOCATION, NULL, + "skipping ph2 handler that's established...\n"); + continue; + } + /* send delete information */ + plog(LLV_DEBUG2, LOCATION, NULL, + "got an established ph2 handler to flush...\n"); isakmp_info_send_d2(p); - + }else{ + plog(LLV_DEBUG2, LOCATION, NULL, + "got a ph2 handler to flush (state %d)\n", p->status); + } + + ike_session_stopped_by_controller(p->parent_session, + ike_session_stopped_by_flush); delete_spd(p); unbindph12(p); remph2(p); @@ -699,7 +814,11 @@ deleteallph2(src, dst, proto_id) next = LIST_NEXT(iph2, chain); if (iph2->proposal == NULL && iph2->approval == NULL) continue; - if (iph2->approval != NULL) { + if (cmpsaddrwop(src, iph2->src) != 0 || + cmpsaddrwop(dst, iph2->dst) != 0) { + continue; + } + if (iph2->approval != NULL) { for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { if (proto_id == pr->proto_id) @@ -714,18 +833,54 @@ deleteallph2(src, dst, proto_id) } continue; zap_it: + plog(LLV_DEBUG2, LOCATION, NULL, + "deleteallph2: got a ph2 handler...\n"); + if (iph2->status == PHASE2ST_ESTABLISHED) + isakmp_info_send_d2(iph2); + ike_session_stopped_by_controller(iph2->parent_session, + ike_session_stopped_by_flush); unbindph12(iph2); remph2(iph2); delph2(iph2); } } +/* + * Delete all Phase 1 handlers for this src/dst. + */ +void +deleteallph1(src, dst) +struct sockaddr *src, *dst; +{ + struct ph1handle *iph1, *next; + + for (iph1 = LIST_FIRST(&ph1tree); iph1 != NULL; iph1 = next) { + next = LIST_NEXT(iph1, chain); + if (cmpsaddrwop(src, iph1->local) != 0 || + cmpsaddrwop(dst, iph1->remote) != 0) { + continue; + } + plog(LLV_DEBUG2, LOCATION, NULL, + "deleteallph1: got a ph1 handler...\n"); + if (iph1->status == PHASE2ST_ESTABLISHED) + isakmp_info_send_d1(iph1); + + ike_session_stopped_by_controller(iph1->parent_session, + ike_session_stopped_by_flush); + remph1(iph1); + delph1(iph1); + } +} + /* %%% */ void bindph12(iph1, iph2) struct ph1handle *iph1; struct ph2handle *iph2; { + if (iph2->ph1 && (struct ph1handle *)iph2->ph1bind.le_next == iph1) { + plog(LLV_ERROR, LOCATION, NULL, "duplicate %s.\n", __FUNCTION__); + } iph2->ph1 = iph1; LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind); } @@ -735,11 +890,37 @@ unbindph12(iph2) struct ph2handle *iph2; { if (iph2->ph1 != NULL) { + plog(LLV_DEBUG, LOCATION, NULL, "unbindph12.\n"); iph2->ph1 = NULL; LIST_REMOVE(iph2, ph1bind); } } +void +rebindph12(new_ph1, iph2) +struct ph1handle *new_ph1; +struct ph2handle *iph2; +{ + if (!new_ph1) { + return; + } + + // reconcile the ph1-to-ph2 binding + plog(LLV_DEBUG, LOCATION, NULL, "rebindph12.\n"); + unbindph12(iph2); + bindph12(new_ph1, iph2); + // recalculate ivm since ph1 binding has changed + if (iph2->ivm != NULL) { + oakley_delivm(iph2->ivm); + if (new_ph1->status == PHASE1ST_ESTABLISHED) { + iph2->ivm = oakley_newiv2(new_ph1, iph2->msgid); + plog(LLV_DEBUG, LOCATION, NULL, "ph12 binding changed... recalculated ivm.\n"); + } else { + iph2->ivm = NULL; + } + } +} + /* %%% management contacted list */ /* * search contacted list. @@ -773,6 +954,12 @@ inscontacted(remote) return -1; new->remote = dupsaddr(remote); + if (new->remote == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + racoon_free(new); + return -1; + } LIST_INSERT_HEAD(&ctdtree, new, chain); @@ -840,9 +1027,11 @@ check_recvdpkt(remote, local, rbuf) /* * the packet was processed before, but the remote address mismatches. + * ignore the port to accomodate port changes (e.g. floating). */ - if (cmpsaddrstrict(remote, r->remote) != 0) - return 2; + if (cmpsaddrwop(remote, r->remote) != 0) { + return 2; + } /* * it should not check the local address because the packet @@ -888,9 +1077,10 @@ check_recvdpkt(remote, local, rbuf) * adding a hash of received packet into the received list. */ int -add_recvdpkt(remote, local, sbuf, rbuf) +add_recvdpkt(remote, local, sbuf, rbuf, non_esp) struct sockaddr *remote, *local; vchar_t *sbuf, *rbuf; + size_t non_esp; { struct recvdpkt *new = NULL; @@ -927,13 +1117,30 @@ add_recvdpkt(remote, local, sbuf, rbuf) del_recvdpkt(new); return -1; } - new->sendbuf = vdup(sbuf); - if (new->sendbuf == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to allocate buffer.\n"); - del_recvdpkt(new); - return -1; - } + + if (non_esp) { + plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n"); + + /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker) + must added just before the packet itself. For this we must + allocate a new buffer and release it at the end. */ + if ((new->sendbuf = vmalloc (sbuf->l + non_esp)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate extra buf for non-esp\n"); + del_recvdpkt(new); + return -1; + } + *(u_int32_t *)new->sendbuf->v = 0; + memcpy(new->sendbuf->v + non_esp, sbuf->v, sbuf->l); + } else { + new->sendbuf = vdup(sbuf); + if (new->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate buffer.\n"); + del_recvdpkt(new); + return -1; + } + } new->retry_counter = lcconf->retry_counter; new->time_send = 0; @@ -1038,3 +1245,129 @@ exclude_cfg_addr(addr) return 1; } #endif + +#ifdef ENABLE_HYBRID +struct ph1handle * +getph1bylogin(login) + char *login; +{ + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->mode_cfg == NULL) + continue; + if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) + return p; + } + + return NULL; +} + +int +purgeph1bylogin(login) + char *login; +{ + struct ph1handle *p; + int found = 0; + + LIST_FOREACH(p, &ph1tree, chain) { + if (p->mode_cfg == NULL) + continue; + if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) { + if (p->status == PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(p); + purge_remote(p); + found++; + } + } + + return found; +} + +int +purgephXbydstaddrwop(remote) +struct sockaddr *remote; +{ + int found = 0; + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (cmpsaddrwop(remote, p->remote) == 0) { + plog(LLV_WARNING, LOCATION, NULL, + "in %s... purging phase1 and related phase2s\n", __FUNCTION__); + ike_session_purge_ph2s_by_ph1(p); + if (p->status == PHASE1ST_ESTABLISHED) + isakmp_info_send_d1(p); + isakmp_ph1expire(p); + found++; + } + } + + return found; +} + +void +purgephXbyspid(u_int32_t spid, + int del_boundph1) +{ + struct ph2handle *iph2; + struct ph1handle *iph1; + + // do ph2's first... we need the ph1s for notifications + LIST_FOREACH(iph2, &ph2tree, chain) { + if (spid == iph2->spid) { + if (iph2->status == PHASE2ST_ESTABLISHED) { + isakmp_info_send_d2(iph2); + } + isakmp_ph2expire(iph2); // iph2 will go down 1 second later. + ike_session_stopped_by_controller(iph2->parent_session, + ike_session_stopped_by_flush); + } + } + + // do the ph1s last. + LIST_FOREACH(iph2, &ph2tree, chain) { + if (spid == iph2->spid) { + if (del_boundph1 && iph2->parent_session) { + for (iph1 = LIST_FIRST(&iph2->parent_session->ikev1_state.ph1tree); iph1; iph1 = LIST_NEXT(iph1, ph1ofsession_chain)) { + if (iph1->status == PHASE1ST_ESTABLISHED) { + isakmp_info_send_d1(iph1); + } + isakmp_ph1expire(iph1); + } + } + } + } +} + +#endif + +#ifdef ENABLE_DPD +int +ph1_force_dpd (struct sockaddr *remote) +{ + int status = -1; + struct ph1handle *p; + + LIST_FOREACH(p, &ph1tree, chain) { + if (cmpsaddrwop(remote, p->remote) == 0) { + if (p->status == PHASE1ST_ESTABLISHED && + !p->is_dying && + p->dpd_support && + p->rmconf->dpd_interval) { + if(!p->dpd_fails) { + isakmp_info_send_r_u(p); + status = 0; + } else { + plog(LLV_DEBUG2, LOCATION, NULL, "skipping forced-DPD for phase1 (dpd already in progress).\n"); + } + } else { + plog(LLV_DEBUG2, LOCATION, NULL, "skipping forced-DPD for phase1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n", + p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval); + } + } + } + + return status; +} +#endif diff --git a/ipsec-tools/racoon/handler.h b/ipsec-tools/racoon/handler.h index 2d5bfb4..9dcfdbd 100644 --- a/ipsec-tools/racoon/handler.h +++ b/ipsec-tools/racoon/handler.h @@ -1,4 +1,6 @@ -/* $Id: handler.h,v 1.11.4.3 2005/05/07 17:26:05 manubsd Exp $ */ +/* $NetBSD: handler.h,v 1.9 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -40,6 +42,8 @@ #include "isakmp_var.h" #include "oakley.h" +typedef struct ike_session ike_session_t; + /* Phase 1 handler */ /* * main mode: @@ -112,6 +116,7 @@ struct ph1handle { int status; /* status of this SA */ int side; /* INITIATOR or RESPONDER */ + int started_by_api; /* connection started by VPNControl API */ struct sockaddr *remote; /* remote address to negosiate ph1 */ struct sockaddr *local; /* local address to negosiate ph1 */ @@ -128,15 +133,18 @@ struct ph1handle { u_int8_t etype; /* Exchange type actually for use */ u_int8_t flags; /* Flags */ u_int32_t msgid; /* message id */ - + +#ifdef ENABLE_NATT struct ph1natt_options *natt_options; /* Selected NAT-T IKE version */ u_int32_t natt_flags; /* NAT-T related flags */ +#endif #ifdef ENABLE_FRAG int frag; /* IKE phase 1 fragmentation */ struct isakmp_frag_item *frag_chain; /* Received fragments */ #endif struct sched *sce; /* schedule for expire */ + struct sched *sce_rekey; /* schedule for rekey */ struct sched *scr; /* schedule for resend */ int retry_counter; /* for resend. */ @@ -165,7 +173,7 @@ struct ph1handle { struct genlist *rsa_candidates; /* possible candidates for peer's RSA key */ vchar_t *id; /* ID minus gen header */ vchar_t *id_p; /* partner's ID minus general header */ - /* i.e. strut ipsecdoi_id_b*. */ + /* i.e. struct ipsecdoi_id_b*. */ struct isakmp_ivm *ivm; /* IVs */ vchar_t *sa; /* whole SA payload to send/to be sent*/ @@ -191,12 +199,19 @@ struct ph1handle { struct timeval end; #endif +#ifdef ENABLE_DPD int dpd_support; /* Does remote supports DPD ? */ time_t dpd_lastack; /* Last ack received */ u_int16_t dpd_seq; /* DPD seq number to receive */ u_int8_t dpd_fails; /* number of failures */ + u_int8_t peer_sent_ike; struct sched *dpd_r_u; +#endif +#ifdef ENABLE_VPNCONTROL_PORT + struct sched *ping_sched; /* for sending pings to keep FW open */ +#endif + u_int32_t msgid2; /* msgid counter for Phase 2 */ int ph2cnt; /* the number which is negotiated by this phase 1 */ LIST_HEAD(_ph2ofph1_, ph2handle) ph2tree; @@ -204,8 +219,16 @@ struct ph1handle { LIST_ENTRY(ph1handle) chain; #ifdef ENABLE_HYBRID struct isakmp_cfg_state *mode_cfg; /* ISAKMP mode config state */ -#endif - + u_int8_t pended_xauth_id; /* saved id for reply from vpn control socket */ + u_int8_t xauth_awaiting_userinput; /* indicates we are waiting for user input */ + vchar_t *xauth_awaiting_userinput_msg; /* tracks the last packet that triggered XAUTH */ +#endif +#ifdef __APPLE__ + int is_rekey:1; + int is_dying:1; + ike_session_t *parent_session; + LIST_ENTRY(ph1handle) ph1ofsession_chain; +#endif }; /* Phase 2 handler */ @@ -311,7 +334,13 @@ struct ph2handle { struct timeval end; #endif struct ph1handle *ph1; /* back pointer to isakmp status */ - +#ifdef __APPLE__ + int is_rekey:1; + int is_dying:1; + ike_session_t *parent_session; + LIST_ENTRY(ph2handle) ph2ofsession_chain; +#endif + LIST_ENTRY(ph2handle) chain; LIST_ENTRY(ph2handle) ph1bind; /* chain to ph1handle */ }; @@ -424,12 +453,21 @@ extern struct ph1handle *getph1byaddr __P((struct sockaddr *, extern struct ph1handle *getph1byaddrwop __P((struct sockaddr *, struct sockaddr *)); extern struct ph1handle *getph1bydstaddrwop __P((struct sockaddr *)); +extern int islast_ph1 __P((struct ph1handle *)); + struct ph1handle *ph1; +#ifdef ENABLE_HYBRID +struct ph1handle *getph1bylogin __P((char *)); +int purgeph1bylogin __P((char *)); +#endif +extern int purgephXbydstaddrwop __P((struct sockaddr *)); +extern void purgephXbyspid __P((u_int32_t, int)); + extern vchar_t *dumpph1 __P((void)); extern struct ph1handle *newph1 __P((void)); extern void delph1 __P((struct ph1handle *)); extern int insph1 __P((struct ph1handle *)); extern void remph1 __P((struct ph1handle *)); -extern void flushph1 __P((void)); +extern void flushph1 __P((int)); extern void initph1tree __P((void)); extern struct ph2handle *getph2byspidx __P((struct policyindex *)); @@ -447,12 +485,14 @@ extern void initph2 __P((struct ph2handle *)); extern void delph2 __P((struct ph2handle *)); extern int insph2 __P((struct ph2handle *)); extern void remph2 __P((struct ph2handle *)); -extern void flushph2 __P((void)); +extern void flushph2 __P((int)); extern void deleteallph2 __P((struct sockaddr *, struct sockaddr *, u_int)); +extern void deleteallph1 __P((struct sockaddr *, struct sockaddr *)); extern void initph2tree __P((void)); extern void bindph12 __P((struct ph1handle *, struct ph2handle *)); extern void unbindph12 __P((struct ph2handle *)); +extern void rebindph12 __P((struct ph1handle *, struct ph2handle *)); extern struct contacted *getcontacted __P((struct sockaddr *)); extern int inscontacted __P((struct sockaddr *)); @@ -462,7 +502,7 @@ extern void initctdtree __P((void)); extern int check_recvdpkt __P((struct sockaddr *, struct sockaddr *, vchar_t *)); extern int add_recvdpkt __P((struct sockaddr *, struct sockaddr *, - vchar_t *, vchar_t *)); + vchar_t *, vchar_t *, size_t)); extern void clear_recvdpkt __P((void)); extern void init_recvdpkt __P((void)); @@ -470,4 +510,8 @@ extern void init_recvdpkt __P((void)); extern int exclude_cfg_addr __P((const struct sockaddr *)); #endif +#ifdef ENABLE_DPD +extern int ph1_force_dpd __P((struct sockaddr *)); +#endif + #endif /* _HANDLER_H */ diff --git a/ipsec-tools/racoon/ike_session.c b/ipsec-tools/racoon/ike_session.c new file mode 100644 index 0000000..4f688bf --- /dev/null +++ b/ipsec-tools/racoon/ike_session.c @@ -0,0 +1,1355 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" + +#include "isakmp_var.h" +#include "isakmp.h" +#include "ike_session.h" +#include "handler.h" +#include "gcmalloc.h" +#include "nattraversal.h" +#include "schedule.h" +#include "pfkey.h" +#include "ipsec_doi.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" +#include "isakmp_inf.h" +#include "localconf.h" +#include "remoteconf.h" +#include "vpn_control.h" + +const char *ike_session_stopped_by_vpn_disconnect = "Stopped by VPN disconnect"; +const char *ike_session_stopped_by_flush = "Stopped by Flush"; +const char *ike_session_stopped_by_idle = "Stopped by Idle"; +const char *ike_session_stopped_by_xauth_timeout = "Stopped by XAUTH timeout"; + +static LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree; + +static ike_session_t * +new_ike_session (ike_session_id_t *id) +{ + ike_session_t *session; + + if (!id) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return NULL; + } + + plog(LLV_DEBUG, LOCATION, NULL, "new parent session.\n"); + session = racoon_calloc(1, sizeof(*session)); + if (session) { + bzero(session, sizeof(*session)); + memcpy(&session->session_id, id, sizeof(*id)); + LIST_INIT(&session->ikev1_state.ph1tree); + LIST_INIT(&session->ikev1_state.ph2tree); + LIST_INSERT_HEAD(&ike_session_tree, session, chain); + session->version = IKE_VERSION_1; // hard-coded for now + IPSECSESSIONTRACERSTART(session); + } + return session; +} + +static void +free_ike_session (ike_session_t *session) +{ + int is_failure = TRUE; + if (session) { + SCHED_KILL(session->traffic_monitor.sc_mon); + SCHED_KILL(session->traffic_monitor.sc_idle); + SCHED_KILL(session->sc_xauth); + if (session->start_timestamp.tv_sec || session->start_timestamp.tv_usec) { + if (!(session->stop_timestamp.tv_sec || session->start_timestamp.tv_usec)) { + gettimeofday(&session->stop_timestamp, NULL); + } + if (session->term_reason != ike_session_stopped_by_vpn_disconnect || + session->term_reason != ike_session_stopped_by_flush || + session->term_reason != ike_session_stopped_by_idle) { + is_failure = FALSE; + } + IPSECSESSIONTRACERSTOP(session, + is_failure, + session->term_reason); + } + // do MessageTracer cleanup here + plog(LLV_DEBUG, LOCATION, NULL, + "Freeing IKE-Session to %s.\n", + saddr2str((struct sockaddr *)&session->session_id.remote)); + LIST_REMOVE(session, chain); + racoon_free(session); + } +} + +struct ph1handle * +ike_session_get_established_or_negoing_ph1 (ike_session_t *session) +{ + struct ph1handle *p, *iph1 = NULL; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return NULL; + } + + // look for the most mature ph1 under the session + for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) { + if (!p->is_dying && p->status >= PHASE1ST_START && p->status <= PHASE1ST_ESTABLISHED) { + if (!iph1 || p->status > iph1->status) { + iph1 = p; + } else if (iph1 && p->status == iph1->status) { + // TODO: pick better one based on farthest rekey/expiry remaining + } + } + } + + return iph1; +} + +struct ph1handle * +ike_session_get_established_ph1 (ike_session_t *session) +{ + struct ph1handle *p; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return NULL; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) { + if (!p->is_dying && p->status == PHASE1ST_ESTABLISHED) { + return p; + } + } + + return NULL; +} + +void +ike_session_init (void) +{ + LIST_INIT(&ike_session_tree); +} + +u_int +ike_session_get_rekey_lifetime (int local_spi_is_higher, u_int expiry_lifetime) +{ + u_int rekey_lifetime = expiry_lifetime / 10; + + if (rekey_lifetime) { + if (local_spi_is_higher) { + return (rekey_lifetime * 9); + } else { + return (rekey_lifetime * 8); + } + } else { + if (local_spi_is_higher) { + rekey_lifetime = expiry_lifetime - 1; + } else { + rekey_lifetime = expiry_lifetime - 2; + } + } + if (rekey_lifetime < expiry_lifetime) { + return (rekey_lifetime); + } + return(0); +} + +// TODO: optimize this mess later +ike_session_t * +ike_session_get_session (struct sockaddr *local, + struct sockaddr *remote, + int alloc_if_absent) +{ + ike_session_t *p; + ike_session_id_t id; + ike_session_id_t id_default; + ike_session_id_t id_floated_default; + ike_session_id_t id_wop; + ike_session_t *best_match = NULL; + u_int16_t remote_port; + int is_isakmp_remote_port; + + if (!local || !remote) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return NULL; + } + + remote_port = extract_port(remote); + if (remote_port && remote_port != PORT_ISAKMP && remote_port != PORT_ISAKMP_NATT) { + is_isakmp_remote_port = 0; + } else { + is_isakmp_remote_port = 1; + } + + /* we will try a couple of matches first: if the exact id isn't found, then we'll try for an id that has zero'd ports */ + bzero(&id, sizeof(id)); + bzero(&id_default, sizeof(id_default)); + bzero(&id_floated_default, sizeof(id_floated_default)); + bzero(&id_wop, sizeof(id_wop)); + if (local->sa_family == AF_INET) { + memcpy(&id.local, local, sizeof(struct sockaddr_in)); + memcpy(&id_default.local, local, sizeof(struct sockaddr_in)); + memcpy(&id_floated_default.local, local, sizeof(struct sockaddr_in)); + memcpy(&id_wop.local, local, sizeof(struct sockaddr_in)); + } else if (local->sa_family == AF_INET6) { + memcpy(&id.local, local, sizeof(struct sockaddr_in6)); + memcpy(&id_default.local, local, sizeof(struct sockaddr_in6)); + memcpy(&id_floated_default.local, local, sizeof(struct sockaddr_in6)); + memcpy(&id_wop.local, local, sizeof(struct sockaddr_in6)); + } + set_port((struct sockaddr *)&id_default.local, PORT_ISAKMP); + set_port((struct sockaddr *)&id_floated_default.local, PORT_ISAKMP_NATT); + set_port((struct sockaddr *)&id_wop.local, 0); + if (remote->sa_family == AF_INET) { + memcpy(&id.remote, remote, sizeof(struct sockaddr_in)); + memcpy(&id_default.remote, remote, sizeof(struct sockaddr_in)); + memcpy(&id_floated_default.remote, remote, sizeof(struct sockaddr_in)); + memcpy(&id_wop.remote, remote, sizeof(struct sockaddr_in)); + } else if (remote->sa_family == AF_INET6) { + memcpy(&id.remote, remote, sizeof(struct sockaddr_in6)); + memcpy(&id_default.remote, remote, sizeof(struct sockaddr_in6)); + memcpy(&id_floated_default.remote, remote, sizeof(struct sockaddr_in6)); + memcpy(&id_wop.remote, remote, sizeof(struct sockaddr_in6)); + } + set_port((struct sockaddr *)&id_default.remote, PORT_ISAKMP); + set_port((struct sockaddr *)&id_floated_default.remote, PORT_ISAKMP_NATT); + set_port((struct sockaddr *)&id_wop.remote, 0); + + plog(LLV_DEBUG, LOCATION, local, + "start search for IKE-Session. target %s.\n", + saddr2str(remote)); + + for (p = LIST_FIRST(&ike_session_tree); p; p = LIST_NEXT(p, chain)) { + plog(LLV_DEBUG, LOCATION, local, + "still search for IKE-Session. this %s.\n", + saddr2str((struct sockaddr *)&p->session_id.remote)); + + if (memcmp(&p->session_id, &id, sizeof(id)) == 0) { + plog(LLV_DEBUG, LOCATION, local, + "Pre-existing IKE-Session to %s. case 1.\n", + saddr2str(remote)); + return p; + } else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_default, sizeof(id_default)) == 0) { + plog(LLV_DEBUG, LOCATION, local, + "Pre-existing IKE-Session to %s. case 2.\n", + saddr2str(remote)); + return p; + } else if (is_isakmp_remote_port && p->ports_floated && memcmp(&p->session_id, &id_floated_default, sizeof(id_floated_default)) == 0) { + plog(LLV_DEBUG, LOCATION, local, + "Pre-existing IKE-Session to %s. case 3.\n", + saddr2str(remote)); + return p; + } else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_wop, sizeof(id_wop)) == 0) { + best_match = p; + } + } + if (best_match) { + plog(LLV_DEBUG, LOCATION, local, + "Best-match IKE-Session to %s.\n", + saddr2str((struct sockaddr *)&best_match->session_id.remote)); + return best_match; + } + if (alloc_if_absent) { + plog(LLV_DEBUG, LOCATION, local, + "New IKE-Session to %s.\n", + saddr2str((struct sockaddr *)&id.remote)); + return new_ike_session(&id); + } else { + return NULL; + } +} + +void +ike_session_init_traffic_cop_params (struct ph1handle *iph1) +{ + if (!iph1 || + !iph1->rmconf || + (!iph1->rmconf->idle_timeout && !iph1->rmconf->dpd_interval)) { + return; + } + + if (!iph1->parent_session->traffic_monitor.interv_idle) { + iph1->parent_session->traffic_monitor.interv_idle = iph1->rmconf->idle_timeout; + } + if (!iph1->parent_session->traffic_monitor.dir_idle) { + iph1->parent_session->traffic_monitor.dir_idle = iph1->rmconf->idle_timeout_dir; + } + + if (!iph1->parent_session->traffic_monitor.interv_mon) { + int min_period, max_period, sample_period = 0; + + /* calculate the sampling interval... half the smaller interval */ + if (iph1->rmconf->dpd_interval && + (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT || + iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT)) { + // when certain types of dpd are enabled + min_period = MIN(iph1->rmconf->dpd_interval, iph1->rmconf->idle_timeout); + max_period = MAX(iph1->rmconf->dpd_interval, iph1->rmconf->idle_timeout); + } else if (iph1->rmconf->idle_timeout) { + min_period = max_period = MIN(0, iph1->rmconf->idle_timeout); + } else { + // DPD_ALGO_DEFAULT is configured and there's no idle timeout... we don't need to monitor traffic + return; + } + if (min_period) { + sample_period = min_period >> 1; + if (!sample_period) + sample_period = 1; // bad + } else { + sample_period = max_period >> 1; + if (!sample_period) + sample_period = 1; // bad + } + iph1->parent_session->traffic_monitor.interv_mon = sample_period; + } +} + +int +ike_session_link_ph1_to_session (struct ph1handle *iph1) +{ + ike_session_t *session; + + if (!iph1) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return -1; + } + + session = ike_session_get_session(iph1->local, iph1->remote, TRUE); + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "failed to get session in %s.\n", __FUNCTION__); + return -1; + } + + // already linked + if (iph1->parent_session) { + if (session == iph1->parent_session) { + return 0; + } + // undo previous session + if (ike_session_unlink_ph1_from_session(iph1) == 0) { + plog(LLV_DEBUG2, LOCATION, NULL, "failed to unlink ph1 in %s.\n", __FUNCTION__); + free_ike_session(session); + return -1; + } + } else { + gettimeofday(&session->start_timestamp, NULL); + } + + + if (iph1->started_by_api) { + session->is_cisco_ipsec = 1; + session->is_l2tpvpn_ipsec = 0; + session->is_btmm_ipsec = 0; + } + iph1->parent_session = session; + LIST_INSERT_HEAD(&session->ikev1_state.ph1tree, iph1, ph1ofsession_chain); + session->ikev1_state.active_ph1cnt++; + if ((!session->ikev1_state.ph1cnt && + iph1->side == INITIATOR) || + iph1->started_by_api) { + // client initiates the first phase1 or, is started by controller api + session->is_client = 1; + } + if (session->established && + session->ikev1_state.ph1cnt) { + iph1->is_rekey = 1; + } + session->ikev1_state.ph1cnt++; + ike_session_init_traffic_cop_params(iph1); + + return 0; +} + +void +ike_session_update_mode (struct ph2handle *iph2) +{ + if (!iph2 || !iph2->parent_session) { + return; + } + + // exit early if we already detected cisco-ipsec + if (iph2->parent_session->is_cisco_ipsec) { + return; + } + + if (iph2->approval) { + if (!ipsecdoi_any_transportmode(iph2->approval)) { + // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1) + iph2->parent_session->is_cisco_ipsec = 0; + iph2->parent_session->is_l2tpvpn_ipsec = 0; + iph2->parent_session->is_btmm_ipsec = 1; + return; + } else if (ipsecdoi_transportmode(iph2->approval)) { + iph2->parent_session->is_cisco_ipsec = 0; + iph2->parent_session->is_l2tpvpn_ipsec = 1; + iph2->parent_session->is_btmm_ipsec = 0; + return; + } + } else if (iph2->proposal) { + if (!ipsecdoi_any_transportmode(iph2->proposal)) { + // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1) + iph2->parent_session->is_cisco_ipsec = 0; + iph2->parent_session->is_l2tpvpn_ipsec = 0; + iph2->parent_session->is_btmm_ipsec = 1; + return; + } else if (ipsecdoi_transportmode(iph2->proposal)) { + iph2->parent_session->is_cisco_ipsec = 0; + iph2->parent_session->is_l2tpvpn_ipsec = 1; + iph2->parent_session->is_btmm_ipsec = 0; + return; + } + } +} + +static void +ike_session_cleanup_xauth_timeout (void *arg) +{ + ike_session_t *session = (ike_session_t *)arg; + + SCHED_KILL(session->sc_xauth); + // if there are no more established ph2s, start a timer to teardown the session + if (!ike_session_has_established_ph2(session)) { + ike_session_cleanup(session, ike_session_stopped_by_xauth_timeout); + } else { + session->sc_xauth = sched_new(300 /* 5 mins */, + ike_session_cleanup_xauth_timeout, + session); + } +} + +int +ike_session_link_ph2_to_session (struct ph2handle *iph2) +{ + struct sockaddr *local; + struct sockaddr *remote; + ike_session_t *session; + + if (!iph2) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return -1; + } + + local = iph2->src; + remote = iph2->dst; + + session = ike_session_get_session(local, remote, TRUE); + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "failed to get session in %s.\n", __FUNCTION__); + return -1; + } + + // already linked + if (iph2->parent_session) { + if (session == iph2->parent_session) { + return 0; + } + // undo previous session + if (ike_session_unlink_ph2_from_session(iph2) == 0) { + plog(LLV_DEBUG2, LOCATION, NULL, "failed to unlink ph2 in %s.\n", __FUNCTION__); + free_ike_session(session); + return -1; + } + } + + iph2->parent_session = session; + LIST_INSERT_HEAD(&session->ikev1_state.ph2tree, iph2, ph2ofsession_chain); + session->ikev1_state.active_ph2cnt++; + if (!session->ikev1_state.ph2cnt && + iph2->side == INITIATOR) { + // client initiates the first phase2 + session->is_client = 1; + } + if (session->established && + session->ikev1_state.ph2cnt) { + iph2->is_rekey = 1; + } + session->ikev1_state.ph2cnt++; + + ike_session_update_mode(iph2); + + return 0; +} + +int +ike_session_unlink_ph1_from_session (struct ph1handle *iph1) +{ + ike_session_t *session; + + if (!iph1 || !iph1->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return -1; + } + + if (LIST_FIRST(&iph1->ph2tree)) { + // reparent any phase2 that may be hanging on to this phase1 + ike_session_update_ph1_ph2tree(iph1); + } + + session = iph1->parent_session; + LIST_REMOVE(iph1, ph1ofsession_chain); + iph1->parent_session = NULL; + session->ikev1_state.active_ph1cnt--; + if (session->ikev1_state.active_ph1cnt == 0 && session->ikev1_state.active_ph2cnt == 0) { + free_ike_session(session); + } + + return 0; +} + +int +ike_session_unlink_ph2_from_session (struct ph2handle *iph2) +{ + ike_session_t *session; + + if (!iph2 || !iph2->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return -1; + } + + LIST_REMOVE(iph2, ph2ofsession_chain); + session = iph2->parent_session; + iph2->parent_session = NULL; + session->ikev1_state.active_ph2cnt--; + if (session->ikev1_state.active_ph1cnt == 0 && session->ikev1_state.active_ph2cnt == 0) { + free_ike_session(session); + } + + return 0; +} + +int +ike_session_has_other_established_ph1 (ike_session_t *session, struct ph1handle *iph1) +{ + struct ph1handle *p; + + if (!session) { + return 0; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) { + if (iph1 != p && !p->is_dying) { + if (p->status == PHASE1ST_ESTABLISHED && p->sce_rekey) { + return 1; + } + } + } + + return 0; +} + +int +ike_session_has_other_negoing_ph1 (ike_session_t *session, struct ph1handle *iph1) +{ + struct ph1handle *p; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return 0; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) { + if (iph1 != p && !p->is_dying) { + if (p->status >= PHASE1ST_START && p->status <= PHASE1ST_ESTABLISHED) { + return 1; + } + } + } + + return 0; +} + +int +ike_session_has_other_established_ph2 (ike_session_t *session, struct ph2handle *iph2) +{ + struct ph2handle *p; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return 0; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) { + if (iph2 != p && !p->is_dying && iph2->spid == p->spid) { + if (p->status == PHASE2ST_ESTABLISHED) { + return 1; + } + } + } + + return 0; +} + +int +ike_session_has_other_negoing_ph2 (ike_session_t *session, struct ph2handle *iph2) +{ + struct ph2handle *p; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return 0; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) { + if (iph2 != p && !p->is_dying && iph2->spid == p->spid) { + if (p->status >= PHASE2ST_START && p->status < PHASE2ST_ESTABLISHED) { + return 1; + } + } + } + + return 0; +} + +static void +ike_session_unbindph12_from_ph1 (struct ph1handle *iph1) +{ + struct ph2handle *p, *next; + + for (p = LIST_FIRST(&iph1->ph2tree); p; p = next) { + // take next pointer now, since unbind and rebind may change the underlying ph2tree list + next = LIST_NEXT(p, ph1bind); + unbindph12(p); + } +} + +static void +ike_session_rebindph12_from_old_ph1_to_new_ph1 (struct ph1handle *old_iph1, + struct ph1handle *new_iph1) +{ + struct ph2handle *p, *next; + + if (old_iph1 == new_iph1 || !old_iph1 || !new_iph1) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + + if (old_iph1->parent_session != new_iph1->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent sessions in %s.\n", __FUNCTION__); + return; + } + + for (p = LIST_FIRST(&old_iph1->ph2tree); p; p = next) { + // take next pointer now, since rebind may change the underlying ph2tree list + next = LIST_NEXT(p, ph1bind); + if (p->parent_session != new_iph1->parent_session) { + plog(LLV_ERROR, LOCATION, NULL, "mismatched parent session in ph1bind replacement.\n"); + } + if (p->ph1 == new_iph1) { + plog(LLV_ERROR, LOCATION, NULL, "same phase1 in ph1bind replacement in %s.\n",__FUNCTION__); + } + rebindph12(new_iph1, p); + } +} + +int +ike_session_verify_ph2_parent_session (struct ph2handle *iph2) +{ + if (!iph2) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return -1; + } + + if (!iph2->parent_session) { + plog(LLV_DEBUG, LOCATION, NULL, "NULL parent session.\n"); + if (ike_session_link_ph2_to_session(iph2)) { + plog(LLV_DEBUG, LOCATION, NULL, "NULL parent session... still failed to link to session.\n"); + // failed to bind ph2 to session + return 1; + } + } + return 0; +} + +struct ph1handle * +ike_session_update_ph1_ph2tree (struct ph1handle *iph1) +{ + struct ph1handle *new_iph1 = NULL; + + if (!iph1) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return NULL; + } + + if (iph1->parent_session) { + new_iph1 = ike_session_get_established_ph1(iph1->parent_session); + + if (!new_iph1) { + plog(LLV_DEBUG2, LOCATION, NULL, "no ph1bind replacement found. NULL ph1.\n"); + ike_session_unbindph12_from_ph1(iph1); + } else if (iph1 == new_iph1) { + plog(LLV_DEBUG2, LOCATION, NULL, "no ph1bind replacement found. same ph1.\n"); + ike_session_unbindph12_from_ph1(iph1); + } else { + ike_session_rebindph12_from_old_ph1_to_new_ph1(iph1, new_iph1); + } + } else { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent session in %s.\n", __FUNCTION__); + } + return new_iph1; +} + +struct ph1handle * +ike_session_update_ph2_ph1bind (struct ph2handle *iph2) +{ + struct ph1handle *iph1; + + if (!iph2) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return NULL; + } + + iph1 = ike_session_get_established_ph1(iph2->parent_session); + if (iph1 && iph2->ph1 && iph1 != iph2->ph1) { + rebindph12(iph1, iph2); + } else if (iph1 && !iph2->ph1) { + bindph12(iph1, iph2); + } + + return iph1; +} + +void +ike_session_ikev1_float_ports (struct ph1handle *iph1) +{ + struct sockaddr *local, *remote; + struct ph2handle *p; + + if (iph1->parent_session) { + local = (struct sockaddr *)&iph1->parent_session->session_id.local; + remote = (struct sockaddr *)&iph1->parent_session->session_id.remote; + + set_port(local, extract_port(iph1->local)); + set_port(remote, extract_port(iph1->remote)); + iph1->parent_session->ports_floated = 1; + + for (p = LIST_FIRST(&iph1->parent_session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) { + + local = p->src; + remote = p->dst; + + set_port(local, extract_port(iph1->local)); + set_port(remote, extract_port(iph1->remote)); + } + } else { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent session in %s.\n", __FUNCTION__); + } +} + +static void +ike_session_traffic_cop (void *arg) +{ + ike_session_t *session = (__typeof__(session))arg; + + if (session) { + SCHED_KILL(session->traffic_monitor.sc_mon); + /* get traffic query from kernel */ + if (pk_sendget_inbound_sastats(session) < 0) { + // log message + plog(LLV_DEBUG2, LOCATION, NULL, "pk_sendget_inbound_sastats failed in %s.\n", __FUNCTION__); + } + if (pk_sendget_outbound_sastats(session) < 0) { + // log message + plog(LLV_DEBUG2, LOCATION, NULL, "pk_sendget_outbound_sastats failed in %s.\n", __FUNCTION__); + } + session->traffic_monitor.sc_mon = sched_new(session->traffic_monitor.interv_mon, + ike_session_traffic_cop, + session); + } else { + // log message + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + } +} + +static void +ike_session_cleanup_idle (void *arg) +{ + ike_session_t *session = (ike_session_t *)arg; + + if (session->traffic_monitor.dir_idle == IPSEC_DIR_INBOUND || + session->traffic_monitor.dir_idle == IPSEC_DIR_ANY) { + if (session->peer_sent_data_sc_idle) { + SCHED_KILL(session->traffic_monitor.sc_idle); + session->traffic_monitor.sc_idle = sched_new(session->traffic_monitor.interv_idle, + ike_session_cleanup_idle, + session); + session->peer_sent_data_sc_idle = 0; + session->i_sent_data_sc_idle = 0; + return; + } + } + if (session->traffic_monitor.dir_idle == IPSEC_DIR_OUTBOUND || + session->traffic_monitor.dir_idle == IPSEC_DIR_ANY) { + if (session->i_sent_data_sc_idle) { + SCHED_KILL(session->traffic_monitor.sc_idle); + session->traffic_monitor.sc_idle = sched_new(session->traffic_monitor.interv_idle, + ike_session_cleanup_idle, + session); + session->peer_sent_data_sc_idle = 0; + session->i_sent_data_sc_idle = 0; + return; + } + } + + ike_session_cleanup((ike_session_t *)arg, ike_session_stopped_by_idle); +} + +void +ike_session_ph2_established (struct ph2handle *iph2) +{ + if (!iph2->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + SCHED_KILL(iph2->parent_session->sc_xauth); + if (!iph2->parent_session->established) { + gettimeofday(&iph2->parent_session->estab_timestamp, NULL); + iph2->parent_session->established = 1; + IPSECSESSIONTRACERESTABLISHED(iph2->parent_session); + if (iph2->parent_session->traffic_monitor.interv_mon) { + iph2->parent_session->traffic_monitor.sc_mon = sched_new(iph2->parent_session->traffic_monitor.interv_mon, + ike_session_traffic_cop, + iph2->parent_session); + } + if (iph2->parent_session->traffic_monitor.interv_idle) { + iph2->parent_session->traffic_monitor.sc_idle = sched_new(iph2->parent_session->traffic_monitor.interv_idle, + ike_session_cleanup_idle, + iph2->parent_session); + } + } + // nothing happening to this session + iph2->parent_session->term_reason = NULL; + + ike_session_update_mode(iph2); +} + +void +ike_session_cleanup_ph1 (struct ph1handle *iph1) +{ + if (iph1->status == PHASE1ST_EXPIRED) { + // since this got here via ike_session_cleanup_other_established_ph1s, assumes LIST_FIRST(&iph1->ph2tree) == NULL + iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); + return; + } + + /* send delete information */ + if (iph1->status == PHASE1ST_ESTABLISHED) { + isakmp_info_send_d1(iph1); + } + + isakmp_ph1expire(iph1); +} + +void +ike_session_cleanup_ph1_stub (void *p) +{ + + ike_session_cleanup_ph1((struct ph1handle *)p); +} + +void +ike_session_cleanup_other_established_ph1s (ike_session_t *session, + struct ph1handle *new_iph1) +{ + struct ph1handle *p, *next; + char *local, *remote; + + if (!session || !new_iph1 || session != new_iph1->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = next) { + // take next pointer now, since delete change the underlying ph1tree list + next = LIST_NEXT(p, ph1ofsession_chain); + /* + * TODO: currently, most recently established SA wins. Need to revisit to see if + * alternative selections is better (e.g. largest p->index stays). + */ + if (p != new_iph1) { + SCHED_KILL(p->sce); + SCHED_KILL(p->sce_rekey); + p->is_dying = 1; + + //log deletion + local = racoon_strdup(saddr2str(p->local)); + remote = racoon_strdup(saddr2str(p->remote)); + STRDUP_FATAL(local); + STRDUP_FATAL(remote); + plog(LLV_DEBUG, LOCATION, NULL, + "ISAKMP-SA needs to be deleted %s-%s spi:%s\n", + local, remote, isakmp_pindex(&p->index, 0)); + racoon_free(local); + racoon_free(remote); + + // first rebind the children ph2s of this dying ph1 to the new ph1. + ike_session_rebindph12_from_old_ph1_to_new_ph1 (p, new_iph1); + + if (p->side == INITIATOR) { + /* everyone deletes old outbound SA */ + p->sce = sched_new(5, ike_session_cleanup_ph1_stub, p); + } else { + /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */ + p->sce = sched_new(7, ike_session_cleanup_ph1_stub, p); + } + } + } +} + +void +ike_session_cleanup_ph2 (struct ph2handle *iph2) +{ + if (iph2->status == PHASE2ST_EXPIRED) { + return; + } + + SCHED_KILL(iph2->sce); + + /* send delete information */ + if (iph2->status == PHASE2ST_ESTABLISHED) { + isakmp_info_send_d2(iph2); + } + + // delete outgoing SAs + if (iph2->approval) { + struct saproto *pr; + + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + if (pr->ok) { + pfkey_send_delete(lcconf->sock_pfkey, + ipsecdoi2pfkey_proto(pr->proto_id), + IPSEC_MODE_ANY, + iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */); + } + } + } + + delete_spd(iph2); + unbindph12(iph2); + remph2(iph2); + delph2(iph2); +} + +void +ike_session_cleanup_ph2_stub (void *p) +{ + + ike_session_cleanup_ph2((struct ph2handle *)p); +} + +void +ike_session_cleanup_other_established_ph2s (ike_session_t *session, + struct ph2handle *new_iph2) +{ + struct ph2handle *p, *next; + + if (!session || !new_iph2 || session != new_iph2->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = next) { + // take next pointer now, since delete change the underlying ph2tree list + next = LIST_NEXT(p, ph2ofsession_chain); + /* + * TODO: currently, most recently established SA wins. Need to revisit to see if + * alternative selections is better. + */ + if (p != new_iph2 && p->spid == new_iph2->spid) { + SCHED_KILL(p->sce); + p->is_dying = 1; + + //log deletion + plog(LLV_DEBUG, LOCATION, NULL, + "IPsec-SA needs to be deleted: %s\n", + sadbsecas2str(p->src, p->dst, + p->satype, p->spid, 0)); + + if (p->side == INITIATOR) { + /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */ + p->sce = sched_new(3, ike_session_cleanup_ph2_stub, p); + } else { + /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */ + p->sce = sched_new(5, ike_session_cleanup_ph2_stub, p); + } + } + } +} + +void +ike_session_stopped_by_controller (ike_session_t *session, + const char *reason) +{ + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + if (session->stop_timestamp.tv_sec || + session->stop_timestamp.tv_usec) { + plog(LLV_DEBUG2, LOCATION, NULL, "already stopped %s.\n", __FUNCTION__); + return; + } + session->stopped_by_vpn_controller = 1; + gettimeofday(&session->stop_timestamp, NULL); + if (!session->term_reason) { + session->term_reason = reason; + } +} + +void +ike_sessions_stopped_by_controller (struct sockaddr *remote, + int withport, + const char *reason) +{ + ike_session_t *p = NULL; + + if (!remote) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + + for (p = LIST_FIRST(&ike_session_tree); p; p = LIST_NEXT(p, chain)) { + if (withport && cmpsaddrstrict(&p->session_id.remote, remote) == 0 || + !withport && cmpsaddrwop(&p->session_id.remote, remote) == 0) { + ike_session_stopped_by_controller(p, reason); + } + } +} + +void +ike_session_purge_ph2s_by_ph1 (struct ph1handle *iph1) +{ + struct ph2handle *p, *next; + + if (!iph1 || !iph1->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + + for (p = LIST_FIRST(&iph1->parent_session->ikev1_state.ph2tree); p; p = next) { + // take next pointer now, since delete change the underlying ph2tree list + next = LIST_NEXT(p, ph2ofsession_chain); + SCHED_KILL(p->sce); + p->is_dying = 1; + + //log deletion + plog(LLV_DEBUG, LOCATION, NULL, + "IPsec-SA needs to be purged: %s\n", + sadbsecas2str(p->src, p->dst, + p->satype, p->spid, 0)); + + ike_session_cleanup_ph2(p); + } +} + +void +ike_session_update_ph2_ports (struct ph2handle *iph2) +{ + struct sockaddr *local; + struct sockaddr *remote; + + if (iph2->parent_session) { + local = (struct sockaddr *)&iph2->parent_session->session_id.local; + remote = (struct sockaddr *)&iph2->parent_session->session_id.remote; + + set_port(iph2->src, extract_port(local)); + set_port(iph2->dst, extract_port(remote)); + } else { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parent session in %s.\n", __FUNCTION__); + } +} + +u_int32_t +ike_session_get_sas_for_stats (ike_session_t *session, + u_int8_t dir, + u_int32_t *seq, + struct sastat *stats, + u_int32_t max_stats) +{ + int found = 0; + struct ph2handle *iph2; + + if (!session || !seq || !stats || !max_stats || (dir != IPSEC_DIR_INBOUND && dir != IPSEC_DIR_OUTBOUND)) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid args in %s.\n", __FUNCTION__); + return found; + } + + *seq = 0; + for (iph2 = LIST_FIRST(&session->ikev1_state.ph2tree); iph2; iph2 = LIST_NEXT(iph2, ph2ofsession_chain)) { + + if (iph2->approval) { + struct saproto *pr; + + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + if (pr->ok && pr->proto_id == IPSECDOI_PROTO_IPSEC_ESP) { + if (!*seq) { + *seq = iph2->seq; + } + if (dir == IPSEC_DIR_INBOUND) { + stats[found].spi = pr->spi; + } else { + stats[found].spi = pr->spi_p; + } + if (++found == max_stats) { + return found; + } + } + } + } + } + return found; +} + +void +ike_session_update_traffic_idle_status (ike_session_t *session, + u_int32_t dir, + struct sastat *new_stats, + u_int32_t max_stats) +{ + int i, j, found = 0, idle = 1; + + if (!session || !new_stats || (dir != IPSEC_DIR_INBOUND && dir != IPSEC_DIR_OUTBOUND)) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid args in %s.\n", __FUNCTION__); + return; + } + + for (i = 0; i < max_stats; i++) { + if (dir == IPSEC_DIR_INBOUND) { + for (j = 0; j < session->traffic_monitor.num_in_last_poll; j++) { + if (new_stats[i].spi != session->traffic_monitor.in_last_poll[j].spi) { + continue; + } + found = 1; + if (new_stats[i].lft_c.sadb_lifetime_bytes != session->traffic_monitor.in_last_poll[j].lft_c.sadb_lifetime_bytes) { + idle = 0; + } + } + } else { + for (j = 0; j < session->traffic_monitor.num_out_last_poll; j++) { + if (new_stats[i].spi != session->traffic_monitor.out_last_poll[j].spi) { + continue; + } + found = 1; + if (new_stats[i].lft_c.sadb_lifetime_bytes != session->traffic_monitor.out_last_poll[j].lft_c.sadb_lifetime_bytes) { + idle = 0; + } + } + } + // new SA.... check for any activity + if (!found) { + if (new_stats[i].lft_c.sadb_lifetime_bytes) { + plog(LLV_DEBUG, LOCATION, NULL, "new SA: dir %d....\n", dir); + idle = 0; + } + } + } + if (dir == IPSEC_DIR_INBOUND) { + // overwrite old stats + bzero(session->traffic_monitor.in_last_poll, sizeof(session->traffic_monitor.in_last_poll)); + bcopy(new_stats, session->traffic_monitor.in_last_poll, (max_stats * sizeof(*new_stats))); + session->traffic_monitor.num_in_last_poll = max_stats; + if (!idle) { + plog(LLV_DEBUG, LOCATION, NULL, "peer sent data....\n"); + session->peer_sent_data_sc_dpd = 1; + session->peer_sent_data_sc_idle = 1; + } + } else { + // overwrite old stats + bzero(session->traffic_monitor.out_last_poll, sizeof(session->traffic_monitor.out_last_poll)); + bcopy(new_stats, session->traffic_monitor.out_last_poll, (max_stats * sizeof(*new_stats))); + session->traffic_monitor.num_out_last_poll = max_stats; + if (!idle) { + plog(LLV_DEBUG, LOCATION, NULL, "i sent data....\n"); + session->i_sent_data_sc_dpd = 1; + session->i_sent_data_sc_idle = 1; + } + } +} + +void +ike_session_cleanup (ike_session_t *session, + const char *reason) +{ + struct ph2handle *iph2; + struct ph1handle *iph1; + + if (!session) + return; + + // do ph2's first... we need the ph1s for notifications + for (iph2 = LIST_FIRST(&session->ikev1_state.ph2tree); iph2; iph2 = LIST_NEXT(iph2, ph2ofsession_chain)) { + if (iph2->status == PHASE2ST_ESTABLISHED) { + isakmp_info_send_d2(iph2); + } + isakmp_ph2expire(iph2); // iph2 will go down 1 second later. + ike_session_stopped_by_controller(session, reason); + } + + // do the ph1s last. + for (iph1 = LIST_FIRST(&session->ikev1_state.ph1tree); iph1; iph1 = LIST_NEXT(iph1, ph1ofsession_chain)) { + if (iph1->status == PHASE1ST_ESTABLISHED) { + isakmp_info_send_d1(iph1); + } + isakmp_ph1expire(iph1); + } + + // send ipsecManager a notification + if (reason == ike_session_stopped_by_idle) { + u_int32_t address; + if (((struct sockaddr *)&session->session_id.remote)->sa_family == AF_INET) { + address = ((struct sockaddr_in *)&session->session_id.remote)->sin_addr.s_addr; + } else { + address = 0; + } + (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_IDLE_TIMEOUT, FROM_LOCAL, address, 0, NULL); + } +} + +int +ike_session_has_negoing_ph1 (ike_session_t *session) +{ + struct ph1handle *p; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return 0; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = LIST_NEXT(p, ph1ofsession_chain)) { + if (!p->is_dying && p->status >= PHASE1ST_START && p->status <= PHASE1ST_ESTABLISHED) { + return 1; + } + } + + return 0; +} + +int +ike_session_has_negoing_ph2 (ike_session_t *session) +{ + struct ph2handle *p; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return 0; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) { + if (!p->is_dying && p->status >= PHASE2ST_START && p->status <= PHASE2ST_ESTABLISHED) { + return 1; + } + } + + return 0; +} + +int +ike_session_has_established_ph2 (ike_session_t *session) +{ + struct ph2handle *p; + + if (!session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return 0; + } + + for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) { + if (!p->is_dying && p->status == PHASE2ST_ESTABLISHED) { + return 1; + } + } + + return 0; +} + +void +ike_session_cleanup_ph1s_by_ph2 (struct ph2handle *iph2) +{ + struct ph1handle *iph1; + + if (!iph2 || !iph2->parent_session) { + plog(LLV_DEBUG2, LOCATION, NULL, "invalid parameters in %s.\n", __FUNCTION__); + return; + } + + // phase1 is no longer useful + for (iph1 = LIST_FIRST(&iph2->parent_session->ikev1_state.ph1tree); iph1; iph1 = LIST_NEXT(iph1, ph1ofsession_chain)) { + if (iph1->status == PHASE1ST_ESTABLISHED) { + isakmp_info_send_d1(iph1); + } + isakmp_ph1expire(iph1); + } +} + +int +ike_session_is_client_ph2_rekey (struct ph2handle *iph2) +{ + if (iph2->parent_session && + iph2->parent_session->is_client && + iph2->is_rekey && + iph2->parent_session->is_cisco_ipsec) { + return 1; + } + return 0; +} + +int +ike_session_is_client_ph1_rekey (struct ph1handle *iph1) +{ + if (iph1->parent_session && + iph1->parent_session->is_client && + iph1->is_rekey && + iph1->parent_session->is_cisco_ipsec) { + return 1; + } + return 0; +} + +void +ike_session_start_xauth_timer (struct ph1handle *iph1) +{ + // if there are no more established ph2s, start a timer to teardown the session + if (iph1->parent_session && + iph1->parent_session->is_client && + iph1->parent_session->is_cisco_ipsec && + !iph1->parent_session->sc_xauth) { + iph1->parent_session->sc_xauth = sched_new(300 /* 5 mins */, + ike_session_cleanup_xauth_timeout, + iph1->parent_session); + } +} + +void +ike_session_stop_xauth_timer (struct ph1handle *iph1) +{ + if (iph1->parent_session) { + SCHED_KILL(iph1->parent_session->sc_xauth); + } +} \ No newline at end of file diff --git a/ipsec-tools/racoon/ike_session.h b/ipsec-tools/racoon/ike_session.h new file mode 100644 index 0000000..ba91e0f --- /dev/null +++ b/ipsec-tools/racoon/ike_session.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IKE_SESSION_H +#define _IKE_SESSION_H + +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif +#include +#include "handler.h" +#include "ipsecSessionTracer.h" + +#define IKE_VERSION_1 0x1 +#define IKE_VERSION_2 0x2 + +typedef struct ike_session_id { + struct sockaddr_storage local; + struct sockaddr_storage remote; +} ike_session_id_t; + +typedef struct ike_session_stats { + u_int32_t counters[IPSECSESSIONEVENTCODE_MAX]; +} ike_session_stats_t; + +typedef struct ike_session_ikev1 { + /* list of ph1s */ + int active_ph1cnt; + int ph1cnt; /* the number which is negotiated for this session */ + LIST_HEAD(_ph1ofsession_, ph1handle) ph1tree; + + /* list of ph2s */ + int active_ph2cnt; + int ph2cnt; /* the number which is negotiated for this session */ + LIST_HEAD(_ph2ofsession_, ph2handle) ph2tree; +} ike_session_ikev1_t; + +typedef struct ike_session_sastats { + int interv_mon; + int interv_idle; + int dir_idle; + struct sched *sc_mon; + struct sched *sc_idle; + + u_int32_t num_in_curr_req; + u_int32_t num_in_last_poll; + struct sastat in_curr_req[8]; + struct sastat in_last_poll[8]; + + u_int32_t num_out_curr_req; + u_int32_t num_out_last_poll; + struct sastat out_curr_req[8]; + struct sastat out_last_poll[8]; +} ike_sesssion_sastats_t; + +struct ike_session { + u_int8_t version; /* mask of version flags */ + u_int8_t mode; /* mode of protocol, see ipsec.h */ + u_int16_t proto; /* IPPROTO_ESP or IPPROTO_AH */ + + ike_session_id_t session_id; + + int established:1; + int ports_floated:1; + int is_cisco_ipsec:1; + int is_l2tpvpn_ipsec:1; + int is_btmm_ipsec:1; + int stopped_by_vpn_controller:1; + int peer_sent_data_sc_dpd:1; + int peer_sent_data_sc_idle:1; + int i_sent_data_sc_dpd:1; + int i_sent_data_sc_idle:1; + int is_client:1; + u_int32_t natt_flags; + char *term_reason; + + struct timeval start_timestamp; + struct timeval estab_timestamp; + struct timeval stop_timestamp; + ike_session_ikev1_t ikev1_state; + + ike_session_stats_t stats; + + ike_sesssion_sastats_t traffic_monitor; + struct sched *sc_idle; + struct sched *sc_xauth; + + LIST_ENTRY(ike_session) chain; +}; + +extern const char * ike_session_stopped_by_vpn_disconnect; +extern const char * ike_session_stopped_by_flush; + +extern void ike_session_init __P((void)); +extern ike_session_t * ike_session_get_session __P((struct sockaddr *, struct sockaddr *, int)); +extern u_int ike_session_get_rekey_lifetime __P((int, u_int)); +extern void ike_session_update_mode __P((struct ph2handle *iph2)); +extern int ike_session_link_ph1_to_session __P((struct ph1handle *)); +extern int ike_session_link_ph2_to_session __P((struct ph2handle *)); +extern int ike_session_unlink_ph1_from_session __P((struct ph1handle *)); +extern int ike_session_unlink_ph2_from_session __P((struct ph2handle *)); +extern int ike_session_has_other_established_ph1 __P((ike_session_t *, struct ph1handle *)); +extern int ike_session_has_other_negoing_ph1 __P((ike_session_t *, struct ph1handle *)); +extern int ike_session_has_other_established_ph2 __P((ike_session_t *, struct ph2handle *)); +extern int ike_session_has_other_negoing_ph2 __P((ike_session_t *, struct ph2handle *)); +extern int ike_session_verify_ph2_parent_session __P((struct ph2handle *)); +extern struct ph1handle * ike_session_update_ph1_ph2tree __P((struct ph1handle *)); +extern struct ph1handle * ike_session_update_ph2_ph1bind __P((struct ph2handle *)); +extern void ike_session_ikev1_float_ports __P((struct ph1handle *)); +extern void ike_session_ph2_established __P((struct ph2handle *)); +extern void ike_session_cleanup_other_established_ph1s __P((ike_session_t *, struct ph1handle *)); +extern void ike_session_cleanup_other_established_ph2s __P((ike_session_t *, struct ph2handle *)); +extern void ike_session_stopped_by_controller __P((ike_session_t *, const char *)); +extern void ike_sessions_stopped_by_controller __P((struct sockaddr *, int, const char *)); +extern void ike_session_purge_ph2s_by_ph1 __P((struct ph1handle *)); +extern struct ph1handle * ike_session_get_established_ph1 __P((ike_session_t *)); +extern void ike_session_update_ph2_ports __P((struct ph2handle *)); +extern u_int32_t ike_session_get_sas_for_stats __P((ike_session_t *, u_int8_t, u_int32_t *, struct sastat *, u_int32_t)); +extern void ike_session_update_traffic_idle_status __P((ike_session_t *, u_int32_t, struct sastat *, u_int32_t)); +extern void ike_session_cleanup __P((ike_session_t *, const char *)); +extern int ike_session_has_negoing_ph1 __P((ike_session_t *)); +extern int ike_session_has_negoing_ph2 __P((ike_session_t *)); +extern int ike_session_has_established_ph2 __P((ike_session_t *)); +extern void ike_session_cleanup_ph1s_by_ph2 __P((struct ph2handle *)); +extern int ike_session_is_client_ph2_rekey __P((struct ph2handle *)); +extern int ike_session_is_client_ph1_rekey __P((struct ph1handle *)); +extern void ike_session_start_xauth_timer __P((struct ph1handle *)); +extern void ike_session_stop_xauth_timer __P((struct ph1handle *)); + +#endif /* _IKE_SESSION_H */ diff --git a/ipsec-tools/racoon/ipsecConfigTracer.c b/ipsec-tools/racoon/ipsecConfigTracer.c new file mode 100644 index 0000000..ca82dce --- /dev/null +++ b/ipsec-tools/racoon/ipsecConfigTracer.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#import +#include +#include "ipsecConfigTracer.h" +#include "ipsecMessageTracer.h" + +const char * ipsecConfigTracerFailedString = "Tracer Failed"; +const char * ipsecConfigInvalidEventString = "Invalid Event"; +const char * ipsecConfigString = "IPSEC"; + +const char * const ipsecConfigEventStrings[IPSECCONFIGEVENTCODE_MAX] = { CONSTSTR("NONE") /* index place holder */, + CONSTSTR("Configuration Reparse Error"), + CONSTSTR("Configuration Parse Error"), + CONSTSTR("Signal Error"), + }; + +const char * +ipsecConfigEventCodeToString (ipsecConfigEventCode_t eventCode) +{ + if (eventCode <= IPSECCONFIGEVENTCODE_NONE || eventCode >= IPSECCONFIGEVENTCODE_MAX) + return ipsecConfigInvalidEventString; + return(ipsecConfigEventStrings[eventCode]); +} + +static +void +ipsecConfigLogEvent (const char *event_msg, const char *failure_signature) +{ + aslmsg m; + + if (!event_msg) { + return; + } + + m = asl_new(ASL_TYPE_MSG); + asl_set(m, ASL_KEY_FACILITY, PLAINIPSECDOMAIN); + asl_set(m, ASL_KEY_MSG, ipsecConfigString); +#if 0 /* is flooding 300000+ events to MessageTracer servers */ + if (failure_signature) { + asl_set(m, "com.apple.message.domain", PLAINIPSECDOMAIN); + asl_set(m, "com.apple.message.result", "failure"); // failure + asl_set(m, "com.apple.message.signature", failure_signature); + } + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg); +#else + if (failure_signature) { + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s (failure: %s)", event_msg, failure_signature); + } else { + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg); + } +#endif + asl_free(m); +} + +void +ipsecConfigTracerEvent (const char *filename, ipsecConfigEventCode_t eventCode, const char *event, const char *failure_reason) +{ + char buf[1024]; + + if (filename == NULL) { + ipsecConfigLogEvent(CONSTSTR("tracer failed. (Invalid filename)."), ipsecConfigTracerFailedString); + return; + } + if (eventCode <= IPSECCONFIGEVENTCODE_NONE || eventCode >= IPSECCONFIGEVENTCODE_MAX) { + ipsecConfigLogEvent(CONSTSTR("tracer failed. (Invalid event code)."), ipsecConfigTracerFailedString); + return; + } + if (event == NULL) { + ipsecConfigLogEvent(CONSTSTR("tracer failed. (Invalid event)."), ipsecConfigTracerFailedString); + return; + } + + buf[0] = (char)0; + snprintf(buf, sizeof(buf), "%s. (%s, filename %s).", ipsecConfigEventCodeToString(eventCode), failure_reason, filename); + ipsecConfigLogEvent(CONSTSTR(buf), event); +} diff --git a/ipsec-tools/racoon/ipsecConfigTracer.h b/ipsec-tools/racoon/ipsecConfigTracer.h new file mode 100644 index 0000000..31492a2 --- /dev/null +++ b/ipsec-tools/racoon/ipsecConfigTracer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IPSECCONFIGTRACER_H +#define _IPSECCONFIGTRACER_H + +typedef enum ipsecConfigEventCode { + IPSECCONFIGEVENTCODE_NONE = 0, + IPSECCONFIGEVENTCODE_REPARSE_ERROR, + IPSECCONFIGEVENTCODE_PARSE_ERROR, + IPSECCONFIGEVENTCODE_SIGNAL_ERROR, + IPSECCONFIGEVENTCODE_MAX, +} ipsecConfigEventCode_t; + +const char * ipsecConfigEventCodeToString (ipsecConfigEventCode_t); +void ipsecConfigTracerEvent (const char *, ipsecConfigEventCode_t, const char *, const char *); + +#endif /* _IPSECCONFIGTRACER_H */ diff --git a/ipsec-tools/racoon/ipsecSessionTracer.c b/ipsec-tools/racoon/ipsecSessionTracer.c new file mode 100644 index 0000000..98308c2 --- /dev/null +++ b/ipsec-tools/racoon/ipsecSessionTracer.c @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#import +#include +#include "ike_session.h" +#include "ipsecMessageTracer.h" +#include "misc.h" +#include "nattraversal.h" + +#define TRUE 1 +#define FALSE 0 +const char *ipsecSessionInvalidEventString = "Invalid Event"; +const char *ipsecSessionString = "IPSEC"; + +/* tells us the event's description */ +const char * const ipsecSessionEventStrings[IPSECSESSIONEVENTCODE_MAX] = { CONSTSTR("NONE") /* index place holder */, + CONSTSTR("IKE Packet: transmit success"), + CONSTSTR("IKE Packet: transmit failed"), + CONSTSTR("IKE Packet: receive success"), + CONSTSTR("IKE Packet: receive failed"), + CONSTSTR("IKEv1 Phase1 Initiator: success"), + CONSTSTR("IKEv1 Phase1 Initiator: failed"), + CONSTSTR("IKEv1 Phase1 Initiator: dropped"), + CONSTSTR("IKEv1 Phase1 Responder: success"), + CONSTSTR("IKEv1 Phase1 Responder: failed"), + CONSTSTR("IKEv1 Phase1 Responder: drop"), + CONSTSTR("IKEv1 Phase1: maximum retransmits"), + CONSTSTR("IKEv1 Phase1 AUTH: success"), + CONSTSTR("IKEv1 Phase1 AUTH: failed"), + CONSTSTR("IKEv1 Dead-Peer-Detection: request transmitted"), + CONSTSTR("IKEv1 Dead-Peer-Detection: response received"), + CONSTSTR("IKEv1 Dead-Peer-Detection: request retransmitted"), + CONSTSTR("IKEv1 Dead-Peer-Detection: request received"), + CONSTSTR("IKEv1 Dead-Peer-Detection: response transmitted"), + CONSTSTR("IKEv1 Dead-Peer-Detection: response retransmitted"), + CONSTSTR("IKEv1 Dead-Peer-Detection: maximum retransmits"), + CONSTSTR("IKEv1 Config: retransmited"), + CONSTSTR("IKEv1 Mode-Config: success"), + CONSTSTR("IKEv1 Mode-Config: failed"), + CONSTSTR("IKEv1 Mode-Config: dropped"), + CONSTSTR("IKEv1 XAUTH: success"), + CONSTSTR("IKEv1 XAUTH: failed"), + CONSTSTR("IKEv1 XAUTH: dropped"), + CONSTSTR("IKEv1 Phase2 Initiator: success"), + CONSTSTR("IKEv1 Phase2 Initiator: failed"), + CONSTSTR("IKEv1 Phase2 Initiator: dropped"), + CONSTSTR("IKEv1 Phase2 Responder: success"), + CONSTSTR("IKEv1 Phase2 Responder: fail"), + CONSTSTR("IKEv1 Phase2 Responder: drop"), + CONSTSTR("IKEv1 Phase2: maximum retransmits"), + CONSTSTR("IKEv1 Phase2 AUTH: success"), + CONSTSTR("IKEv1 Phase2 AUTH: failed"), + CONSTSTR("IKEv1 Information-Notice: transmit success"), + CONSTSTR("IKEv1 Information-Notice: transmit failed"), + CONSTSTR("IKEv1 Information-Notice: receive success"), + CONSTSTR("IKEv1 Information-Notice: receive failed"), + }; + +/* tells us if we can ignore the failure_reason passed into the event tracer */ +const int const ipsecSessionEventIgnoreReason[IPSECSESSIONEVENTCODE_MAX] = {TRUE/* index place holder */, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + FALSE, + TRUE, + TRUE, + FALSE, + TRUE, + FALSE, + TRUE, + FALSE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + FALSE, + TRUE, + TRUE, + FALSE, + FALSE, + TRUE, + FALSE, + FALSE, + TRUE, + FALSE, + TRUE, + TRUE, + FALSE, + TRUE, + FALSE, + TRUE, + FALSE, + TRUE, + TRUE, + TRUE, + TRUE, + }; + + +const char * +ipsecSessionEventCodeToString (ipsecSessionEventCode_t eventCode) +{ + if (eventCode <= IPSECSESSIONEVENTCODE_NONE || eventCode >= IPSECSESSIONEVENTCODE_MAX) + return ipsecSessionInvalidEventString; + return(ipsecSessionEventStrings[eventCode]); +} + +const char * +ipsecSessionGetConnectionDomain (ike_session_t *session) +{ + if (session) { + if (session->is_cisco_ipsec) { + if (session->established) { + return CISCOIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN; + } else { + return CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN; + } + } else if (session->is_l2tpvpn_ipsec) { + if (session->established) { + return L2TPIPSECVPN_CONNECTION_ESTABLISHED_DOMAIN; + } else { + return L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN; + } + } else if (session->is_btmm_ipsec) { + if (session->established) { + return BTMMIPSEC_CONNECTION_ESTABLISHED_DOMAIN; + } else { + return BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN; + } + } else { + if (session->established) { + return PLAINIPSEC_CONNECTION_ESTABLISHED_DOMAIN; + } else { + return PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN; + } + } + } + return PLAINIPSECDOMAIN; +} + +const char * +ipsecSessionGetConnectionLessDomain (ike_session_t *session) +{ + if (session) { + if (session->is_cisco_ipsec) { + return CISCOIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN; + } else if (session->is_l2tpvpn_ipsec) { + return L2TPIPSECVPN_CONNECTION_NOTESTABLISHED_DOMAIN; + } else if (session->is_btmm_ipsec) { + return BTMMIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN; + } else { + return PLAINIPSEC_CONNECTION_NOTESTABLISHED_DOMAIN; + } + } + return PLAINIPSECDOMAIN; +} + +const char * +ipsecSessionGetPhaseDomain (ike_session_t *session) +{ + if (session) { + if (session->is_cisco_ipsec) { + return CISCOIPSECVPN_PHASE_DOMAIN; + } else if (session->is_l2tpvpn_ipsec) { + return L2TPIPSECVPN_PHASE_DOMAIN; + } else if (session->is_btmm_ipsec) { + return BTMMIPSEC_PHASE_DOMAIN; + } + } + return PLAINIPSEC_PHASE_DOMAIN; +} + +static +void +ipsecSessionLogEvent (ike_session_t *session, const char *event_msg) +{ + aslmsg m; + + if (!event_msg) { + return; + } + + m = asl_new(ASL_TYPE_MSG); + asl_set(m, ASL_KEY_FACILITY, ipsecSessionGetPhaseDomain(session)); + asl_set(m, ASL_KEY_MSG, ipsecSessionString); + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg); + asl_free(m); +} + +void +ipsecSessionTracerStart (ike_session_t *session) +{ + if (session == NULL) { + return; + } + bzero(&session->stats, sizeof(session->stats)); + bzero(&session->stop_timestamp, sizeof(session->stop_timestamp)); + bzero(&session->estab_timestamp, sizeof(session->estab_timestamp)); + gettimeofday(&session->start_timestamp, NULL); + ipsecSessionLogEvent(session, CONSTSTR("Connecting.")); +} + +void +ipsecSessionTracerEvent (ike_session_t *session, ipsecSessionEventCode_t eventCode, const char *event, const char *failure_reason) +{ + char buf[1024]; + + if (session == NULL) { + ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid session).")); + return; + } + if (eventCode <= IPSECSESSIONEVENTCODE_NONE || eventCode >= IPSECSESSIONEVENTCODE_MAX) { + ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid event code).")); + return; + } + if (event == NULL) { + ipsecSessionLogEvent(session, CONSTSTR("tracer failed. (Invalid event).")); + return; + } + + if (failure_reason) { + if (!session->term_reason && + !ipsecSessionEventIgnoreReason[eventCode]) { + session->term_reason = failure_reason; + } + } + + session->stats.counters[eventCode]++; + buf[0] = (char)0; + snprintf(buf, sizeof(buf), "%s. (%s).", ipsecSessionEventCodeToString(eventCode), event); + ipsecSessionLogEvent(session, CONSTSTR(buf)); +} + +static void +ipsecSessionTracerLogFailureRate (ike_session_t *session, const char *signature, double failure_rate) +{ + aslmsg m; + char buf[128]; + const char *domain = ipsecSessionGetPhaseDomain(session); + + if (!signature || failure_rate <= 0.001) { + return; + } + + m = asl_new(ASL_TYPE_MSG); + asl_set(m, "com.apple.message.domain", domain); + asl_set(m, ASL_KEY_FACILITY, domain); + asl_set(m, ASL_KEY_MSG, ipsecSessionString); + asl_set(m, "com.apple.message.result", "noop"); + asl_set(m, "com.apple.message.signature", signature); + snprintf(buf, sizeof(buf), "%.3f", failure_rate); + asl_set(m, "com.apple.message.value", buf); // stuff the up time into value + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s. (Failure-Rate = %s).", signature, buf); + asl_free(m); +} + +static void +ipsecSessionTracerLogStop (ike_session_t *session, int caused_by_failure, const char *reason) +{ + aslmsg m; + char nat_buf[128]; + char buf[128]; + const char *domain = (session->established)? ipsecSessionGetConnectionDomain(session) : ipsecSessionGetConnectionLessDomain(session); + + m = asl_new(ASL_TYPE_MSG); + asl_set(m, "com.apple.message.domain", domain); + asl_set(m, ASL_KEY_FACILITY, domain); + asl_set(m, ASL_KEY_MSG, ipsecSessionString); + if (caused_by_failure || + (reason && reason != ike_session_stopped_by_flush && reason != ike_session_stopped_by_vpn_disconnect)) { + asl_set(m, "com.apple.message.result", CONSTSTR("failure")); // failure + } else { + asl_set(m, "com.apple.message.result", CONSTSTR("success")); // success + } + if (reason) { + if (session->natt_flags & NAT_DETECTED_ME) { + snprintf(nat_buf, sizeof(nat_buf), "%s. NAT detected by Me", reason); + asl_set(m, "com.apple.message.signature", nat_buf); + } else if (session->natt_flags & NAT_DETECTED_PEER) { + snprintf(nat_buf, sizeof(nat_buf), "%s. NAT detected by Peer", reason); + asl_set(m, "com.apple.message.signature", nat_buf); + } else { + asl_set(m, "com.apple.message.signature", reason); + } + } else { + // reason was NULL; make sure success/failure have different signature + if (caused_by_failure) { + asl_set(m, "com.apple.message.signature", CONSTSTR("Internal/Server-side error")); + } else { + asl_set(m, "com.apple.message.signature", CONSTSTR("User/System initiated the disconnect")); + } + } + if (session->established) { + snprintf(buf, sizeof(buf), "%8.6f", timedelta(&session->estab_timestamp, &session->stop_timestamp)); + asl_set(m, "com.apple.message.value", buf); // stuff the up time into value + asl_log(NULL, m, ASL_LEVEL_NOTICE, "Disconnecting. (Connection was up for, %s seconds).", buf); + } else { + snprintf(buf, sizeof(buf), "%8.6f", timedelta(&session->start_timestamp, &session->stop_timestamp)); + asl_set(m, "com.apple.message.value2", buf); /// stuff the negoing time into value2 + asl_log(NULL, m, ASL_LEVEL_NOTICE, "Disconnecting. (Connection tried to negotiate for, %s seconds).", buf); + } + asl_free(m); +} + +void +ipsecSessionTracerStop (ike_session_t *session, int caused_by_failure, const char *reason) +{ + if (session == NULL) { + return; + } + + gettimeofday(&session->stop_timestamp, NULL); + + ipsecSessionTracerLogStop(session, caused_by_failure, reason); + + // go thru counters logging failure-rate events + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Packets Transmit Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Packets Receive Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC])); + } + if (session->version == IKE_VERSION_1) { + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT] || + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL] || + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase1 Failure-Rate Statistic"), + get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]), + (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC]))); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase1 Initiator Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase1 Responder Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase1 Authentication Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Dead-Peer-Detection Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT], + (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ]))); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT] || + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Dead-Peer-Detect Retransmit-Rate Statistic"), + get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT]), + (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ]))); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE MODE-Config Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_MODECFG_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE XAUTH Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT] || + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL] || + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase2 Failure-Rate Statistic"), + get_percentage((double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]), + (double)(session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC] + + session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]))); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase2 Initiator Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase2 Responder Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Phase2 Authentication Failure-Rate Statistics"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_SUCC])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Information-Notice Transmit Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL])); + } + if (session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL]) { + ipsecSessionTracerLogFailureRate(session, + CONSTSTR("IKE Information-Notice Receive Failure-Rate Statistic"), + get_percentage((double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL], (double)session->stats.counters[IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_SUCC])); + } + } +} + +void +ipsecSessionTracerLogEstablished (ike_session_t *session) +{ + aslmsg m; + const char *domain = ipsecSessionGetConnectionLessDomain(session); + + m = asl_new(ASL_TYPE_MSG); + asl_set(m, "com.apple.message.domain", domain); + asl_set(m, ASL_KEY_FACILITY, domain); + asl_set(m, ASL_KEY_MSG, ipsecSessionString); + asl_set(m, "com.apple.message.result", "success"); // success + asl_set(m, "com.apple.message.signature", "success"); + asl_log(NULL, m, ASL_LEVEL_NOTICE, "Connected."); + asl_free(m); +} diff --git a/ipsec-tools/racoon/ipsecSessionTracer.h b/ipsec-tools/racoon/ipsecSessionTracer.h new file mode 100644 index 0000000..4cb7421 --- /dev/null +++ b/ipsec-tools/racoon/ipsecSessionTracer.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IPSECSESSIONTRACER_H +#define _IPSECSESSIONTRACER_H + +typedef enum ipsecSessionEventCode { + IPSECSESSIONEVENTCODE_NONE = 0, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_DROP, + IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_DROP, + IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ, + IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RESP, + IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT, + IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ, + IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RESP, + IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT, + IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT, + IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT, + IPSECSESSIONEVENTCODE_IKEV1_MODECFG_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_MODECFG_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_MODECFG_DROP, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP, + IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP, + IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_DROP, + IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT, + IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_PH2_AUTH_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_SUCC, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_RX_FAIL, + IPSECSESSIONEVENTCODE_MAX, +} ipsecSessionEventCode_t; + +const char * ipsecSessionEventCodeToString (ipsecSessionEventCode_t); +void ipsecSessionTracerStart (ike_session_t *); +void ipsecSessionTracerEvent (ike_session_t *, ipsecSessionEventCode_t, const char *, const char *); +void ipsecSessionTracerStop (ike_session_t *, int, const char *); +void ipsecSessionTracerLogEstablished (ike_session_t *session); + +#endif /* _IPSECSESSIONTRACER_H */ diff --git a/ipsec-tools/racoon/ipsec_doi.c b/ipsec-tools/racoon/ipsec_doi.c index 1854964..713ec4c 100644 --- a/ipsec-tools/racoon/ipsec_doi.c +++ b/ipsec-tools/racoon/ipsec_doi.c @@ -274,10 +274,12 @@ found: plog(LLV_WARNING, LOCATION, NULL, "invalid DH parameter found, use default.\n"); oakley_dhgrp_free(sa->dhgrp); + sa->dhgrp=NULL; } if (oakley_setdhgroup(sa->dh_group, &sa->dhgrp) == -1) { sa->dhgrp = NULL; + racoon_free(sa); return NULL; } @@ -285,7 +287,7 @@ saok: #ifdef HAVE_GSSAPI if (sa->gssid != NULL) plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n", - sa->gssid->l, sa->gssid->v); + (int)sa->gssid->l, sa->gssid->v); if (iph1-> side == INITIATOR) { if (iph1->rmconf->proposal->gssid != NULL) iph1->gi_i = vdup(iph1->rmconf->proposal->gssid); @@ -303,13 +305,17 @@ saok: } if (iph1->gi_i != NULL) plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n", - iph1->gi_i->l, iph1->gi_i->v); + (int)iph1->gi_i->l, iph1->gi_i->v); if (iph1->gi_r != NULL) plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n", - iph1->gi_r->l, iph1->gi_r->v); + (int)iph1->gi_r->l, iph1->gi_r->v); #else iph1->approval = sa; #endif + if(iph1->approval) { + plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n", + s_oakley_attr_method(iph1->approval->authmethod)); + } newsa = get_sabyproppair(p, iph1); if (newsa == NULL) { @@ -336,6 +342,7 @@ get_ph1approvalx(p, proposal, sap, check_level) struct isakmp_pl_t *trns = p->trns; struct isakmpsa sa, *s, *tsap; int authmethod; + int tsap_authmethod; plog(LLV_DEBUG, LOCATION, NULL, "prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n", @@ -355,8 +362,10 @@ get_ph1approvalx(p, proposal, sap, check_level) for (s = proposal; s != NULL; s = s->next) { #ifdef ENABLE_HYBRID authmethod = switch_authmethod(s->authmethod); + tsap_authmethod = switch_authmethod(tsap->authmethod); #else authmethod = s->authmethod; + tsap_authmethod = tsap->authmethod; #endif plog(LLV_DEBUG, LOCATION, NULL, "Compared: DB:Peer\n"); plog(LLV_DEBUG, LOCATION, NULL, "(lifetime = %ld:%ld)\n", @@ -377,7 +386,7 @@ get_ph1approvalx(p, proposal, sap, check_level) tsap->hashtype)); plog(LLV_DEBUG, LOCATION, NULL, "authmethod = %s:%s\n", s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, - authmethod), + s->authmethod), s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, tsap->authmethod)); plog(LLV_DEBUG, LOCATION, NULL, "dh_group = %s:%s\n", @@ -394,7 +403,7 @@ get_ph1approvalx(p, proposal, sap, check_level) * is bigger than mine, it might be accepted. */ if(tsap->enctype == s->enctype && - tsap->authmethod == authmethod && + (tsap->authmethod == authmethod || tsap_authmethod == authmethod) && tsap->hashtype == s->hashtype && tsap->dh_group == s->dh_group && tsap->encklen == s->encklen) { @@ -435,8 +444,10 @@ get_ph1approvalx(p, proposal, sap, check_level) } found: - if (tsap->dhgrp != NULL) + if (tsap->dhgrp != NULL){ oakley_dhgrp_free(tsap->dhgrp); + tsap->dhgrp = NULL; + } if ((s = dupisakmpsa(s)) != NULL) { switch(check_level) { @@ -460,8 +471,11 @@ found: default: break; } + // hack to get around cisco rekeys + if (tsap->authmethod != authmethod && tsap_authmethod == authmethod) { + s->authmethod = tsap->authmethod; + } } - return s; } @@ -531,8 +545,10 @@ print_ph1mismatched(p, proposal) } } - if (sa.dhgrp != NULL) + if (sa.dhgrp != NULL){ oakley_dhgrp_free(sa.dhgrp); + sa.dhgrp=NULL; + } } /* @@ -740,7 +756,8 @@ t2isakmpsa(trns, sa) #ifdef HAVE_GSSAPI case OAKLEY_ATTR_GSS_ID: { - iconv_t cd; + int error = -1; + iconv_t cd = (iconv_t) -1; size_t srcleft, dstleft, rv; __iconv_const char *src; char *dst; @@ -753,12 +770,19 @@ t2isakmpsa(trns, sa) * compatible with this behavior. */ if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) { - sa->gssid = vmalloc(len); + if ((sa->gssid = vmalloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate memory\n"); + goto out; + } memcpy(sa->gssid->v, d + 1, len); plog(LLV_DEBUG, LOCATION, NULL, - "received old-style gss id '%.*s' (len %d)\n", - sa->gssid->l, sa->gssid->v, sa->gssid->l); - break; + "received old-style gss " + "id '%.*s' (len %zu)\n", + (int)sa->gssid->l, sa->gssid->v, + sa->gssid->l); + error = 0; + goto out; } /* @@ -775,10 +799,14 @@ t2isakmpsa(trns, sa) "unable to initialize utf-16le -> latin1 " "conversion descriptor: %s\n", strerror(errno)); - break; + goto out; } - sa->gssid = vmalloc(len / 2); + if ((sa->gssid = vmalloc(len / 2)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate memory\n"); + goto out; + } src = (__iconv_const char *)(d + 1); srcleft = len; @@ -800,19 +828,25 @@ t2isakmpsa(trns, sa) "be represented in latin1\n", rv, rv == 1 ? "" : "s"); } - (void) iconv_close(cd); - vfree(sa->gssid); - sa->gssid = NULL; - break; + goto out; } - (void) iconv_close(cd); /* XXX dstleft should always be 0; assert it? */ sa->gssid->l = (len / 2) - dstleft; plog(LLV_DEBUG, LOCATION, NULL, - "received gss id '%.*s' (len %d)\n", - sa->gssid->l, sa->gssid->v, sa->gssid->l); + "received gss id '%.*s' (len %zu)\n", + (int)sa->gssid->l, sa->gssid->v, sa->gssid->l); + + error = 0; +out: + if (cd != (iconv_t)-1) + (void)iconv_close(cd); + + if ((error != 0) && (sa->gssid != NULL)) { + vfree(sa->gssid); + sa->gssid = NULL; + } break; } #endif /* HAVE_GSSAPI */ @@ -1164,7 +1198,8 @@ found: { struct saproto *sp; - struct prop_pair *p, *n, *x; + struct prop_pair *p, *x; + struct prop_pair *n = NULL; ret = NULL; @@ -1189,7 +1224,7 @@ found: goto err; /* XXX */ n = racoon_calloc(1, sizeof(struct prop_pair)); - if (!n) { + if (n == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer.\n"); goto err; @@ -1261,7 +1296,7 @@ get_proppair(sa, mode) vchar_t *sa; int mode; { - struct prop_pair **pair; + struct prop_pair **pair = NULL; int num_p = 0; /* number of proposal for use */ int tlen; caddr_t bp; @@ -1275,22 +1310,22 @@ get_proppair(sa, mode) if (sa->l < sizeof(*sab)) { plog(LLV_ERROR, LOCATION, NULL, "Invalid SA length = %zu.\n", sa->l); - return NULL; + goto bad; } /* check DOI */ if (check_doi(ntohl(sab->doi)) < 0) - return NULL; + goto bad; /* check SITUATION */ if (check_situation(ntohl(sab->sit)) < 0) - return NULL; + goto bad; pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair)); if (pair == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer.\n"); - return NULL; + goto bad; } memset(pair, 0, sizeof(pair)); @@ -1305,7 +1340,7 @@ get_proppair(sa, mode) pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, tlen); if (pbuf == NULL) - return NULL; + goto bad; for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; @@ -1315,7 +1350,7 @@ get_proppair(sa, mode) plog(LLV_ERROR, LOCATION, NULL, "Invalid payload type=%u\n", pa->type); vfree(pbuf); - return NULL; + goto bad; } prop = (struct isakmp_pl_p *)pa->ptr; @@ -1328,7 +1363,7 @@ get_proppair(sa, mode) plog(LLV_ERROR, LOCATION, NULL, "invalid proposal with length %d\n", proplen); vfree(pbuf); - return NULL; + goto bad; } /* check Protocol ID */ @@ -1348,7 +1383,7 @@ get_proppair(sa, mode) /* get transform */ if (get_transform(prop, pair, &num_p) < 0) { vfree(pbuf); - return NULL; + goto bad; } } vfree(pbuf); @@ -1410,10 +1445,14 @@ get_proppair(sa, mode) if (num_p <= 0) { plog(LLV_ERROR, LOCATION, NULL, "no Proposal found.\n"); - return NULL; + goto bad; } return pair; +bad: + if (pair != NULL) + racoon_free(pair); + return NULL; } /* @@ -1658,8 +1697,8 @@ get_sabysaprop(pp0, sa0) struct saprop *pp0; vchar_t *sa0; { - struct prop_pair **pair; - vchar_t *newsa; + struct prop_pair **pair = NULL; + vchar_t *newsa = NULL; int newtlen; u_int8_t *np_p = NULL; struct prop_pair *p = NULL; @@ -1668,17 +1707,18 @@ get_sabysaprop(pp0, sa0) struct satrns *tr; int prophlen, trnslen; caddr_t bp; + int error = -1; /* get proposal pair */ pair = get_proppair(sa0, IPSECDOI_TYPE_PH2); if (pair == NULL) - return NULL; + goto out; newtlen = sizeof(struct ipsecdoi_sa_b); for (pp = pp0; pp; pp = pp->next) { if (pair[pp->prop_no] == NULL) - return NULL; + goto out; for (pr = pp->head; pr; pr = pr->next) { newtlen += (sizeof(struct isakmp_pl_p) @@ -1690,7 +1730,7 @@ get_sabysaprop(pp0, sa0) break; } if (p == NULL) - return NULL; + goto out; newtlen += ntohs(p->trns->h.len); } @@ -1700,7 +1740,7 @@ get_sabysaprop(pp0, sa0) newsa = vmalloc(newtlen); if (newsa == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n"); - return NULL; + goto out; } bp = newsa->v; @@ -1721,7 +1761,7 @@ get_sabysaprop(pp0, sa0) break; } if (p == NULL) - return NULL; + goto out; trnslen = ntohs(p->trns->h.len); @@ -1746,6 +1786,18 @@ get_sabysaprop(pp0, sa0) } } + error = 0; +out: + if (pair != NULL) + racoon_free(pair); + + if (error != 0) { + if (newsa != NULL) { + vfree(newsa); + newsa = NULL; + } + } + return newsa; } @@ -2085,20 +2137,32 @@ check_attr_isakmp(trns) case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: -#endif + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: +#if 0 /* Clashes with OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB */ + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: +#endif + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: break; case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: #endif case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: plog(LLV_ERROR, LOCATION, NULL, - "auth method %d isn't supported.\n", - lorv); + "auth method %s isn't supported.\n", + s_oakley_attr_method(lorv)); return -1; default: plog(LLV_ERROR, LOCATION, NULL, @@ -2804,8 +2868,8 @@ setph1attr(sa, buf) else attrlen += sa->gssid->l * 2; if (buf) { - plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %d, " - "val '%.*s'\n", sa->gssid->l, sa->gssid->l, + plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %zu, " + "val '%.*s'\n", sa->gssid->l, (int)sa->gssid->l, sa->gssid->v); if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) { p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID, @@ -3139,7 +3203,7 @@ ipsecdoi_setph2proposal(iph2) #ifdef __APPLE__ /* - * return 1 if all of the given protocols are transport mode. + * return 1 if all of the given protocols are tunnel mode. */ int ipsecdoi_tunnelmode(iph2) @@ -3159,6 +3223,27 @@ ipsecdoi_tunnelmode(iph2) return 1; } + +/* + * return 1 if any of the given protocols are transport mode. + */ +int +ipsecdoi_any_transportmode(pp) +struct saprop *pp; +{ + struct saproto *pr = NULL; + + for (; pp; pp = pp->next) { + for (pr = pp->head; pr; pr = pr->next) { + if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TRNS || + pr->encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC || + pr->encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT) + return 1; + } + } + + return 0; +} #endif /* @@ -3264,6 +3349,259 @@ doi2ipproto(proto) return -1; /* XXX */ } +/* + * Check if a subnet id is valid for comparison + * with an address id ( address length mask ) + * and compare them + * Return value + * = 0 for match + * = 1 for mismatch + */ + +int +ipsecdoi_subnetisaddr_v4( subnet, address ) + const vchar_t *subnet; + const vchar_t *address; +{ + struct in_addr *mask; + + if (address->l != sizeof(struct in_addr)) + return 1; + + if (subnet->l != (sizeof(struct in_addr)*2)) + return 1; + + mask = (struct in_addr*)(subnet->v + sizeof(struct in_addr)); + + if (mask->s_addr!=0xffffffff) + return 1; + + return memcmp(subnet->v,address->v,address->l); +} + +#ifdef INET6 + +int +ipsecdoi_subnetisaddr_v6( subnet, address ) + const vchar_t *subnet; + const vchar_t *address; +{ + struct in6_addr *mask; + int i; + + if (address->l != sizeof(struct in6_addr)) + return 1; + + if (subnet->l != (sizeof(struct in6_addr)*2)) + return 1; + + mask = (struct in6_addr*)(subnet->v + sizeof(struct in6_addr)); + + for (i=0; i<16; i++) + if(mask->s6_addr[i]!=0xff) + return 1; + + return memcmp(subnet->v,address->v,address->l); +} + +#endif + +/* + * Check and Compare two IDs + * - specify 0 for exact if wildcards are allowed + * Return value + * = 0 for match + * = 1 for misatch + * = -1 for integrity error + */ + +int +ipsecdoi_chkcmpids( idt, ids, exact ) + const vchar_t *idt; /* id cmp target */ + const vchar_t *ids; /* id cmp source */ + int exact; +{ + struct ipsecdoi_id_b *id_bt; + struct ipsecdoi_id_b *id_bs; + vchar_t ident_t; + vchar_t ident_s; + int result; + + /* handle wildcard IDs */ + + if (idt == NULL || ids == NULL) + { + if( !exact ) + { + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : values matched (ANONYMOUS)\n" ); + return 0; + } + else + { + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : value mismatch (ANONYMOUS)\n" ); + return -1; + } + } + + /* make sure the ids are of the same type */ + + id_bt = (struct ipsecdoi_id_b *) idt->v; + id_bs = (struct ipsecdoi_id_b *) ids->v; + + ident_t.v = idt->v + sizeof(*id_bt); + ident_t.l = idt->l - sizeof(*id_bt); + ident_s.v = ids->v + sizeof(*id_bs); + ident_s.l = ids->l - sizeof(*id_bs); + + if (id_bs->type != id_bt->type) + { + /* + * special exception for comparing + * address to subnet id types when + * the netmask is address length + */ + + if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&& + (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) { + result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s); + goto cmpid_result; + } + + if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&& + (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) { + result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t); + goto cmpid_result; + } + +#ifdef INET6 + if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&& + (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { + result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s); + goto cmpid_result; + } + + if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&& + (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) { + result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t); + goto cmpid_result; + } +#endif + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : id type mismatch %s != %s\n", + s_ipsecdoi_ident(id_bs->type), + s_ipsecdoi_ident(id_bt->type)); + + return 1; + } + + if(id_bs->proto_id != id_bt->proto_id){ + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : proto_id mismatch %d != %d\n", + id_bs->proto_id, id_bt->proto_id); + + return 1; + } + + /* compare the ID data. */ + + switch (id_bt->type) { + case IPSECDOI_ID_DER_ASN1_DN: + case IPSECDOI_ID_DER_ASN1_GN: + /* compare asn1 ids */ + result = eay_cmp_asn1dn(&ident_t, &ident_s); + goto cmpid_result; + + case IPSECDOI_ID_IPV4_ADDR: + /* validate lengths */ + if ((ident_t.l != sizeof(struct in_addr))|| + (ident_s.l != sizeof(struct in_addr))) + goto cmpid_invalid; + break; + + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV4_ADDR_RANGE: + /* validate lengths */ + if ((ident_t.l != (sizeof(struct in_addr)*2))|| + (ident_s.l != (sizeof(struct in_addr)*2))) + goto cmpid_invalid; + break; + +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + /* validate lengths */ + if ((ident_t.l != sizeof(struct in6_addr))|| + (ident_s.l != sizeof(struct in6_addr))) + goto cmpid_invalid; + break; + + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR_RANGE: + /* validate lengths */ + if ((ident_t.l != (sizeof(struct in6_addr)*2))|| + (ident_s.l != (sizeof(struct in6_addr)*2))) + goto cmpid_invalid; + break; +#endif + case IPSECDOI_ID_FQDN: + case IPSECDOI_ID_USER_FQDN: + case IPSECDOI_ID_KEY_ID: + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "Unhandled id type %i specified for comparison\n", + id_bt->type); + return -1; + } + + /* validate matching data and length */ + if (ident_t.l == ident_s.l) + result = memcmp(ident_t.v,ident_s.v,ident_t.l); + else + result = 1; + +cmpid_result: + + /* debug level output */ + if(loglevel >= LLV_DEBUG) { + char *idstrt = ipsecdoi_id2str(idt); + char *idstrs = ipsecdoi_id2str(ids); + + if (!result) + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : values matched (%s)\n", + s_ipsecdoi_ident(id_bs->type) ); + else + plog(LLV_DEBUG, LOCATION, NULL, + "check and compare ids : value mismatch (%s)\n", + s_ipsecdoi_ident(id_bs->type)); + + plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: \'%s\'\n", idstrt ); + plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: \'%s\'\n", idstrs ); + + racoon_free(idstrs); + racoon_free(idstrt); + } + + /* return result */ + if( !result ) + return 0; + else + return 1; + +cmpid_invalid: + + /* id integrity error */ + plog(LLV_DEBUG, LOCATION, NULL, "check and compare ids : %s integrity error\n", + s_ipsecdoi_ident(id_bs->type)); + plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: length = \'%zu\'\n", ident_t.l ); + plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: length = \'%zu\'\n", ident_s.l ); + + return -1; +} + /* * check the following: * - In main mode with pre-shared key, only address type can be used. @@ -3328,7 +3666,7 @@ ipsecdoi_checkid1(iph1) } /* if phase 1 ID payload conformed RFC2407 4.6.2. */ - if (id_b->type == IPSECDOI_ID_IPV4_ADDR || // %%%% BUG_FIX - should be || not && + if (id_b->type == IPSECDOI_ID_IPV4_ADDR || id_b->type == IPSECDOI_ID_IPV6_ADDR) { if (id_b->proto_id == 0 && ntohs(id_b->port) != 0) { @@ -3393,9 +3731,8 @@ ipsecdoi_checkid1(iph1) switch (id->idtype) { case IDTYPE_ASN1DN: - ident.v = (caddr_t)(id_b + 1); - ident.l = iph1->id_p->l - 1; /* had ident.l = ident0->l; but why?? */ - /* is the actual packet contents length sometimes wrong? */ + ident.v = iph1->id_p->v + sizeof(*id_b); + ident.l = iph1->id_p->l - sizeof(*id_b); if (eay_cmp_asn1dn(ident0, &ident) == 0) goto matched; break; @@ -3591,6 +3928,15 @@ int set_identifier(vpp, type, value) vchar_t **vpp, *value; int type; +{ + return set_identifier_qual(vpp, type, value, IDQUAL_UNSPEC); +} + +int +set_identifier_qual(vpp, type, value, qual) + vchar_t **vpp, *value; + int type; + int qual; { vchar_t *new = NULL; @@ -3625,31 +3971,55 @@ set_identifier(vpp, type, value) memcpy(new->v, value->v, new->l); break; case IDTYPE_KEYID: - { - FILE *fp; - char b[512]; - int tlen, len; - - fp = fopen(value->v, "r"); - if (fp == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "can not open %s\n", value->v); - return -1; + /* + * If no qualifier is specified: IDQUAL_UNSPEC. It means + * to use a file for backward compatibility sake. + */ + switch(qual) { + case IDQUAL_FILE: + case IDQUAL_UNSPEC: { + FILE *fp; + char b[512]; + int tlen, len; + + fp = fopen(value->v, "r"); + if (fp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "can not open %s\n", value->v); + return -1; + } + tlen = 0; + while ((len = fread(b, 1, sizeof(b), fp)) != 0) { + new = vrealloc(new, tlen + len); + if (!new) { + fclose(fp); + return -1; + } + memcpy(new->v + tlen, b, len); + tlen += len; + } + fclose(fp); + break; } - tlen = 0; - while ((len = fread(b, 1, sizeof(b), fp)) != 0) { - new = vrealloc(new, tlen + len); - if (!new) { - fclose(fp); + + case IDQUAL_TAG: + new = vmalloc(value->l - 1); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "can not allocate memory"); return -1; } - memcpy(new->v + tlen, b, len); - tlen += len; + memcpy(new->v, value->v, new->l); + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unknown qualifier"); + return -1; } break; - } - case IDTYPE_ADDRESS: - { + + case IDTYPE_ADDRESS: { struct sockaddr *sa; /* length is adjusted since QUOTEDSTRING teminates NULL. */ @@ -3664,9 +4034,12 @@ set_identifier(vpp, type, value) } new = vmalloc(sysdep_sa_len(sa)); - if (new == NULL) + if (new == NULL) { + racoon_free(sa); return -1; + } memcpy(new->v, sa, new->l); + racoon_free(sa); break; } case IDTYPE_ASN1DN: @@ -3779,13 +4152,7 @@ ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto) switch (saddr->sa_family) { case AF_INET: len1 = sizeof(struct in_addr); - if ( -#if 0 - prefixlen == ~0 -#else - prefixlen == (sizeof(struct in_addr) << 3) -#endif - ) { + if (prefixlen == (sizeof(struct in_addr) << 3)) { type = IPSECDOI_ID_IPV4_ADDR; len2 = 0; } else { @@ -3798,13 +4165,7 @@ ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto) #ifdef INET6 case AF_INET6: len1 = sizeof(struct in6_addr); - if ( -#if 0 - prefixlen == ~0 -#else - prefixlen == (sizeof(struct in6_addr) << 3) -#endif - ) { + if (prefixlen == (sizeof(struct in6_addr) << 3)) { type = IPSECDOI_ID_IPV6_ADDR; len2 = 0; } else { @@ -3865,6 +4226,71 @@ ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto) return new; } +vchar_t * +ipsecdoi_sockrange2id(laddr, haddr, ul_proto) + struct sockaddr *laddr, *haddr; + u_int ul_proto; +{ + vchar_t *new; + int type, len1, len2; + u_short port; + + if (laddr->sa_family != haddr->sa_family) { + plog(LLV_ERROR, LOCATION, NULL, "Address family mismatch\n"); + return NULL; + } + + switch (laddr->sa_family) { + case AF_INET: + type = IPSECDOI_ID_IPV4_ADDR_RANGE; + len1 = sizeof(struct in_addr); + len2 = sizeof(struct in_addr); + break; +#ifdef INET6 + case AF_INET6: + type = IPSECDOI_ID_IPV6_ADDR_RANGE; + len1 = sizeof(struct in6_addr); + len2 = sizeof(struct in6_addr); + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid family: %d.\n", laddr->sa_family); + return NULL; + } + + /* get ID buffer */ + new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2); + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get ID buffer.\n"); + return NULL; + } + + memset(new->v, 0, new->l); + /* set the part of header. */ + ((struct ipsecdoi_id_b *)new->v)->type = type; + + /* set ul_proto and port */ + /* + * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card + * because 0 means port number of 0. Instead of 0, we use IPSEC_*_ANY. + */ + ((struct ipsecdoi_id_b *)new->v)->proto_id = + ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto; + port = ((struct sockaddr_in *)(laddr))->sin_port; + ((struct ipsecdoi_id_b *)new->v)->port = + port == IPSEC_PORT_ANY ? 0 : port; + memcpy(new->v + sizeof(struct ipsecdoi_id_b), + (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr, + len1); + memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1, + (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr, + len2); + return new; +} + + /* * create sockaddr structure from ID payload (buf). * buffers (saddr, prefixlen, ul_proto) must be allocated. @@ -3965,9 +4391,9 @@ ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto) + alen; for (; *p == 0xff; p++) { + plen += 8; if (plen >= max) break; - plen += 8; } if (plen < max) { @@ -3997,16 +4423,210 @@ ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto) /* * make printable string from ID payload except of general header. */ -const char * +char * ipsecdoi_id2str(id) const vchar_t *id; { - static char buf[256]; +#define BUFLEN 512 + char * ret = NULL; + int len = 0; + char *dat; + static char buf[BUFLEN]; + struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v; + struct sockaddr_storage saddr; + u_int plen = 0; + + bzero(&saddr, sizeof(saddr)); + + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR: + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV4_ADDR_RANGE: + +#ifndef __linux__ + ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in); +#endif + ((struct sockaddr *)&saddr)->sa_family = AF_INET; + ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, + id->v + sizeof(*id_b), sizeof(struct in_addr)); + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR_RANGE: + +#ifndef __linux__ + ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in6); +#endif + ((struct sockaddr *)&saddr)->sa_family = AF_INET6; + ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr, + id->v + sizeof(*id_b), sizeof(struct in6_addr)); + break; +#endif + } + + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR: +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: +#endif + len = snprintf( buf, sizeof(buf), "%s", saddrwop2str((struct sockaddr *)&saddr)); + break; - /* XXX */ - buf[0] = '\0'; + case IPSECDOI_ID_IPV4_ADDR_SUBNET: +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_SUBNET: +#endif + { + u_char *p; + u_int max; + int alen = sizeof(struct in_addr); - return buf; + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + alen = sizeof(struct in_addr); + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + alen = sizeof(struct in6_addr); + break; +#endif + } + + /* sanity check */ + if (id->l < alen) { + len = 0; + break; + } + + /* get subnet mask length */ + plen = 0; + max = alen <<3; + + p = (unsigned char *) id->v + + sizeof(struct ipsecdoi_id_b) + + alen; + + for (; *p == 0xff; p++) { + plen += 8; + if (plen >= max) + break; + } + + if (plen < max) { + u_int l = 0; + u_char b = ~(*p); + + while (b) { + b >>= 1; + l++; + } + + l = 8 - l; + plen += l; + } + + len = snprintf( buf, sizeof(buf), "%s/%i", saddrwop2str((struct sockaddr *)&saddr), plen); + } + break; + + case IPSECDOI_ID_IPV4_ADDR_RANGE: + + len = snprintf( buf, sizeof(buf), "%s-", saddrwop2str((struct sockaddr *)&saddr)); + +#ifndef __linux__ + ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in); +#endif + ((struct sockaddr *)&saddr)->sa_family = AF_INET; + ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, + id->v + sizeof(*id_b) + sizeof(struct in_addr), + sizeof(struct in_addr)); + + if (len >= 0) { + len += snprintf( buf + len, sizeof(buf) - len, "%s", saddrwop2str((struct sockaddr *)&saddr)); + } + + break; + +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_RANGE: + + len = snprintf( buf, sizeof(buf), "%s-", saddrwop2str((struct sockaddr *)&saddr)); + +#ifndef __linux__ + ((struct sockaddr *)&saddr)->sa_len = sizeof(struct sockaddr_in6); +#endif + ((struct sockaddr *)&saddr)->sa_family = AF_INET6; + ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr, + id->v + sizeof(*id_b) + sizeof(struct in6_addr), + sizeof(struct in6_addr)); + + if (len >= 0) { + len += snprintf( buf + len, sizeof(buf) - len, "%s", saddrwop2str((struct sockaddr *)&saddr)); + } + + break; +#endif + + case IPSECDOI_ID_FQDN: + case IPSECDOI_ID_USER_FQDN: + len = id->l - sizeof(*id_b); + if (len > BUFLEN) + len = BUFLEN; + memcpy(buf, id->v + sizeof(*id_b), len); + break; + + case IPSECDOI_ID_DER_ASN1_DN: + case IPSECDOI_ID_DER_ASN1_GN: + { + X509_NAME *xn = NULL; + + dat = id->v + sizeof(*id_b); + len = id->l - sizeof(*id_b); + + if (d2i_X509_NAME(&xn, (void*) &dat, len) != NULL) { + BIO *bio = BIO_new(BIO_s_mem()); + X509_NAME_print_ex(bio, xn, 0, 0); + len = BIO_get_mem_data(bio, &dat); + if (len > BUFLEN) + len = BUFLEN; + memcpy(buf,dat,len); + BIO_free(bio); + X509_NAME_free(xn); + } else { + plog(LLV_ERROR, LOCATION, NULL, + "unable to extract asn1dn from id\n"); + + len = snprintf(buf, sizeof(buf), ""); + } + + break; + } + + /* currently unhandled id types */ + case IPSECDOI_ID_KEY_ID: + len = snprintf( buf, sizeof(buf), ""); + break; + + default: + plog(LLV_ERROR, LOCATION, NULL, + "unknown ID type %d\n", id_b->type); + } + + if (!len) + len = snprintf( buf, sizeof(buf), ""); + + ret = racoon_malloc(len+1); + if (ret != NULL) { + memcpy(ret,buf,len); + ret[len]=0; + } + + return ret; } /* @@ -4265,9 +4885,6 @@ static int rm_idtype2doi[] = { 255, /* IDTYPE_ADDRESS, 4 * it expands into 4 types by another function. */ IPSECDOI_ID_DER_ASN1_DN, /* IDTYPE_ASN1DN, 5 */ -#ifdef ENABLE_HYBRID - 255, /* IDTYPE_LOGIN, 6 */ -#endif }; /* @@ -4323,16 +4940,16 @@ switch_authmethod(authmethod) case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I; break; - /* Those are not implemented */ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; break; - case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: - authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I; - break; case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; break; + /* Those are not implemented */ + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I; + break; case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I; break; diff --git a/ipsec-tools/racoon/ipsec_doi.h b/ipsec-tools/racoon/ipsec_doi.h index 9d5e7a9..ff07bd3 100644 --- a/ipsec-tools/racoon/ipsec_doi.h +++ b/ipsec-tools/racoon/ipsec_doi.h @@ -200,6 +200,12 @@ struct ipsecdoi_pl_id { #define VERIFICATION_OPTION_OPEN_DIR 2 #endif +/* qualifiers for KEYID (and maybe others) */ +#define IDQUAL_UNSPEC 0 +#define IDQUAL_FILE 1 +#define IDQUAL_TAG 2 + + /* The use for checking proposal payload. This is not exchange type. */ #define IPSECDOI_TYPE_PH1 0 #define IPSECDOI_TYPE_PH2 1 @@ -219,20 +225,25 @@ extern struct prop_pair **get_proppair __P((vchar_t *, int)); extern vchar_t *get_sabyproppair __P((struct prop_pair *, struct ph1handle *)); extern int ipsecdoi_updatespi __P((struct ph2handle *iph2)); extern vchar_t *get_sabysaprop __P((struct saprop *, vchar_t *)); +extern int ipsecdoi_chkcmpids( const vchar_t *, const vchar_t *, int ); extern int ipsecdoi_checkid1 __P((struct ph1handle *)); extern int ipsecdoi_setid1 __P((struct ph1handle *)); extern int set_identifier __P((vchar_t **, int, vchar_t *)); +extern int set_identifier_qual __P((vchar_t **, int, vchar_t *, int)); extern int ipsecdoi_setid2 __P((struct ph2handle *)); extern vchar_t *ipsecdoi_sockaddr2id __P((struct sockaddr *, u_int, u_int)); extern int ipsecdoi_id2sockaddr __P((vchar_t *, struct sockaddr *, u_int8_t *, u_int16_t *)); -extern const char *ipsecdoi_id2str __P((const vchar_t *)); +extern char *ipsecdoi_id2str __P((const vchar_t *)); +extern vchar_t *ipsecdoi_sockrange2id __P(( struct sockaddr *, + struct sockaddr *, u_int)); extern vchar_t *ipsecdoi_setph1proposal __P((struct isakmpsa *)); extern int ipsecdoi_setph2proposal __P((struct ph2handle *)); extern int ipsecdoi_transportmode __P((struct saprop *)); #ifdef __APPLE__ extern int ipsecdoi_tunnelmode __P((struct ph2handle *)); +extern int ipsecdoi_any_transportmode __P((struct saprop *)); #endif extern int ipsecdoi_get_defaultlifetime __P((void)); extern int ipsecdoi_checkalgtypes __P((int, int, int, int)); diff --git a/ipsec-tools/racoon/isakmp.c b/ipsec-tools/racoon/isakmp.c index dc58420..7d8e24e 100644 --- a/ipsec-tools/racoon/isakmp.c +++ b/ipsec-tools/racoon/isakmp.c @@ -1,4 +1,6 @@ -/* $Id: isakmp.c,v 1.34.2.21 2006/02/02 10:31:01 vanhu Exp $ */ +/* $NetBSD: isakmp.c,v 1.20.6.7 2007/08/01 11:52:20 vanhu Exp $ */ + +/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -67,7 +69,9 @@ #include #endif #include -#include +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -101,7 +105,9 @@ #include "vpn_control.h" #include "vpn_control_var.h" #ifdef ENABLE_HYBRID +#include "vendorid.h" #include "isakmp_xauth.h" +#include "isakmp_unity.h" #include "isakmp_cfg.h" #endif #ifdef ENABLE_FRAG @@ -109,22 +115,29 @@ #endif #include "strnames.h" +#include + #ifdef ENABLE_NATT # include "nattraversal.h" +#endif +#include "ike_session.h" # ifdef __linux__ # include -#include - +# include # ifndef SOL_UDP # define SOL_UDP 17 # endif # endif /* __linux__ */ -# if defined(__NetBSD__) || defined(__FreeBSD__) +# if defined(__NetBSD__) || defined(__FreeBSD__) || \ + (defined(__APPLE__) && defined(__MACH__)) # include # include +# include +# include # define SOL_UDP IPPROTO_UDP # endif /* __NetBSD__ / __FreeBSD__ */ -#endif +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" static int nostate1 __P((struct ph1handle *, vchar_t *)); static int nostate2 __P((struct ph2handle *, vchar_t *)); @@ -162,7 +175,7 @@ static int (*ph2exchange[][2][PHASE2ST_MAX]) __P((struct ph2handle *, vchar_t *)) = { /* error */ { {}, {}, }, - /* Quick mode for IKE*/ + /* Quick mode for IKE */ { { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send, quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, }, @@ -198,6 +211,13 @@ isakmp_handler(so_isakmp) union { char buf[sizeof (isakmp) + 4]; u_int32_t non_esp[2]; + char lbuf[sizeof(struct udphdr) + +#ifdef __linux + sizeof(struct iphdr) + +#else + sizeof(struct ip) + +#endif + sizeof(isakmp) + 4]; } x; struct sockaddr_storage remote; struct sockaddr_storage local; @@ -228,10 +248,32 @@ isakmp_handler(so_isakmp) plog(LLV_ERROR, LOCATION, NULL, "failed to receive keep alive packet: %s\n", strerror (errno)); - } + } goto end; } + /* Lucent IKE in UDP encapsulation */ + { + struct udphdr *udp; +#ifdef __linux__ + struct iphdr *ip; + + udp = (struct udphdr *)&x.lbuf[0]; + if (ntohs(udp->dest) == 501) { + ip = (struct iphdr *)(x.lbuf + sizeof(*udp)); + extralen += sizeof(*udp) + ip->ihl; + } +#else + struct ip *ip; + + udp = (struct udphdr *)&x.lbuf[0]; + if (ntohs(udp->uh_dport) == 501) { + ip = (struct ip *)(x.lbuf + sizeof(*udp)); + extralen += sizeof(*udp) + ip->ip_hl; + } +#endif + } + #ifdef ENABLE_NATT /* we don't know about portchange yet, look for non-esp marker instead */ @@ -309,8 +351,6 @@ isakmp_handler(so_isakmp) memcpy (buf->v, tmpbuf->v + extralen, buf->l); - vfree (tmpbuf); - len -= extralen; if (len != buf->l) { @@ -370,6 +410,8 @@ isakmp_handler(so_isakmp) error = 0; end: + if (tmpbuf != NULL) + vfree(tmpbuf); if (buf != NULL) vfree(buf); @@ -447,6 +489,10 @@ isakmp_main(msg, remote, local) /* validity check */ if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 && iph1->side == INITIATOR) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("malformed or unexpected cookie"), + CONSTSTR("Failed to process packet (malformed/unexpected cookie)")); plog(LLV_DEBUG, LOCATION, remote, "malformed cookie received or " "the initiator's cookies collide.\n"); @@ -463,10 +509,34 @@ isakmp_main(msg, remote, local) /* prevent memory leak */ racoon_free(iph1->remote); racoon_free(iph1->local); + iph1->remote = NULL; + iph1->local = NULL; /* copy-in new addresses */ iph1->remote = dupsaddr(remote); + if (iph1->remote == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("failed to duplicate remote address"), + CONSTSTR("Failed to process phase1 message (can't duplicate remote address")); + plog(LLV_ERROR, LOCATION, iph1->remote, + "phase1 failed: dupsaddr failed.\n"); + remph1(iph1); + delph1(iph1); + return -1; + } iph1->local = dupsaddr(local); + if (iph1->local == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("failed to duplicate local address"), + CONSTSTR("Failed to process phase1 message (can't duplicate local address")); + plog(LLV_ERROR, LOCATION, iph1->remote, + "phase1 failed: dupsaddr failed.\n"); + remph1(iph1); + delph1(iph1); + return -1; + } /* set the flag to prevent further port floating (FIXME: should we allow it? E.g. when the NAT gw @@ -487,8 +557,10 @@ isakmp_main(msg, remote, local) if (cmpsaddrstrict(iph1->remote, remote) != 0) { char *saddr_db, *saddr_act; - saddr_db = strdup(saddr2str(iph1->remote)); - saddr_act = strdup(saddr2str(remote)); + saddr_db = racoon_strdup(saddr2str(iph1->remote)); + saddr_act = racoon_strdup(saddr2str(remote)); + STRDUP_FATAL(saddr_db); + STRDUP_FATAL(saddr_act); plog(LLV_WARNING, LOCATION, remote, "remote address mismatched. db=%s, act=%s\n", @@ -504,6 +576,12 @@ isakmp_main(msg, remote, local) */ /* XXX more acceptable check */ + +#ifdef ENABLE_DPD + // received ike packets: update dpd checks + isakmp_reschedule_info_monitor_if_pending(iph1, + "ike packets received from peer"); +#endif /* DPD */ } switch (isakmp->etype) { @@ -548,6 +626,10 @@ isakmp_main(msg, remote, local) /* it must be the 2nd message from the responder. */ if (iph1->side != INITIATOR) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("malformed cookie and unexpected side"), + CONSTSTR("Failed to process phase1 message (unexpected side)")); plog(LLV_DEBUG, LOCATION, remote, "malformed cookie received. " "it has to be as the initiator. %s\n", @@ -562,6 +644,10 @@ isakmp_main(msg, remote, local) * authencication completed. */ if (iph1->etype != isakmp->etype) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("mismatched exchange type"), + CONSTSTR("Failed to process phase1 message (mismatched exchange type)")); plog(LLV_ERROR, LOCATION, iph1->remote, "exchange type is mismatched: " "db=%s packet=%s, ignore it.\n", @@ -639,7 +725,13 @@ isakmp_main(msg, remote, local) isakmp->msgid)); return -1; } - +#ifdef ENABLE_HYBRID + /* Reinit the IVM if it's still there */ + if (iph1->mode_cfg && iph1->mode_cfg->ivm) { + oakley_delivm(iph1->mode_cfg->ivm); + iph1->mode_cfg->ivm = NULL; + } +#endif #ifdef ENABLE_FRAG if (isakmp->np == ISAKMP_NPTYPE_FRAG) return frag_handler(iph1, msg, remote, local); @@ -647,6 +739,10 @@ isakmp_main(msg, remote, local) /* check status of phase 1 whether negotiated or not. */ if (iph1->status != PHASE1ST_ESTABLISHED) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP, + CONSTSTR("can't start phase2 without valid phase1"), + CONSTSTR("Failed to start phase2 resonder (no established phase1")); plog(LLV_ERROR, LOCATION, remote, "can't start the quick mode, " "there is no valid ISAKMP-SA, %s\n", @@ -741,9 +837,12 @@ ph1_main(iph1, msg) vchar_t *msg; { int error; + int ini_contact = iph1->rmconf->ini_contact; #ifdef ENABLE_STATS struct timeval start, end; #endif + int spi_cmp; + u_int rekey_lifetime; /* ignore a packet */ if (iph1->status == PHASE1ST_ESTABLISHED) @@ -756,6 +855,10 @@ ph1_main(iph1, msg) if (ph1exchange[etypesw1(iph1->etype)] [iph1->side] [iph1->status] == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("unavailable function"), + CONSTSTR("Failed to process phase1 message (no state function)")); plog(LLV_ERROR, LOCATION, iph1->remote, "why isn't the function defined.\n"); return -1; @@ -764,6 +867,7 @@ ph1_main(iph1, msg) [iph1->side] [iph1->status])(iph1, msg); if (error != 0) { + /* XXX * When an invalid packet is received on phase1, it should * be selected to process this packet. That is to respond @@ -772,7 +876,7 @@ ph1_main(iph1, msg) * acting as RESPONDER we must not keep phase 1 handler or else * it will stay forever. */ - + if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) { plog(LLV_ERROR, LOCATION, iph1->remote, "failed to pre-process packet.\n"); @@ -783,17 +887,19 @@ ph1_main(iph1, msg) } } +#ifndef ENABLE_FRAG /* free resend buffer */ if (iph1->sendbuf == NULL) { plog(LLV_ERROR, LOCATION, NULL, "no buffer found as sendbuf\n"); return -1; } +#endif + VPTRINIT(iph1->sendbuf); /* turn off schedule */ - if (iph1->scr) - SCHED_KILL(iph1->scr); + SCHED_KILL(iph1->scr); /* send */ plog(LLV_DEBUG, LOCATION, NULL, "===\n"); @@ -822,45 +928,80 @@ ph1_main(iph1, msg) #ifdef ENABLE_VPNCONTROL_PORT - if (iph1->side == RESPONDER && - iph1->local->sa_family == AF_INET) { - - struct redirect *addr; - - LIST_FOREACH(addr, &lcconf->redirect_addresses, chain) { - if (((struct sockaddr_in *)iph1->local)->sin_addr.s_addr == addr->cluster_address) { - vchar_t *raddr = vmalloc(sizeof(u_int32_t)); + if (iph1->side == RESPONDER && + iph1->local->sa_family == AF_INET) { + + struct redirect *addr; - if (raddr == NULL) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "failed to send redirect message - memory error.\n"); - } else { - memcpy(raddr->v, &addr->redirect_address, sizeof(u_int32_t)); - (void)isakmp_info_send_n1(iph1, ISAKMP_NTYPE_LOAD_BALANCE, raddr); - plog(LLV_DEBUG, LOCATION, iph1->remote, "sent redirect notification - address = %x.\n", ntohl(addr->redirect_address)); - vfree(raddr); - if (addr->force) - isakmp_ph1delete(iph1); + LIST_FOREACH(addr, &lcconf->redirect_addresses, chain) { + if (((struct sockaddr_in *)iph1->local)->sin_addr.s_addr == addr->cluster_address) { + vchar_t *raddr = vmalloc(sizeof(u_int32_t)); + + if (raddr == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to send redirect message - memory error.\n"); + } else { + memcpy(raddr->v, &addr->redirect_address, sizeof(u_int32_t)); + (void)isakmp_info_send_n1(iph1, ISAKMP_NTYPE_LOAD_BALANCE, raddr); + plog(LLV_DEBUG, LOCATION, iph1->remote, "sent redirect notification - address = %x.\n", ntohl(addr->redirect_address)); + vfree(raddr); + if (addr->force) { + (void)ike_session_update_ph1_ph2tree(iph1); + isakmp_ph1delete(iph1); + } + } } + return 0; } - return 0; } - } #endif /* save created date. */ (void)time(&iph1->created); /* add to the schedule to expire, and save back pointer. */ iph1->sce = sched_new(iph1->approval->lifetime, - isakmp_ph1expire_stub, iph1); + isakmp_ph1expire_stub, iph1); + + if (iph1->rmconf->initiate_ph1rekey) { + if (iph1->side == INITIATOR) { + spi_cmp = memcmp(&iph1->index.i_ck, &iph1->index.r_ck, sizeof(iph1->index.i_ck)); + if (spi_cmp == 0) + spi_cmp = 1; + } else { + spi_cmp = memcmp(&iph1->index.r_ck, &iph1->index.i_ck, sizeof(iph1->index.r_ck)); + if (spi_cmp == 0) + spi_cmp = -1; + } + rekey_lifetime = ike_session_get_rekey_lifetime((spi_cmp > 0), + iph1->approval->lifetime); + if (rekey_lifetime) { + iph1->sce_rekey = sched_new(rekey_lifetime, + isakmp_ph1rekeyexpire_stub, + iph1); + } else { + /* iph1->approval->lifetime is too small (e.g. 1) so why bother? + * LOG ERROR + */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "failed to get rekey timer - lifetime is too small... probably.\n"); + } + } + #ifdef ENABLE_HYBRID - if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { - switch(iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + /* ignore xauth if it is a rekey */ + if (!iph1->is_rekey && + iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + switch(AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: xauth_sendreq(iph1); /* XXX Don't process INITIAL_CONTACT */ - iph1->rmconf->ini_contact = 0; + ini_contact = 0; break; default: break; @@ -874,9 +1015,9 @@ ph1_main(iph1, msg) #endif /* INITIAL-CONTACT processing */ + /* ignore initial-contact if it is a rekey */ /* don't send anything if local test mode. */ - if (!f_local - && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) { + if (!iph1->is_rekey && !f_local && ini_contact && !getcontacted(iph1->remote)) { /* send INITIAL-CONTACT */ isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INITIAL_CONTACT, NULL); @@ -891,19 +1032,37 @@ ph1_main(iph1, msg) log_ph1established(iph1); plog(LLV_DEBUG, LOCATION, NULL, "===\n"); -#ifdef ENABLE_VPNCONTROL_PORT - vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL); -#endif - - /* - * SA up shell script hook: do it now,except if - * ISAKMP mode config was requested. In the later + * SA up shell script hook: do it now for rekeys, otherwise only + * if ISAKMP mode config wasn't requested. In the later * case it is done when we receive the configuration. */ if ((iph1->status == PHASE1ST_ESTABLISHED) && - !iph1->rmconf->mode_cfg) - script_hook(iph1, SCRIPT_PHASE1_UP); + (iph1->is_rekey || !iph1->rmconf->mode_cfg)) { + switch (AUTHMETHOD(iph1)) { +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + /* Unimplemeted... */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + break; +#endif + default: + script_hook(iph1, SCRIPT_PHASE1_UP); + break; + } + } + + ike_session_cleanup_other_established_ph1s(iph1->parent_session, iph1); + +#ifdef ENABLE_VPNCONTROL_PORT + vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL); +#endif + } return 0; @@ -965,8 +1124,7 @@ quick_main(iph2, msg) VPTRINIT(iph2->sendbuf); /* turn off schedule */ - if (iph2->scr) - SCHED_KILL(iph2->scr); + SCHED_KILL(iph2->scr); /* when using commit bit, status will be reached here. */ if (iph2->status == PHASE2ST_ADDSA) //%%% BUG FIX - moved to here @@ -995,9 +1153,10 @@ quick_main(iph2, msg) /* new negotiation of phase 1 for initiator */ int -isakmp_ph1begin_i(rmconf, remote, local) +isakmp_ph1begin_i(rmconf, remote, local, started_by_api) struct remoteconf *rmconf; struct sockaddr *remote, *local; + int started_by_api; { struct ph1handle *iph1; #ifdef ENABLE_STATS @@ -1011,7 +1170,19 @@ isakmp_ph1begin_i(rmconf, remote, local) iph1->status = PHASE1ST_START; iph1->rmconf = rmconf; +#ifdef __APPLE__ + if (link_rmconf_to_ph1(rmconf) < 0) { + plog(LLV_ERROR, LOCATION, remote, + "couldn't link " + "configuration.\n"); + iph1->rmconf = NULL; + /* don't call remph1(iph1) until after insph1(iph1) is called */ + delph1(iph1); + return -1; + } +#endif iph1->side = INITIATOR; + iph1->started_by_api = started_by_api; iph1->version = ISAKMP_VERSION_NUMBER; iph1->msgid = 0; iph1->flags = 0; @@ -1020,21 +1191,38 @@ isakmp_ph1begin_i(rmconf, remote, local) iph1->gssapi_state = NULL; #endif #ifdef ENABLE_HYBRID - if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + /* don't call remph1(iph1) until after insph1(iph1) is called */ + delph1(iph1); return -1; + } #endif #ifdef ENABLE_FRAG - iph1->frag = 0; + + if(rmconf->ike_frag == ISAKMP_FRAG_FORCE) + iph1->frag = 1; + else + iph1->frag = 0; iph1->frag_chain = NULL; #endif iph1->approval = NULL; /* XXX copy remote address */ - if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + /* don't call remph1(iph1) until after insph1(iph1) is called */ + delph1(iph1); return -1; + } (void)insph1(iph1); + if (ike_session_link_ph1_to_session(iph1) != 0) { + plog(LLV_DEBUG, LOCATION, NULL, "Failed to link ph1 to session\n"); + remph1(iph1); + delph1(iph1); + return -1; + } + /* start phase 1 exchange */ iph1->etype = rmconf->etypes->type; @@ -1042,7 +1230,9 @@ isakmp_ph1begin_i(rmconf, remote, local) { char *a; - a = strdup(saddr2str(iph1->local)); + a = racoon_strdup(saddr2str(iph1->local)); + STRDUP_FATAL(a); + plog(LLV_INFO, LOCATION, NULL, "initiate new phase 1 negotiation: %s<=>%s\n", a, saddr2str(iph1->remote)); @@ -1123,8 +1313,20 @@ isakmp_ph1begin_r(msg, remote, local, etype) memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck)); iph1->status = PHASE1ST_START; iph1->rmconf = rmconf; +#ifdef __APPLE__ + if (link_rmconf_to_ph1(rmconf) < 0) { + plog(LLV_ERROR, LOCATION, remote, + "couldn't link " + "configuration.\n"); + iph1->rmconf = NULL; + /* don't call remph1(iph1) until after insph1(iph1) is called */ + delph1(iph1); + return -1; + } +#endif iph1->flags = 0; iph1->side = RESPONDER; + iph1->started_by_api = 0; iph1->etype = etypeok->type; iph1->version = isakmp->v; iph1->msgid = 0; @@ -1132,8 +1334,11 @@ isakmp_ph1begin_r(msg, remote, local, etype) iph1->gssapi_state = NULL; #endif #ifdef ENABLE_HYBRID - if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + /* don't call remph1(iph1) until after insph1(iph1) is called */ + delph1(iph1); return -1; + } #endif #ifdef ENABLE_FRAG iph1->frag = 0; @@ -1151,16 +1356,26 @@ isakmp_ph1begin_r(msg, remote, local, etype) #endif /* copy remote address */ - if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + /* don't call remph1(iph1) until after insph1(iph1) is called */ + delph1(iph1); return -1; - + } (void)insph1(iph1); + if (ike_session_link_ph1_to_session(iph1) != 0) { + remph1(iph1); + delph1(iph1); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); { char *a; - a = strdup(saddr2str(iph1->local)); + a = racoon_strdup(saddr2str(iph1->local)); + STRDUP_FATAL(a); + plog(LLV_INFO, LOCATION, NULL, "respond new phase 1 negotiation: %s<=>%s\n", a, saddr2str(iph1->remote)); @@ -1173,6 +1388,9 @@ isakmp_ph1begin_r(msg, remote, local, etype) gettimeofday(&iph1->start, NULL); gettimeofday(&start, NULL); #endif + +#ifndef ENABLE_FRAG + /* start exchange */ if ((ph1exchange[etypesw1(iph1->etype)] [iph1->side] @@ -1186,6 +1404,7 @@ isakmp_ph1begin_r(msg, remote, local, etype) delph1(iph1); return -1; } + #ifdef ENABLE_STATS gettimeofday(&end, NULL); syslog(LOG_NOTICE, "%s(%s): %8.6f", @@ -1198,6 +1417,17 @@ isakmp_ph1begin_r(msg, remote, local, etype) #endif return 0; + +#else /* ENABLE_FRAG */ + + /* now that we have a phase1 handle, feed back into our + * main receive function to catch fragmented packets + */ + + return isakmp_main(msg, remote, local); + +#endif /* ENABLE_FRAG */ + } /* new negotiation of phase 2 for initiator */ @@ -1219,7 +1449,9 @@ isakmp_ph2begin_i(iph1, iph2) plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); { char *a; - a = strdup(saddr2str(iph2->src)); + a = racoon_strdup(saddr2str(iph2->src)); + STRDUP_FATAL(a); + plog(LLV_INFO, LOCATION, NULL, "initiate new phase 2 negotiation: %s<=>%s\n", a, saddr2str(iph2->dst)); @@ -1230,15 +1462,21 @@ isakmp_ph2begin_i(iph1, iph2) gettimeofday(&iph2->start, NULL); #endif /* found isakmp-sa */ - bindph12(iph1, iph2); + if (iph2->ph1 && iph1 != iph2->ph1) { + plog(LLV_DEBUG2, LOCATION, NULL, "phase2 already bound in %s.\n",__FUNCTION__); + rebindph12(iph1, iph2); + } else if (!iph2->ph1) { + bindph12(iph1, iph2); + } + iph2->is_dying = 0; + if (ike_session_link_ph2_to_session(iph2) != 0) { + return -1; + } iph2->status = PHASE2ST_STATUS2; if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)] [iph2->side] [iph2->status])(iph2, NULL) < 0) { - unbindph12(iph2); - /* release ipsecsa handler due to internal error. */ - remph2(iph2); return -1; } @@ -1340,12 +1578,21 @@ isakmp_ph2begin_r(iph1, msg) /* add new entry to isakmp status table */ insph2(iph2); bindph12(iph1, iph2); - + iph2->is_dying = 0; + if (ike_session_link_ph2_to_session(iph2) != 0) { + unbindph12(iph2); + remph2(iph2); + delph2(iph2); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); { char *a; - a = strdup(saddr2str(iph2->src)); + a = racoon_strdup(saddr2str(iph2->src)); + STRDUP_FATAL(a); + plog(LLV_INFO, LOCATION, NULL, "respond new phase 2 negotiation: %s<=>%s\n", a, saddr2str(iph2->dst)); @@ -1507,6 +1754,7 @@ isakmp_parse(buf) } /* %%% */ +#ifndef __APPLE__ int isakmp_init() { @@ -1515,6 +1763,7 @@ isakmp_init() initph2tree(); initctdtree(); init_recvdpkt(); + ike_session_init(); if (isakmp_open() < 0) goto err; @@ -1525,6 +1774,28 @@ err: isakmp_close(); return(-1); } +#else +int +isakmp_init(int ignore_phX) +{ + /* initialize a isakmp status table */ + if (!ignore_phX) { + initph1tree(); + initph2tree(); + } + initctdtree(); + init_recvdpkt(); + + if (isakmp_open() < 0) + goto err; + + return(0); + +err: + isakmp_close(); + return(-1); +} +#endif /* __APPLE__ */ void isakmp_cleanup() @@ -1634,6 +1905,10 @@ isakmp_open() goto err_and_next; } + if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1) + plog(LLV_WARNING, LOCATION, NULL, + "failed to put socket in non-blocking mode\n"); + /* receive my interface address on inbound packets. */ switch (p->addr->sa_family) { case AF_INET: @@ -1645,7 +1920,8 @@ isakmp_open() #endif (const void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt IP_RECVDSTADDR (%s)\n", + strerror(errno)); goto err_and_next; } break; @@ -1664,12 +1940,8 @@ isakmp_open() (const void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt(%d): %s\n", + "setsockopt IPV6_RECVDSTADDR (%d):%s\n", pktinfo, strerror(errno)); - if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1) - plog(LLV_WARNING, LOCATION, NULL, - "failed to put socket in non-blocking mode\n"); - goto err_and_next; } break; @@ -1681,7 +1953,8 @@ isakmp_open() setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU, (void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt IPV6_USE_MIN_MTU (%s)\n", + strerror(errno)); return -1; } #endif @@ -1705,7 +1978,6 @@ isakmp_open() "failed to bind to address %s (%s).\n", saddr2str(p->addr), strerror(errno)); close(p->sock); - p->sock = -1; goto err_and_next; } @@ -1731,11 +2003,11 @@ isakmp_open() option = UDP_ENCAP_ESPINUDP_NON_IKE; #endif if(option != -1){ - if (setsockopt (p->sock, SOL_UDP, UDP_ENCAP, - &option, sizeof (option)) < 0) { + if (setsockopt (p->sock, SOL_UDP, + UDP_ENCAP, &option, sizeof (option)) < 0) { plog(LLV_WARNING, LOCATION, NULL, - "setsockopt(%s): %s\n", - option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE", + "setsockopt(%s): UDP_ENCAP %s\n", + option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE", strerror(errno)); goto skip_encap; } @@ -1817,11 +2089,9 @@ isakmp_close_unused() if (p->in_use == 0) { // not in use ? if (p->sock >= 0) - close(p->sock); - if (p->addr) - racoon_free(p->addr); + close(p->sock); *prev = p->next; - racoon_free(p); + delmyaddr(p); } else prev = &(p->next); } @@ -1855,7 +2125,11 @@ isakmp_send(iph1, sbuf) must added just before the packet itself. For this we must allocate a new buffer and release it at the end. */ if (extralen) { - vbuf = vmalloc (sbuf->l + extralen); + if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "vbuf allocation failed\n"); + return -1; + } *(u_int32_t *)vbuf->v = 0; memcpy (vbuf->v + extralen, sbuf->v, sbuf->l); sbuf = vbuf; @@ -1906,34 +2180,70 @@ void isakmp_ph1resend_stub(p) void *p; { - (void)isakmp_ph1resend((struct ph1handle *)p); + struct ph1handle *iph1; + + iph1=(struct ph1handle *)p; + if(isakmp_ph1resend(iph1) < 0){ + if(iph1->scr != NULL){ + /* Should not happen... + */ + sched_kill(iph1->scr); + iph1->scr=NULL; + } + + remph1(iph1); + delph1(iph1); + } } int isakmp_ph1resend(iph1) struct ph1handle *iph1; { - if (iph1->retry_counter < 0) { + /* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function + */ + if (iph1->retry_counter <= 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT, + CONSTSTR("Phase1 Maximum Retransmits"), + CONSTSTR("Phase1 negotiation failed (Maximum retransmits)")); + plog(LLV_ERROR, LOCATION, NULL, "phase1 negotiation failed due to time up. %s\n", isakmp_pindex(&iph1->index, iph1->msgid)); EVT_PUSH(iph1->local, iph1->remote, EVTT_PEER_NO_RESPONSE, NULL); - - remph1(iph1); - delph1(iph1); + if (iph1->side == INITIATOR && iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client) { + /* to get around a bug on the peer, in which rekeys to port 4500 are dropped */ + if (isakmp_ph1rekeyretry(iph1) == 0) + return 0; + } return -1; } if (isakmp_send(iph1, iph1->sendbuf) < 0){ - iph1->retry_counter--; - - iph1->scr = sched_new(iph1->rmconf->retry_interval, - isakmp_ph1resend_stub, iph1); + if (iph1->rmconf->retry_counter != iph1->retry_counter) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Phase1 Retransmit"), + CONSTSTR("Failed to retrasmit Phase1")); + } + plog(LLV_ERROR, LOCATION, iph1->remote, + "phase1 negotiation failed due to send error. %s\n", + isakmp_pindex(&iph1->index, iph1->msgid)); + EVT_PUSH(iph1->local, iph1->remote, + EVTT_PEER_NO_RESPONSE, NULL); return -1; } - plog(LLV_DEBUG, LOCATION, NULL, + if (iph1->rmconf->retry_counter != iph1->retry_counter) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Phase1 Retransmit"), + CONSTSTR(NULL)); + } + + plog(LLV_DEBUG, LOCATION, iph1->remote, "resend phase1 packet %s\n", isakmp_pindex(&iph1->index, iph1->msgid)); @@ -1950,37 +2260,73 @@ void isakmp_ph2resend_stub(p) void *p; { + struct ph2handle *iph2; + + iph2=(struct ph2handle *)p; - (void)isakmp_ph2resend((struct ph2handle *)p); + if(isakmp_ph2resend(iph2) < 0){ + unbindph12(iph2); + remph2(iph2); + delph2(iph2); + } } int isakmp_ph2resend(iph2) struct ph2handle *iph2; { - if (iph2->retry_counter < 0) { + /* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function + */ + //%%% BUG FIX - related to commit bit usage - crash happened here + if (iph2->ph1 == 0) { plog(LLV_ERROR, LOCATION, NULL, + "internal error - attempt to re-send phase2 with no phase1 bound.\n"); + return -1; + } + + if (iph2->ph1->status == PHASE1ST_EXPIRED){ + IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT, + CONSTSTR("Underlying Phase1 expired"), + CONSTSTR("Failed to retransmit phase2 (underlying phase1 expired)")); + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, + "phase2 negotiation failed due to phase1 expired. %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); + return -1; + } + + if (iph2->retry_counter <= 0) { + IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT, + CONSTSTR("Phase2 maximum retransmits"), + CONSTSTR("Phase2 negotiation failed (maximum retransmits)")); + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, "phase2 negotiation failed due to time up. %s\n", isakmp_pindex(&iph2->ph1->index, iph2->msgid)); EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL); - unbindph12(iph2); - remph2(iph2); - delph2(iph2); return -1; } - //%%% BUG FIX - related to commit bit usage - crash happened here - if (iph2->ph1 == 0) { + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){ + if (iph2->ph1->rmconf->retry_counter != iph2->retry_counter) { + IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Phase2 Retransmit"), + CONSTSTR("Failed to retransmit Phase2 message")); + } plog(LLV_ERROR, LOCATION, NULL, - "internal error - attempt to re-send phase2 with no phase1 bound.\n"); - iph2->retry_counter = -1; - remph2(iph2); - delph2(iph2); - return -1; - } + "phase2 negotiation failed due to send error. %s\n", + isakmp_pindex(&iph2->ph1->index, iph2->msgid)); + EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL); - if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) return -1; + } + if (iph2->ph1->rmconf->retry_counter != iph2->retry_counter) { + IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Phase2 Retransmit"), + CONSTSTR(NULL)); + } plog(LLV_DEBUG, LOCATION, NULL, "resend phase2 packet %s\n", @@ -1991,6 +2337,13 @@ isakmp_ph2resend(iph2) iph2->scr = sched_new(iph2->ph1->rmconf->retry_interval, isakmp_ph2resend_stub, iph2); +#ifdef ENABLE_DPD + if (iph2->scr) { + isakmp_reschedule_info_monitor_if_pending(iph2->ph1, + "phase2 packets sent to peer: retransmit timer armed"); + } +#endif /* DPD */ + return 0; } @@ -2010,10 +2363,16 @@ isakmp_ph1expire(iph1) char *src, *dst; SCHED_KILL(iph1->sce); +#ifdef ENABLE_DPD + SCHED_KILL(iph1->dpd_r_u); +#endif if(iph1->status != PHASE1ST_EXPIRED){ - src = strdup(saddr2str(iph1->local)); - dst = strdup(saddr2str(iph1->remote)); + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + plog(LLV_INFO, LOCATION, NULL, "ISAKMP-SA expired %s-%s spi:%s\n", src, dst, @@ -2021,6 +2380,7 @@ isakmp_ph1expire(iph1) racoon_free(src); racoon_free(dst); iph1->status = PHASE1ST_EXPIRED; + (void)ike_session_update_ph1_ph2tree(iph1); } /* @@ -2034,6 +2394,143 @@ isakmp_ph1expire(iph1) iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); } +/* called from scheduler */ +void +isakmp_ph1rekeyexpire_stub(p) +void *p; +{ + + isakmp_ph1rekeyexpire((struct ph1handle *)p); +} + +void +isakmp_ph1rekeyexpire(iph1) +struct ph1handle *iph1; +{ + char *src, *dst; + struct remoteconf *rmconf; + + SCHED_KILL(iph1->sce_rekey); + + // early exit if iph2->sce == NULL, iph2 isn't established or if entire session is going down + if (iph1->sce == NULL || + iph1->status != PHASE1ST_ESTABLISHED || + iph1->is_dying) { + return; + } + + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + + plog(LLV_INFO, LOCATION, NULL, + "ISAKMP-SA rekey-timer expired %s-%s spi:%s\n", + src, dst, + isakmp_pindex(&iph1->index, 0)); + racoon_free(src); + racoon_free(dst); + + // exit if there is another ph1 that is established (with a pending rekey timer) + if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) { + plog(LLV_INFO, LOCATION, iph1->remote, + "request for ISAKMP-SA rekey was ignored " + "due to another established ph1.\n"); + return; + } + + // if there is another ph1 that is negotiating, postpone this rekey for a few seconds later + if (ike_session_has_other_negoing_ph1(iph1->parent_session, iph1)) { + plog(LLV_DEBUG, LOCATION, NULL, "reschedule Phase1 rekey.\n"); + iph1->sce_rekey = sched_new(1, + isakmp_ph1rekeyexpire_stub, + iph1); + return; + } + + // get rmconf to initiate rekey with + rmconf = iph1->rmconf; + if (!rmconf || rmconf->to_delete || rmconf->to_remove) { + rmconf = getrmconf(iph1->remote); + } + if (rmconf) { + /* begin quick mode */ + plog(LLV_DEBUG, LOCATION, NULL, "begin Phase1 rekey.\n"); + + /* start phase 1 negotiation as a initiator. */ + if (isakmp_ph1begin_i(rmconf, iph1->remote, iph1->local, 0) < 0) { + plog(LLV_DEBUG, LOCATION, NULL, "Phase1 rekey Failed.\n"); + } + } else { + plog(LLV_ERROR, LOCATION, NULL, + "Phase1 rekey failed: no configuration found for %s.\n", + saddrwop2str(iph1->remote)); + } +} + +int +isakmp_ph1rekeyretry(iph1) +struct ph1handle *iph1; +{ + char *src, *dst; + struct remoteconf *rmconf; + + // this code path is meant for floated ph1 rekeys that are failing on the first message + if (iph1->sce != NULL || + iph1->sce_rekey != NULL || + (iph1->status != PHASE1ST_MSG1SENT || (iph1->natt_flags & NAT_PORTS_CHANGED == 0)) || + (extract_port(iph1->local) != PORT_ISAKMP_NATT && extract_port(iph1->remote) != PORT_ISAKMP_NATT) || + iph1->is_dying) { + return -1; + } + + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + + plog(LLV_INFO, LOCATION, NULL, + "ISAKMP-SA rekey failed... retrying %s-%s spi:%s\n", + src, dst, + isakmp_pindex(&iph1->index, 0)); + racoon_free(src); + racoon_free(dst); + + // exit if there is another ph1 that is established (with a pending rekey timer) + if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) { + plog(LLV_INFO, LOCATION, iph1->remote, + "request to retry ISAKMP-SA rekey was ignored " + "due to another established ph1.\n"); + return -1; + } + + // some servers don't like respond to 4500 for rekeys... try accomodate them + if (extract_port(iph1->local) == PORT_ISAKMP_NATT) { + set_port(iph1->local, PORT_ISAKMP); + } + if (extract_port(iph1->remote) == PORT_ISAKMP_NATT) { + set_port(iph1->remote, PORT_ISAKMP); + } + iph1->natt_flags &= ~NAT_PORTS_CHANGED; + rmconf = getrmconf(iph1->remote); + if (rmconf) { + /* begin quick mode */ + plog(LLV_DEBUG, LOCATION, NULL, "begin Phase1 rekey retry.\n"); + + /* start phase 1 negotiation as a initiator. */ + if (isakmp_ph1begin_i(rmconf, iph1->remote, iph1->local, 0) < 0) { + plog(LLV_DEBUG, LOCATION, NULL, "Phase1 rekey retry Failed.\n"); + return -1; + } + } else { + plog(LLV_ERROR, LOCATION, NULL, + "Phase1 rekey retry failed: no configuration found for %s.\n", + saddrwop2str(iph1->remote)); + return -1; + } + return 0; +} + /* called from scheduler */ void isakmp_ph1delete_stub(p) @@ -2049,18 +2546,26 @@ isakmp_ph1delete(iph1) { char *src, *dst; - if (iph1->sce) - SCHED_KILL(iph1->sce); + SCHED_KILL(iph1->sce); + SCHED_KILL(iph1->sce_rekey); +#ifdef ENABLE_DPD + SCHED_KILL(iph1->dpd_r_u); +#endif if (LIST_FIRST(&iph1->ph2tree) != NULL) { iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); return; } + isakmp_info_send_d1(iph1); + /* don't re-negosiation when the phase 1 SA expires. */ - src = strdup(saddr2str(iph1->local)); - dst = strdup(saddr2str(iph1->remote)); + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + plog(LLV_INFO, LOCATION, NULL, "ISAKMP-SA deleted %s-%s spi:%s\n", src, dst, isakmp_pindex(&iph1->index, 0)); @@ -2096,13 +2601,30 @@ isakmp_ph2expire(iph2) SCHED_KILL(iph2->sce); - src = strdup(saddrwop2str(iph2->src)); - dst = strdup(saddrwop2str(iph2->dst)); + src = racoon_strdup(saddrwop2str(iph2->src)); + dst = racoon_strdup(saddrwop2str(iph2->dst)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + plog(LLV_INFO, LOCATION, NULL, "phase2 sa expired %s-%s\n", src, dst); racoon_free(src); racoon_free(dst); + // delete outgoing SAs + if (iph2->status == PHASE2ST_ESTABLISHED && iph2->approval) { + struct saproto *pr; + + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + if (pr->ok) { + pfkey_send_delete(lcconf->sock_pfkey, + ipsecdoi2pfkey_proto(pr->proto_id), + IPSEC_MODE_ANY, + iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */); + } + } + } + iph2->status = PHASE2ST_EXPIRED; iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2); @@ -2127,8 +2649,11 @@ isakmp_ph2delete(iph2) SCHED_KILL(iph2->sce); - src = strdup(saddrwop2str(iph2->src)); - dst = strdup(saddrwop2str(iph2->dst)); + src = racoon_strdup(saddrwop2str(iph2->src)); + dst = racoon_strdup(saddrwop2str(iph2->dst)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + plog(LLV_INFO, LOCATION, NULL, "phase2 sa deleted %s-%s\n", src, dst); racoon_free(src); @@ -2154,6 +2679,8 @@ isakmp_post_acquire(iph2) { struct remoteconf *rmconf; struct ph1handle *iph1 = NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n"); /* search appropreate configuration with masking port. */ rmconf = getrmconf(iph2->dst); @@ -2173,23 +2700,29 @@ isakmp_post_acquire(iph2) return 0; } - /* - * Search isakmp status table by address and port - * If NAT-T is in use, consider null ports as a - * wildcard and use IKE ports instead. - */ -#ifdef ENABLE_NATT - if (!extract_port(iph2->src) && !extract_port(iph2->dst)) { - if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) { - set_port(iph2->src, extract_port(iph1->local)); - set_port(iph2->dst, extract_port(iph1->remote)); - } - } else { - iph1 = getph1byaddr(iph2->src, iph2->dst); + if (ike_session_verify_ph2_parent_session(iph2)) { + plog(LLV_INFO, LOCATION, iph2->dst, + "request for establishing IPsec-SA was ignored " + "because there was a failure verifying parent session.\n"); + return -1; } -#else - iph1 = getph1byaddr(iph2->src, iph2->dst); -#endif + + // what if there is another ph2 that is negotiating + if (ike_session_has_other_negoing_ph2(iph2->parent_session, iph2)) { + // TODO: postpone this rekey for a second later + plog(LLV_INFO, LOCATION, iph2->dst, + "request for establishing IPsec-SA was ignored " + "due to another negoing ph2.\n"); + return -1; + } + + // if this is a phase2 rekeys (the policy may not have the current port number). + // so, use the appropriate ports. + if (iph2->is_rekey) { + ike_session_update_ph2_ports(iph2); + } + + iph1 = ike_session_update_ph2_ph1bind(iph2); /* no ISAKMP-SA found. */ if (iph1 == NULL) { @@ -2203,7 +2736,7 @@ isakmp_post_acquire(iph2) saddrwop2str(iph2->dst)); /* start phase 1 negotiation as a initiator. */ - if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) < 0) { + if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src, 0) < 0) { SCHED_KILL(sc); return -1; } @@ -2288,12 +2821,21 @@ isakmp_chkph1there(iph2) struct ph1handle *iph1; iph2->retry_checkph1--; - if (iph2->retry_checkph1 < 0) { - plog(LLV_ERROR, LOCATION, iph2->dst, - "phase2 negotiation failed " - "due to time up waiting for phase1. %s\n", - sadbsecas2str(iph2->dst, iph2->src, - iph2->satype, 0, 0)); + if (iph2->retry_checkph1 < 0 || + ike_session_verify_ph2_parent_session(iph2)) { + if (iph2->retry_checkph1 < 0) { + plog(LLV_ERROR, LOCATION, iph2->dst, + "phase2 negotiation failed " + "due to time up waiting for phase1. %s\n", + sadbsecas2str(iph2->dst, iph2->src, + iph2->satype, 0, 0)); + } else { + plog(LLV_ERROR, LOCATION, iph2->dst, + "phase2 negotiation failed " + "due to invalid parent session. %s\n", + sadbsecas2str(iph2->dst, iph2->src, + iph2->satype, 0, 0)); + } plog(LLV_INFO, LOCATION, NULL, "delete phase 2 handler.\n"); @@ -2307,39 +2849,44 @@ isakmp_chkph1there(iph2) return; } - /* - * Search isakmp status table by address and port - * If NAT-T is in use, consider null ports as a - * wildcard and use IKE ports instead. - */ -#ifdef ENABLE_NATT - if (!extract_port(iph2->src) && !extract_port(iph2->dst)) { - if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) { - /* - * cannot set ph2 ports until after switch to natt port - * otherwise this function will never again find phase 1 - */ - if (iph1->status == PHASE1ST_ESTABLISHED) { - set_port(iph2->src, extract_port(iph1->local)); - set_port(iph2->dst, extract_port(iph1->remote)); - } - } - } else { - iph1 = getph1byaddr(iph2->src, iph2->dst); - } -#else - iph1 = getph1byaddr(iph2->src, iph2->dst); -#endif + iph1 = ike_session_update_ph2_ph1bind(iph2); /* XXX Even if ph1 as responder is there, should we not start * phase 2 negotiation ? */ if (iph1 != NULL && iph1->status == PHASE1ST_ESTABLISHED) { /* found isakmp-sa */ + + plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str(iph1->local)); + plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str(iph1->remote)); + plog(LLV_DEBUG2, LOCATION, NULL, "before:\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst)); + set_port(iph2->src, extract_port(iph1->local)); + set_port(iph2->dst, extract_port(iph1->remote)); + plog(LLV_DEBUG2, LOCATION, NULL, "After:\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst)); + /* begin quick mode */ - (void)isakmp_ph2begin_i(iph1, iph2); + if (isakmp_ph2begin_i(iph1, iph2)) { + unbindph12(iph2); + remph2(iph2); + delph2(iph2); + } return; } + if (!ike_session_has_negoing_ph1(iph2->parent_session)) { + struct remoteconf *rmconf = getrmconf(iph2->dst); + /* start phase 1 negotiation as a initiator. */ + if (rmconf == NULL || + isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src, 0) < 0) { + plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established/negoing ph1 handler found... failed to initiate new one\n"); + } + } + + plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n"); /* no isakmp-sa found */ sched_new(1, isakmp_chkph1there_stub, iph2); @@ -2907,7 +3454,7 @@ copy_ph1addresses(iph1, rmconf, remote, local) port = &((struct sockaddr_in *)iph1->local)->sin_port; if (*port) break; - *port = ((struct sockaddr_in *)local)->sin_port; + *port = ((struct sockaddr_in *)iph1->local)->sin_port; if (*port) break; *port = getmyaddrsport(iph1->local); @@ -2917,7 +3464,7 @@ copy_ph1addresses(iph1, rmconf, remote, local) port = &((struct sockaddr_in6 *)iph1->local)->sin6_port; if (*port) break; - *port = ((struct sockaddr_in6 *)local)->sin6_port; + *port = ((struct sockaddr_in6 *)iph1->local)->sin6_port; if (*port) break; *port = getmyaddrsport(iph1->local); @@ -2965,13 +3512,19 @@ log_ph1established(iph1) { char *src, *dst; - src = strdup(saddr2str(iph1->local)); - dst = strdup(saddr2str(iph1->remote)); + src = racoon_strdup(saddr2str(iph1->local)); + dst = racoon_strdup(saddr2str(iph1->remote)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); + plog(LLV_INFO, LOCATION, NULL, "ISAKMP-SA established %s-%s spi:%s\n", src, dst, isakmp_pindex(&iph1->index, 0)); EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL); + if(!iph1->rmconf->mode_cfg) + EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL); + racoon_free(src); racoon_free(dst); @@ -3001,21 +3554,13 @@ isakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_t vchar_t * isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1) { - struct payload_list *ptr, *first; + struct payload_list *ptr = *plist, *first; size_t tlen = sizeof (struct isakmp), n = 0; - vchar_t *buf; + vchar_t *buf = NULL; char *p; - if (plist == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "in isakmp_plist_set_all: plist == NULL\n"); - return NULL; - } - /* Seek to the first item. */ - ptr = *plist; - while (ptr->prev) - ptr = ptr->prev; + while (ptr->prev) ptr = ptr->prev; first = ptr; /* Compute the whole length. */ @@ -3051,6 +3596,8 @@ isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1) return buf; end: + if (buf != NULL) + vfree(buf); return NULL; } @@ -3091,7 +3638,9 @@ script_hook(iph1, script) struct sockaddr_in *sin; char **c; - if (iph1->rmconf->script[script] == -1) + if (iph1 == NULL || + iph1->rmconf == NULL || + iph1->rmconf->script[script] == NULL) return; #ifdef ENABLE_HYBRID @@ -3101,7 +3650,7 @@ script_hook(iph1, script) /* local address */ sin = (struct sockaddr_in *)iph1->local; inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX); - snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port)); + snprintf(portstr, sizeof(portstr), "%d", ntohs(sin->sin_port)); if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) { plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n"); @@ -3114,21 +3663,27 @@ script_hook(iph1, script) } /* Peer address */ - sin = (struct sockaddr_in *)iph1->remote; - inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX); - snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port)); + if (iph1->remote != NULL) { + sin = (struct sockaddr_in *)iph1->remote; + inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX); + snprintf(portstr, sizeof(portstr), "%d", ntohs(sin->sin_port)); - if (script_env_append(&envp, &envc, "REMOTE_ADDR", addrstr) != 0) { - plog(LLV_ERROR, LOCATION, NULL, "Cannot set REMOTE_ADDR\n"); - goto out; - } + if (script_env_append(&envp, &envc, + "REMOTE_ADDR", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set REMOTE_ADDR\n"); + goto out; + } - if (script_env_append(&envp, &envc, "REMOTE_PORT", portstr) != 0) { - plog(LLV_ERROR, LOCATION, NULL, "Cannot set REMOTEL_PORT\n"); - goto out; + if (script_env_append(&envp, &envc, + "REMOTE_PORT", portstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set REMOTEL_PORT\n"); + goto out; + } } - if (privsep_script_exec(iph1->rmconf->script[script], + if (privsep_script_exec(iph1->rmconf->script[script]->v, script, envp) != 0) plog(LLV_ERROR, LOCATION, NULL, "Script %s execution failed\n", script_names[script]); @@ -3152,21 +3707,23 @@ script_env_append(envp, envc, name, value) char *envitem; char **newenvp; int newenvc; - int envitemlen = strlen(name) + 1 + strlen(value) + 1; + int envitem_len; - envitem = racoon_malloc(envitemlen); + envitem_len = strlen(name) + 1 + strlen(value) + 1; + envitem = racoon_malloc(envitem_len); if (envitem == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); return -1; } - snprintf(envitem, envitemlen, "%s=%s", name, value); + snprintf(envitem, envitem_len, "%s=%s", name, value); newenvc = (*envc) + 1; newenvp = racoon_realloc(*envp, newenvc * sizeof(char *)); if (newenvp == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); + racoon_free(envitem); return -1; } @@ -3180,29 +3737,20 @@ script_env_append(envp, envc, name, value) int script_exec(script, name, envp) - int script; + char *script; int name; char *const envp[]; { char *argv[] = { NULL, NULL, NULL }; - vchar_t **sp; - - if (script_paths == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: script_paths was not initialized\n"); - return -1; - } - sp = (vchar_t **)(script_paths->v); - - argv[0] = sp[script]->v; + argv[0] = script; argv[1] = script_names[name]; argv[2] = NULL; switch (fork()) { case 0: execve(argv[0], argv, envp); - plog(LLV_ERROR2, LOCATION, NULL, + plog(LLV_ERROR, LOCATION, NULL, "execve(\"%s\") failed: %s\n", argv[0], strerror(errno)); _exit(1); @@ -3239,8 +3787,7 @@ purge_remote(iph1) /* Mark as expired. */ iph1->status = PHASE1ST_EXPIRED; - /* Check if we have another, still valid, phase1 SA. */ - new_iph1 = getph1byaddr(iph1->local, iph1->remote); + new_iph1 = ike_session_update_ph1_ph2tree(iph1); /* * Delete all orphaned or binded to the deleting ph1handle phase2 SAs. @@ -3289,7 +3836,11 @@ purge_remote(iph1) continue; } - /* check in/outbound SAs */ + /* + * check in/outbound SAs. + * Select only SAs where src == local and dst == remote (outgoing) + * or src == remote and dst == local (incoming). + */ if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) && (CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) { msg = next; @@ -3361,8 +3912,7 @@ purge_remote(iph1) "purged ISAKMP-SA spi=%s.\n", isakmp_pindex(&(iph1->index), iph1->msgid)); - if (iph1->sce) - SCHED_KILL(iph1->sce); + SCHED_KILL(iph1->sce); iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); } diff --git a/ipsec-tools/racoon/isakmp.h b/ipsec-tools/racoon/isakmp.h index 06ee511..8a3936e 100644 --- a/ipsec-tools/racoon/isakmp.h +++ b/ipsec-tools/racoon/isakmp.h @@ -348,6 +348,8 @@ struct isakmp_pl_n { #define ISAKMP_NTYPE_CERTIFICATE_UNAVAILABLE 28 #define ISAKMP_NTYPE_UNSUPPORTED_EXCHANGE_TYPE 29 #define ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS 30 +#define ISAKMP_NTYPE_MINERROR 1 +#define ISAKMP_NTYPE_MAXERROR 16383 /* NOTIFY MESSAGES - STATUS TYPES */ #define ISAKMP_NTYPE_CONNECTED 16384 /* 4.6.3 IPSEC DOI Notify Message Types */ @@ -362,6 +364,7 @@ struct isakmp_pl_n { #define ISAKMP_NTYPE_LOAD_BALANCE 40501 #define ISAKMP_NTYPE_HEARTBEAT 40503 + /* using only to log */ #define ISAKMP_LOG_RETRY_LIMIT_REACHED 65530 @@ -444,4 +447,15 @@ struct isakmp_pl_lb { u_int32_t address; /* redirect address */ } __attribute__((__packed__)); +/* Responder-Lifetime Notification */ +struct isakmp_pl_resp_lifetime { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int8_t proto_id; /* Protocol-Id */ + u_int8_t spi_size; /* SPI Size */ + u_int16_t type; /* Notify type */ + /* spi follows next */ + /* data follows next */ +} __attribute__((__packed__)); + #endif /* _ISAKMP_H */ diff --git a/ipsec-tools/racoon/isakmp_agg.c b/ipsec-tools/racoon/isakmp_agg.c index eea7726..7dddea3 100644 --- a/ipsec-tools/racoon/isakmp_agg.c +++ b/ipsec-tools/racoon/isakmp_agg.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_agg.c,v 1.20.2.5 2005/11/21 09:46:23 vanhu Exp $ */ +/* $NetBSD: isakmp_agg.c,v 1.9 2006/09/30 21:49:37 manu Exp $ */ + +/* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -59,6 +61,10 @@ #include "schedule.h" #include "debug.h" +#ifdef ENABLE_HYBRID +#include +#endif + #include "localconf.h" #include "remoteconf.h" #include "isakmp_var.h" @@ -91,6 +97,8 @@ #include "vpn_control.h" #include "vpn_control_var.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" /* * begin Aggressive Mode as initiator. @@ -111,7 +119,7 @@ agg_i1send(iph1, msg) { struct payload_list *plist = NULL; int need_cr = 0; - vchar_t *cr = NULL, *gsstoken = NULL; + vchar_t *cr = NULL; int error = -1; #ifdef ENABLE_NATT vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; @@ -125,6 +133,7 @@ agg_i1send(iph1, msg) vchar_t *vid_frag = NULL; #endif #ifdef HAVE_GSSAPI + vchar_t *gsstoken = NULL; int len; #endif #ifdef ENABLE_DPD @@ -149,13 +158,19 @@ agg_i1send(iph1, msg) isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); /* make ID payload into isakmp status */ - if (ipsecdoi_setid1(iph1) < 0) + if (ipsecdoi_setid1(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ID"); goto end; + } /* create SA payload for my proposal */ iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal); - if (iph1->sa == NULL) + if (iph1->sa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set proposal"); goto end; + } /* consistency check of proposals */ if (iph1->rmconf->dhgrp == NULL) { @@ -166,19 +181,30 @@ agg_i1send(iph1, msg) /* generate DH public value */ if (oakley_dh_generate(iph1->rmconf->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate DH"); goto end; + } /* generate NONCE value */ iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); - if (iph1->nonce == NULL) + if (iph1->nonce == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NONCE"); goto end; + } #ifdef ENABLE_HYBRID /* Do we need Xauth VID? */ - switch (iph1->rmconf->proposal->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + switch (RMAUTHMETHOD(iph1)) { + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) plog(LLV_ERROR, LOCATION, NULL, "Xauth vendor ID generation failed\n"); @@ -211,7 +237,7 @@ agg_i1send(iph1, msg) cr = oakley_getcr(iph1); if (cr == NULL) { plog(LLV_ERROR, LOCATION, NULL, - "failed to get cr buffer.\n"); + "failed to get CR"); goto end; } } @@ -219,10 +245,8 @@ agg_i1send(iph1, msg) plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n", s_oakley_attr_method(iph1->rmconf->proposal->authmethod)); #ifdef HAVE_GSSAPI - if (iph1->rmconf->proposal->authmethod == - OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_itoken(iph1, &len); - } #endif /* set SA payload to propose */ @@ -238,11 +262,10 @@ agg_i1send(iph1, msg) plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); #ifdef HAVE_GSSAPI - if (iph1->rmconf->proposal->authmethod == - OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { gssapi_get_token_to_send(iph1, &gsstoken); plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); - } else + } #endif /* create isakmp CR payload */ if (need_cr) @@ -284,18 +307,34 @@ agg_i1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } iph1->status = PHASE1ST_MSG1SENT; error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Aggressive-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 1"), + CONSTSTR("Failed to transmit Aggressive-Mode Message 1")); + } if (cr) vfree(cr); +#ifdef HAVE_GSSAPI if (gsstoken) vfree(gsstoken); +#endif #ifdef ENABLE_FRAG if (vid_frag) vfree(vid_frag); @@ -304,16 +343,16 @@ end: for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) vfree(vid_natt[i]); #endif -#ifdef ENABLE_DPD - if (vid_dpd != NULL) - vfree(vid_dpd); -#endif #ifdef ENABLE_HYBRID if (vid_xauth != NULL) vfree(vid_xauth); if (vid_unity != NULL) vfree(vid_unity); #endif +#ifdef ENABLE_DPD + if (vid_dpd != NULL) + vfree(vid_dpd); +#endif return error; } @@ -365,8 +404,11 @@ agg_i2recv(iph1, msg) /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } pa = (struct isakmp_parse_t *)pbuf->v; iph1->pl_hash = NULL; @@ -380,8 +422,11 @@ agg_i2recv(iph1, msg) goto end; } - if (isakmp_p2ph(&satmp, pa->ptr) < 0) + if (isakmp_p2ph(&satmp, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SA payload"); goto end; + } pa++; for (/*nothing*/; @@ -390,31 +435,49 @@ agg_i2recv(iph1, msg) switch (pa->type) { case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_ID: - if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process ID payload"); goto end; + } break; case ISAKMP_NPTYPE_HASH: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; break; case ISAKMP_NPTYPE_CR: - if (oakley_savecr(iph1, pa->ptr) < 0) + if (oakley_savecr(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CR payload"); goto end; + } break; case ISAKMP_NPTYPE_CERT: - if (oakley_savecert(iph1, pa->ptr) < 0) + if (oakley_savecert(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CERT payload"); goto end; + } break; case ISAKMP_NPTYPE_SIG: - if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SIG payload"); goto end; + } break; case ISAKMP_NPTYPE_VID: vid_numeric = check_vendorid(pa->ptr); @@ -451,8 +514,11 @@ agg_i2recv(iph1, msg) break; #ifdef HAVE_GSSAPI case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process GSS payload"); goto end; + } gssapi_save_received_token(iph1, gsstoken); break; #endif @@ -467,13 +533,19 @@ agg_i2recv(iph1, msg) pa->type == iph1->natt_options->payload_nat_d) { struct natd_payload *natd; natd = (struct natd_payload *)racoon_malloc(sizeof(*natd)); - if (!natd) + if (!natd) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to pre-process NATD payload"); goto end; + } natd->payload = NULL; - if (isakmp_p2ph (&natd->payload, pa->ptr) < 0) + if (isakmp_p2ph (&natd->payload, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NATD payload"); goto end; + } natd->seq = natd_seq++; @@ -564,22 +636,41 @@ agg_i2recv(iph1, msg) /* compute sharing secret of DH */ if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub, - iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute DH"); goto end; + } /* generate SKEYIDs & IV & final cipher key */ - if (oakley_skeyid(iph1) < 0) + if (oakley_skeyid(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID"); goto end; - if (oakley_skeyid_dae(iph1) < 0) + } + if (oakley_skeyid_dae(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID-DAE"); goto end; - if (oakley_compute_enckey(iph1) < 0) + } + if (oakley_compute_enckey(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate ENCKEY"); goto end; - if (oakley_newiv(iph1) < 0) + } + if (oakley_newiv(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate IV"); goto end; + } /* validate authentication value */ ptype = oakley_validate_auth(iph1); if (ptype != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 2"), + CONSTSTR("Failed to authenticate, Aggressive-Mode Message 2")); if (ptype == -1) { /* message printed inner oakley_validate_auth() */ goto end; @@ -589,7 +680,11 @@ agg_i2recv(iph1, msg) isakmp_info_send_n1(iph1, ptype, NULL); goto end; } - + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Initiator, Aggressive-Mode Message 2"), + CONSTSTR(NULL)); + if (oakley_checkcr(iph1) < 0) { /* Ignore this error in order to be interoperability. */ ; @@ -604,7 +699,22 @@ agg_i2recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Aggressive-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 2"), + CONSTSTR("Failure processing Aggressive-Mode Message 2")); + } +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (pbuf) vfree(pbuf); if (satmp) @@ -642,6 +752,11 @@ agg_i2send(iph1, msg) int need_cert = 0; int error = -1; vchar_t *gsshash = NULL; +#ifdef ENABLE_NATT + vchar_t *natd[2] = { NULL, NULL }; +#endif + vchar_t *notp_unity = NULL; + vchar_t *notp_ini = NULL; /* validity check */ if (iph1->status != PHASE1ST_MSG2RECEIVED) { @@ -655,35 +770,50 @@ agg_i2send(iph1, msg) iph1->hash = oakley_ph1hash_common(iph1, GENERATE); if (iph1->hash == NULL) { #ifdef HAVE_GSSAPI - if (gssapi_more_tokens(iph1)) + if (gssapi_more_tokens(iph1) && +#ifdef ENABLE_HYBRID + !iph1->rmconf->xauth && +#endif + 1) isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); #endif + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate HASH"); goto end; } - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: #endif /* set HASH payload */ - plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); + plist = isakmp_plist_append(plist, + iph1->hash, ISAKMP_NPTYPE_HASH); break; + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: -#endif + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: +#endif /* XXX if there is CR or not ? */ - if (oakley_getmycert(iph1) < 0) + if (oakley_getmycert(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get mycert"); goto end; + } - if (oakley_getsign(iph1) < 0) + if (oakley_getsign(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get sign"); goto end; + } if (iph1->cert != NULL && iph1->rmconf->send_cert) need_cert = 1; @@ -698,13 +828,17 @@ agg_i2send(iph1, msg) case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: +#endif break; #ifdef HAVE_GSSAPI case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: gsshash = gssapi_wraphash(iph1); if (gsshash == NULL) { plog(LLV_ERROR, LOCATION, NULL, - "failed to wrap hash\n"); + "failed to get GSS hash\n"); isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); goto end; @@ -713,19 +847,11 @@ agg_i2send(iph1, msg) plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); break; #endif - default: - plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; - break; } #ifdef ENABLE_NATT /* generate NAT-D payloads */ - if (NATT_AVAILABLE(iph1)) - { - vchar_t *natd[2] = { NULL, NULL }; - + if (NATT_AVAILABLE(iph1)) { plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -753,18 +879,24 @@ agg_i2send(iph1, msg) } #endif - iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); #endif + /* send to responder */ - if (isakmp_send(iph1, iph1->sendbuf) < 0) + if (isakmp_send(iph1, iph1->sendbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -775,9 +907,35 @@ agg_i2send(iph1, msg) iph1->status = PHASE1ST_ESTABLISHED; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC, + CONSTSTR("Initiator, Aggressive-Mode"), + CONSTSTR(NULL)); + error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Aggressive-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 3"), + CONSTSTR("Failed to transmit Aggressive-Mode Message 3")); + } +#ifdef ENABLE_NATT + if (natd[0]) + vfree(natd[0]); + if (natd[1]) + vfree(natd[1]); +#endif + if (notp_unity) + vfree(notp_unity); + if (notp_ini) + vfree(notp_ini); if (gsshash) vfree(gsshash); return error; @@ -814,8 +972,11 @@ agg_r1recv(iph1, msg) /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } pa = (struct isakmp_parse_t *)pbuf->v; /* SA payload is fixed postion */ @@ -826,8 +987,11 @@ agg_r1recv(iph1, msg) pa->type, ISAKMP_NPTYPE_SA); goto end; } - if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SA payload"); goto end; + } pa++; for (/*nothing*/; @@ -840,16 +1004,25 @@ agg_r1recv(iph1, msg) switch (pa->type) { case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_ID: - if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process ID payload"); goto end; + } break; case ISAKMP_NPTYPE_VID: vid_numeric = check_vendorid(pa->ptr); @@ -891,14 +1064,20 @@ agg_r1recv(iph1, msg) break; case ISAKMP_NPTYPE_CR: - if (oakley_savecr(iph1, pa->ptr) < 0) + if (oakley_savecr(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CR payload"); goto end; + } break; #ifdef HAVE_GSSAPI case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process GSS payload"); goto end; + } gssapi_save_received_token(iph1, gsstoken); break; #endif @@ -950,7 +1129,22 @@ agg_r1recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Aggressive-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 1"), + CONSTSTR("Failed to process Aggressive-Mode Message 1")); + } +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (pbuf) vfree(pbuf); if (error) { @@ -982,7 +1176,6 @@ agg_r1send(iph1, msg) int need_cr = 0; int need_cert = 0; vchar_t *cr = NULL; - vchar_t *vid = NULL; int error = -1; #ifdef ENABLE_HYBRID vchar_t *xauth_vid = NULL; @@ -995,11 +1188,15 @@ agg_r1send(iph1, msg) #ifdef ENABLE_DPD vchar_t *vid_dpd = NULL; #endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif #ifdef HAVE_GSSAPI int gsslen; vchar_t *gsstoken = NULL, *gsshash = NULL; vchar_t *gss_sa = NULL; + int free_gss_sa = 0; #endif /* validity check */ @@ -1013,37 +1210,60 @@ agg_r1send(iph1, msg) isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); /* make ID payload into isakmp status */ - if (ipsecdoi_setid1(iph1) < 0) + if (ipsecdoi_setid1(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ID"); goto end; + } /* generate DH public value */ if (oakley_dh_generate(iph1->rmconf->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate DH"); goto end; + } /* generate NONCE value */ iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); - if (iph1->nonce == NULL) + if (iph1->nonce == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NONCE"); goto end; + } /* compute sharing secret of DH */ if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, - iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute DH"); goto end; + } /* generate SKEYIDs & IV & final cipher key */ - if (oakley_skeyid(iph1) < 0) + if (oakley_skeyid(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID"); goto end; - if (oakley_skeyid_dae(iph1) < 0) + } + if (oakley_skeyid_dae(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID-DAE"); goto end; - if (oakley_compute_enckey(iph1) < 0) + } + if (oakley_compute_enckey(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate ENCKEY"); goto end; - if (oakley_newiv(iph1) < 0) + } + if (oakley_newiv(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate IV"); goto end; + } #ifdef HAVE_GSSAPI - if (iph1->rmconf->proposal->authmethod == - OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_rtoken(iph1, &gsslen); #endif @@ -1056,6 +1276,8 @@ agg_r1send(iph1, msg) isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); #endif + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate GSS HASH"); goto end; } @@ -1067,7 +1289,7 @@ agg_r1send(iph1, msg) cr = oakley_getcr(iph1); if (cr == NULL) { plog(LLV_ERROR, LOCATION, NULL, - "failed to get cr buffer.\n"); + "failed to get CR.\n"); goto end; } } @@ -1098,9 +1320,23 @@ agg_r1send(iph1, msg) if (iph1->dpd_support && iph1->rmconf->dpd) vid_dpd = set_vendorid(VENDORID_DPD); #endif +#ifdef ENABLE_FRAG + if (iph1->frag) { + vid_frag = set_vendorid(VENDORID_FRAG); + if (vid_frag != NULL) + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_AGG); + if (vid_frag == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } +#endif - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif /* set SA payload to reply */ plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA); @@ -1114,11 +1350,8 @@ agg_r1send(iph1, msg) plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); /* create isakmp HASH payload */ - plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); - - /* append vendor id, if needed */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); + plist = isakmp_plist_append(plist, + iph1->hash, ISAKMP_NPTYPE_HASH); /* create isakmp CR payload if needed */ if (need_cr) @@ -1127,16 +1360,24 @@ agg_r1send(iph1, msg) case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: #endif /* XXX if there is CR or not ? */ - if (oakley_getmycert(iph1) < 0) + if (oakley_getmycert(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get mycert"); goto end; + } - if (oakley_getsign(iph1) < 0) + if (oakley_getsign(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get sign"); goto end; + } if (iph1->cert != NULL && iph1->rmconf->send_cert) need_cert = 1; @@ -1160,12 +1401,78 @@ agg_r1send(iph1, msg) /* add SIG payload */ plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); - /* append vendor id, if needed */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); + /* create isakmp CR payload if needed */ + if (need_cr) + plist = isakmp_plist_append(plist, + cr, ISAKMP_NPTYPE_CR); + break; + + case OAKLEY_ATTR_AUTH_METHOD_RSAENC: + case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + break; +#ifdef HAVE_GSSAPI + case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + /* create buffer to send isakmp payload */ + gsshash = gssapi_wraphash(iph1); + if (gsshash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate GSS HASH\n"); + /* + * This is probably due to the GSS + * roundtrips not being finished yet. + * Return this error in the hope that + * a fallback to main mode will be done. + */ + isakmp_info_send_n1(iph1, + ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); + goto end; + } + if (iph1->approval->gssid != NULL) + gss_sa = + ipsecdoi_setph1proposal(iph1->approval); + else + gss_sa = iph1->sa_ret; + + if (gss_sa != iph1->sa_ret) + free_gss_sa = 1; + + /* set SA payload to reply */ + plist = isakmp_plist_append(plist, + gss_sa, ISAKMP_NPTYPE_SA); + + /* create isakmp KE payload */ + plist = isakmp_plist_append(plist, + iph1->dhpub, ISAKMP_NPTYPE_KE); + + /* create isakmp NONCE payload */ + plist = isakmp_plist_append(plist, + iph1->nonce, ISAKMP_NPTYPE_NONCE); + + /* create isakmp ID payload */ + plist = isakmp_plist_append(plist, + iph1->id, ISAKMP_NPTYPE_ID); + + /* create GSS payload */ + gssapi_get_token_to_send(iph1, &gsstoken); + plist = isakmp_plist_append(plist, + gsstoken, ISAKMP_NPTYPE_GSS); + + /* create isakmp HASH payload */ + plist = isakmp_plist_append(plist, + gsshash, ISAKMP_NPTYPE_HASH); + + /* append vendor id, if needed */ + break; +#endif + } #ifdef ENABLE_HYBRID if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n"); if ((xauth_vid = set_vendorid(VENDORID_XAUTH)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot create Xauth vendor ID\n"); @@ -1186,68 +1493,6 @@ agg_r1send(iph1, msg) } #endif - /* create isakmp CR payload if needed */ - if (need_cr) - plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR); - break; - - case OAKLEY_ATTR_AUTH_METHOD_RSAENC: - case OAKLEY_ATTR_AUTH_METHOD_RSAREV: - break; -#ifdef HAVE_GSSAPI - case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: - /* create buffer to send isakmp payload */ - gsshash = gssapi_wraphash(iph1); - if (gsshash == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to wrap hash\n"); - /* - * This is probably due to the GSS roundtrips not - * being finished yet. Return this error in - * the hope that a fallback to main mode will - * be done. - */ - isakmp_info_send_n1(iph1, - ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); - goto end; - } - if (iph1->approval->gssid != NULL) - gss_sa = ipsecdoi_setph1proposal(iph1->approval); - else - gss_sa = iph1->sa_ret; - - /* set SA payload to reply */ - plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA); - - /* create isakmp KE payload */ - plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); - - /* create isakmp NONCE payload */ - plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); - - /* create isakmp ID payload */ - plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); - - /* create GSS payload */ - gssapi_get_token_to_send(iph1, &gsstoken); - plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); - - /* create isakmp HASH payload */ - plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); - - /* append vendor id, if needed */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); - - break; -#endif - default: - plog(LLV_ERROR, LOCATION, NULL, "Invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; - break; - } - #ifdef ENABLE_NATT /* append NAT-T payloads */ if (vid_natt) { @@ -1267,6 +1512,12 @@ agg_r1send(iph1, msg) } } #endif + +#ifdef ENABLE_FRAG + if (vid_frag) + plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID); +#endif + #ifdef ENABLE_DPD if (vid_dpd) plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); @@ -1280,11 +1531,15 @@ agg_r1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -1298,11 +1553,20 @@ agg_r1send(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Aggressive-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 2"), + CONSTSTR("Failed to process Aggressive-Mode Message 2")); + } if (cr) vfree(cr); - if (vid) - vfree(vid); #ifdef ENABLE_HYBRID if (xauth_vid) vfree(xauth_vid); @@ -1314,13 +1578,25 @@ end: vfree(gsstoken); if (gsshash) vfree(gsshash); - if (gss_sa != iph1->sa_ret) + if (free_gss_sa) vfree(gss_sa); #endif +#ifdef ENABLE_NATT + if (vid_natt) + vfree(vid_natt); + if (natd[0]) + vfree(natd[0]); + if (natd[1]) + vfree(natd[1]); +#endif #ifdef ENABLE_DPD if (vid_dpd) vfree(vid_dpd); #endif +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif return error; } @@ -1360,15 +1636,21 @@ agg_r2recv(iph1, msg0) if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt msg"); goto end; + } } else msg = vdup(msg0); /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } iph1->pl_hash = NULL; @@ -1384,12 +1666,18 @@ agg_r2recv(iph1, msg0) (void)check_vendorid(pa->ptr); break; case ISAKMP_NPTYPE_CERT: - if (oakley_savecert(iph1, pa->ptr) < 0) + if (oakley_savecert(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CERT payload"); goto end; + } break; case ISAKMP_NPTYPE_SIG: - if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SIG payload"); goto end; + } break; case ISAKMP_NPTYPE_N: isakmp_check_notify(pa->ptr, iph1); @@ -1398,17 +1686,17 @@ agg_r2recv(iph1, msg0) #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATD_DRAFT: case ISAKMP_NPTYPE_NATD_RFC: -#ifdef __APPLE__ - case ISAKMP_NPTYPE_NATD_BADDRAFT: -#endif if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && pa->type == iph1->natt_options->payload_nat_d) { vchar_t *natd_received = NULL; int natd_verified; - if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NATD payload"); goto end; + } if (natd_seq == 0) iph1->natt_flags |= NAT_DETECTED; @@ -1450,6 +1738,10 @@ agg_r2recv(iph1, msg0) /* validate authentication value */ ptype = oakley_validate_auth(iph1); if (ptype != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 3"), + CONSTSTR("Failed to authenticate Aggressive-Mode Message 3")); if (ptype == -1) { /* message printed inner oakley_validate_auth() */ goto end; @@ -1459,12 +1751,27 @@ agg_r2recv(iph1, msg0) isakmp_info_send_n1(iph1, ptype, NULL); goto end; } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Responder, Aggressive-Mode Message 3"), + CONSTSTR(NULL)); iph1->status = PHASE1ST_MSG2RECEIVED; error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Aggressive-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 3"), + CONSTSTR("Failed to process Aggressive-Mode Message 3")); + } if (pbuf) vfree(pbuf); if (msg) @@ -1507,6 +1814,11 @@ agg_r2send(iph1, msg) iph1->status = PHASE1ST_ESTABLISHED; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC, + CONSTSTR("Responder, Aggressive-Mode"), + CONSTSTR(NULL)); + error = 0; end: diff --git a/ipsec-tools/racoon/isakmp_base.c b/ipsec-tools/racoon/isakmp_base.c index f33b733..3ac9e7c 100644 --- a/ipsec-tools/racoon/isakmp_base.c +++ b/ipsec-tools/racoon/isakmp_base.c @@ -1,3 +1,5 @@ +/* $NetBSD: isakmp_base.c,v 1.7 2006/10/02 21:51:33 manu Exp $ */ + /* $KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane Exp $ */ /* @@ -59,6 +61,10 @@ #include "schedule.h" #include "debug.h" +#ifdef ENABLE_HYBRID +#include +#endif + #include "localconf.h" #include "remoteconf.h" #include "isakmp_var.h" @@ -78,6 +84,10 @@ #ifdef ENABLE_FRAG #include "isakmp_frag.h" #endif +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif #include "vpn_control.h" #include "vpn_control_var.h" @@ -105,6 +115,14 @@ base_i1send(iph1, msg) #ifdef ENABLE_FRAG vchar_t *vid_frag = NULL; #endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif + /* validity check */ if (msg != NULL) { @@ -136,6 +154,28 @@ base_i1send(iph1, msg) if (iph1->nonce == NULL) goto end; +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (RMAUTHMETHOD(iph1)) { + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Xauth vendor ID generation failed\n"); + + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Unity vendor ID generation failed\n"); + break; + default: + break; + } +#endif #ifdef ENABLE_FRAG if (iph1->rmconf->ike_frag) { vid_frag = set_vendorid(VENDORID_FRAG); @@ -184,13 +224,28 @@ base_i1send(iph1, msg) if (vid_frag) plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID); #endif +#ifdef ENABLE_HYBRID + if (vid_xauth) + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + if (vid_unity) + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); +#endif +#ifdef ENABLE_DPD + if (iph1->rmconf->dpd) { + vid_dpd = set_vendorid(VENDORID_DPD); + if (vid_dpd != NULL) + plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); + } +#endif #ifdef ENABLE_NATT /* set VID payload for NAT-T */ for (i = 0; i < vid_natt_i; i++) plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID); - - iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); #endif + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -214,6 +269,16 @@ end: for (i = 0; i < vid_natt_i; i++) vfree(vid_natt[i]); #endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif +#ifdef ENABLE_DPD + if (vid_dpd != NULL) + vfree(vid_dpd); +#endif return error; } @@ -235,6 +300,10 @@ base_i2recv(iph1, msg) vchar_t *satmp = NULL; int error = -1; int vid_numeric; +#ifdef ENABLE_HYBRID + vchar_t *unity_vid; + vchar_t *xauth_vid; +#endif /* validity check */ if (iph1->status != PHASE1ST_MSG1SENT) { @@ -279,6 +348,29 @@ base_i2recv(iph1, msg) #ifdef ENABLE_NATT if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric)) natt_handle_vendorid(iph1, vid_numeric); +#endif +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif +#ifdef ENABLE_DPD + if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) { + iph1->dpd_support=1; + plog(LLV_DEBUG, LOCATION, NULL, + "remote supports DPD\n"); + } #endif break; default: @@ -376,10 +468,21 @@ base_i2send(iph1, msg) goto end; /* generate SKEYID to compute hash if not signature mode */ - if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG) { + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif + break; + default: if (oakley_skeyid(iph1) < 0) goto end; + break; } /* generate HASH to send */ @@ -387,9 +490,13 @@ base_i2send(iph1, msg) iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE); if (iph1->hash == NULL) goto end; - - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif vid = set_vendorid(iph1->approval->vendorid); /* create isakmp KE payload */ @@ -404,6 +511,10 @@ base_i2send(iph1, msg) break; case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: +#endif /* XXX if there is CR or not ? */ if (oakley_getmycert(iph1) < 0) @@ -425,16 +536,17 @@ base_i2send(iph1, msg) /* add SIG payload */ plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); break; +#ifdef HAVE_GSSAPI case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: /* ... */ break; +#endif case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: - break; - default: - plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: +#endif break; } @@ -483,7 +595,8 @@ base_i2send(iph1, msg) goto end; /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -632,10 +745,21 @@ base_i3recv(iph1, msg) goto end; /* generate SKEYID to compute hash if signature mode */ - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_RSASIG - || iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_DSSSIG) { + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif if (oakley_skeyid(iph1) < 0) goto end; + break; + default: + break; } /* generate SKEYIDs & IV & final cipher key */ @@ -766,6 +890,29 @@ base_r1recv(iph1, msg) (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE)) iph1->frag = 1; #endif +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif +#ifdef ENABLE_DPD + if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) { + iph1->dpd_support=1; + plog(LLV_DEBUG, LOCATION, NULL, + "remote supports DPD\n"); + } +#endif break; default: /* don't send information, see ident_r1recv() */ @@ -839,6 +986,16 @@ base_r1send(iph1, msg) #ifdef ENABLE_NATT vchar_t *vid_natt = NULL; #endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif +#ifdef ENABLE_DPD + vchar_t *vid_dpd = NULL; +#endif /* validity check */ if (iph1->status != PHASE1ST_MSG1RECEIVED) { @@ -875,6 +1032,56 @@ base_r1send(iph1, msg) if (vid_natt) plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID); #endif +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n"); + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Xauth vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + } + + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Unity vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + } +#endif +#ifdef ENABLE_DPD + /* + * Only send DPD support if remote announced DPD + * and if DPD support is active + */ + if (iph1->dpd_support && iph1->rmconf->dpd) { + if ((vid_dpd = set_vendorid(VENDORID_DPD)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "DPD vendorID construction failed\n"); + } else { + plist = isakmp_plist_append(plist, vid_dpd, + ISAKMP_NPTYPE_VID); + } + } +#endif +#ifdef ENABLE_FRAG + if (iph1->rmconf->ike_frag) { + if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } else { + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_BASE); + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } + } +#endif iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); @@ -884,11 +1091,14 @@ base_r1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + iph1 = NULL; goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -907,8 +1117,23 @@ end: if (vid_natt) vfree(vid_natt); #endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif +#ifdef ENABLE_DPD + if (vid_dpd) + vfree(vid_dpd); +#endif - VPTRINIT(iph1->sa_ret); + if (iph1 != NULL) + VPTRINIT(iph1->sa_ret); return error; } @@ -1096,15 +1321,30 @@ base_r2send(iph1, msg) /* generate HASH to send */ plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n"); - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif iph1->hash = oakley_ph1hash_common(iph1, GENERATE); break; case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: +#endif +#ifdef HAVE_GSSAPI case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: +#endif iph1->hash = oakley_ph1hash_base_r(iph1, GENERATE); break; default: @@ -1116,8 +1356,11 @@ base_r2send(iph1, msg) if (iph1->hash == NULL) goto end; - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif vid = set_vendorid(iph1->approval->vendorid); /* create isakmp KE payload */ @@ -1132,6 +1375,12 @@ base_r2send(iph1, msg) break; case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: +#endif /* XXX if there is CR or not ? */ if (oakley_getmycert(iph1) < 0) @@ -1152,23 +1401,23 @@ base_r2send(iph1, msg) /* add SIG payload */ plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); break; +#ifdef HAVE_GSSAPI case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: /* ... */ break; +#endif case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: - break; - default: - plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif break; } #ifdef ENABLE_NATT /* generate NAT-D payloads */ - if (NATT_AVAILABLE(iph1)) - { + if (NATT_AVAILABLE(iph1)) { vchar_t *natd[2] = { NULL, NULL }; plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); @@ -1198,7 +1447,7 @@ base_r2send(iph1, msg) } #endif - iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + iph1->sendbuf = isakmp_plist_set_all(&plist, iph1); #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -1209,7 +1458,8 @@ base_r2send(iph1, msg) goto end; /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; diff --git a/ipsec-tools/racoon/isakmp_cfg.c b/ipsec-tools/racoon/isakmp_cfg.c index 56e96de..c72600a 100644 --- a/ipsec-tools/racoon/isakmp_cfg.c +++ b/ipsec-tools/racoon/isakmp_cfg.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_cfg.c,v 1.26.2.7 2006/01/07 23:50:42 manubsd Exp $ */ +/* $NetBSD: isakmp_cfg.c,v 1.12.6.1 2007/06/07 20:06:34 manu Exp $ */ + +/* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */ /* * Copyright (C) 2004-2006 Emmanuel Dreyfus @@ -36,6 +38,18 @@ #include #include +#include +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + +#ifdef __FreeBSD__ +# include +#endif +#ifdef __NetBSD__ +# include +#endif + #include #include @@ -57,7 +71,11 @@ #ifdef HAVE_UNISTD_H #include #endif +#if HAVE_STDINT_H +#include +#endif #include +#include #ifdef HAVE_LIBRADIUS #include @@ -78,6 +96,7 @@ #include "evt.h" #include "throttle.h" #include "remoteconf.h" +#include "localconf.h" #include "crypto_openssl.h" #include "isakmp_inf.h" #include "isakmp_xauth.h" @@ -86,22 +105,14 @@ #include "strnames.h" #include "admin.h" #include "privsep.h" +#include "vpn_control.h" +#include "vpn_control_var.h" +#include "ike_session.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" +#include "nattraversal.h" -struct isakmp_cfg_config isakmp_cfg_config = { - 0x00000000, /* network4 */ - 0x00000000, /* netmask4 */ - 0x00000000, /* dns4 */ - 0x00000000, /* nbns4 */ - NULL, /* pool */ - ISAKMP_CFG_AUTH_SYSTEM, /* authsource */ - ISAKMP_CFG_CONF_LOCAL, /* confsource */ - ISAKMP_CFG_ACCT_NONE, /* accounting */ - ISAKMP_CFG_MAX_CNX, /* pool_size */ - THROTTLE_PENALTY, /* auth_throttle */ - ISAKMP_CFG_MOTD, /* motd */ - 0, /* pfs_group */ - 0, /* save_passwd */ -}; +struct isakmp_cfg_config isakmp_cfg_config; static vchar_t *buffer_cat(vchar_t *s, vchar_t *append); static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *); @@ -111,6 +122,12 @@ static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *); static vchar_t *isakmp_cfg_addr4(struct ph1handle *, struct isakmp_data *, in_addr_t *); static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *); +static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *, + struct isakmp_data *, in_addr_t *, int); +static void isakmp_cfg_appendaddr4(struct isakmp_data *, + struct in_addr *, int *, int); +static void isakmp_cfg_getstring(struct isakmp_data *,char *); +void isakmp_cfg_iplist_to_str(char *, int, void *, int); #define ISAKMP_CFG_LOGIN 1 #define ISAKMP_CFG_LOGOUT 2 @@ -135,17 +152,27 @@ isakmp_cfg_r(iph1, msg) int np; vchar_t *dmsg; struct isakmp_ivm *ivm; + struct ph2handle *iph2; + int error = -1; /* Check that the packet is long enough to have a header */ if (msg->l < sizeof(*packet)) { - plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n"); - return; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("MODE-Config. Unexpected short packet"), + CONSTSTR("Failed to process short MODE-Config packet")); + plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n"); + return; } packet = (struct isakmp *)msg->v; /* Is it encrypted? It should be encrypted */ if ((packet->flags & ISAKMP_FLAG_E) == 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("MODE-Config. User credentials sent in cleartext"), + CONSTSTR("Dropped cleattext User credentials")); plog(LLV_ERROR, LOCATION, NULL, "User credentials sent in cleartext!\n"); return; @@ -155,13 +182,18 @@ isakmp_cfg_r(iph1, msg) * Decrypt the packet. If this is the beginning of a new * exchange, reinitialize the IV */ - if (iph1->mode_cfg->ivm == NULL) + if (iph1->mode_cfg->ivm == NULL || + iph1->mode_cfg->last_msgid != packet->msgid ) iph1->mode_cfg->ivm = isakmp_cfg_newiv(iph1, packet->msgid); ivm = iph1->mode_cfg->ivm; dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive); if (dmsg == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("MODE-Config. Failed to decrypt packet"), + CONSTSTR("Failed to decrypt MODE-Config packet")); plog(LLV_ERROR, LOCATION, NULL, "failed to decrypt message\n"); return; @@ -235,7 +267,7 @@ isakmp_cfg_r(iph1, msg) struct isakmp_pl_attr *attrpl; attrpl = (struct isakmp_pl_attr *)ph; - isakmp_cfg_attr_r(iph1, packet->msgid, attrpl); + isakmp_cfg_attr_r(iph1, packet->msgid, attrpl, msg); break; } @@ -253,24 +285,47 @@ isakmp_cfg_r(iph1, msg) ph = (struct isakmp_gen *)(npp + ntohs(ph->len)); } + error = 0; + /* find phase 2 in case pkt scheduled for resend */ + iph2 = getph2bymsgid(iph1, packet->msgid); + if (iph2 == NULL) + goto out; /* no resend scheduled */ + SCHED_KILL(iph2->scr); /* turn off schedule */ + unbindph12(iph2); + remph2(iph2); + delph2(iph2); + + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("MODE-Config"), + CONSTSTR(NULL)); out: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("MODE-Config"), + CONSTSTR("Failed to process Mode-Config packet")); + } vfree(dmsg); } int -isakmp_cfg_attr_r(iph1, msgid, attrpl) +isakmp_cfg_attr_r(iph1, msgid, attrpl, msg) struct ph1handle *iph1; u_int32_t msgid; struct isakmp_pl_attr *attrpl; + vchar_t *msg; { int type = attrpl->type; + plog(LLV_DEBUG, LOCATION, NULL, + "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type)); switch (type) { case ISAKMP_CFG_ACK: /* ignore, but this is the time to reinit the IV */ oakley_delivm(iph1->mode_cfg->ivm); iph1->mode_cfg->ivm = NULL; - return 0; + return 0; break; case ISAKMP_CFG_REPLY: @@ -279,12 +334,12 @@ isakmp_cfg_attr_r(iph1, msgid, attrpl) case ISAKMP_CFG_REQUEST: iph1->msgid = msgid; - return isakmp_cfg_request(iph1, attrpl); + return isakmp_cfg_request(iph1, attrpl, msg); break; case ISAKMP_CFG_SET: iph1->msgid = msgid; - return isakmp_cfg_set(iph1, attrpl); + return isakmp_cfg_set(iph1, attrpl, msg); break; default: @@ -307,12 +362,15 @@ isakmp_cfg_reply(iph1, attrpl) size_t alen; char *npp; int type; - struct sockaddr_in *sin; + int error; + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_REPLY) + return 0; /* already received this - duplicate packet */ + tlen = ntohs(attrpl->h.len); attr = (struct isakmp_data *)(attrpl + 1); tlen -= sizeof(*attrpl); - + while (tlen > 0) { type = ntohs(attr->type); @@ -321,17 +379,22 @@ isakmp_cfg_reply(iph1, attrpl) type &= ~ISAKMP_GEN_MASK; plog(LLV_DEBUG, LOCATION, NULL, - "Short attribute %d = %d\n", - type, ntohs(attr->lorv)); + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); - switch (type) { + switch (type) { case XAUTH_TYPE: - xauth_attr_reply(iph1, attr, ntohs(attrpl->id)); + if ((error = xauth_attr_reply(iph1, + attr, ntohs(attrpl->id))) != 0) + return error; + break; + break; default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored short attribute %d\n", type); + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -346,12 +409,14 @@ isakmp_cfg_reply(iph1, attrpl) /* Check that the attribute fit in the packet */ if (tlen < alen) { plog(LLV_ERROR, LOCATION, NULL, - "Short attribute %d\n", type); + "Short attribute %s\n", + s_isakmp_cfg_type(type)); return -1; } plog(LLV_DEBUG, LOCATION, NULL, - "Attribute %d, len %zu\n", type, alen); + "Attribute %s, len %zu\n", + s_isakmp_cfg_type(type), alen); switch(type) { case XAUTH_TYPE: @@ -364,39 +429,67 @@ isakmp_cfg_reply(iph1, attrpl) case XAUTH_STATUS: case XAUTH_NEXT_PIN: case XAUTH_ANSWER: - xauth_attr_reply(iph1, attr, ntohs(attrpl->id)); + if ((error = xauth_attr_reply(iph1, + attr, ntohs(attrpl->id))) != 0) + return error; break; case INTERNAL_IP4_ADDRESS: - isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4); - iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4; + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) == 0) { + isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4; + } break; case INTERNAL_IP4_NETMASK: - isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4); - iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4; + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) == 0) { + isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4; + } break; case INTERNAL_IP4_DNS: - isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->dns4); - iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4; + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) == 0) { + isakmp_cfg_appendaddr4(attr, + &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index], + &iph1->mode_cfg->dns4_index, MAXNS); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4; + } break; case INTERNAL_IP4_NBNS: - isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->wins4); - iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4; + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) == 0) { + isakmp_cfg_appendaddr4(attr, + &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index], + &iph1->mode_cfg->wins4_index, MAXNS); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4; + } break; - case INTERNAL_IP4_SUBNET: - case INTERNAL_ADDRESS_EXPIRY: - case UNITY_BANNER: - case UNITY_SAVE_PASSWD: case UNITY_DEF_DOMAIN: - case UNITY_SPLITDNS_NAME: + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) == 0) { + isakmp_cfg_getstring(attr, + iph1->mode_cfg->default_domain); + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN; + } + break; case UNITY_SPLIT_INCLUDE: + case UNITY_LOCAL_LAN: + case UNITY_SPLITDNS_NAME: + case UNITY_BANNER: + case UNITY_SAVE_PASSWD: case UNITY_NATT_PORT: - case UNITY_PFS: case UNITY_FW_TYPE: case UNITY_BACKUP_SERVERS: case UNITY_DDNS_HOSTNAME: + case APPLICATION_VERSION: + case UNITY_PFS: + isakmp_unity_reply(iph1, attr); + break; + case INTERNAL_IP4_SUBNET: + case INTERNAL_ADDRESS_EXPIRY: + if (iph1->started_by_api) + break; /* not actually ignored - don't fall thru */ + // else fall thru default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -404,15 +497,49 @@ isakmp_cfg_reply(iph1, attrpl) attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); tlen -= (sizeof(*attr) + alen); } - + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_REPLY; + + if (iph1->started_by_api || (iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client)) { + /* connection was started by API - save attr list for passing to VPN controller */ + if (iph1->mode_cfg->attr_list != NULL) /* shouldn't happen */ + vfree(iph1->mode_cfg->attr_list); + alen = ntohs(attrpl->h.len) - sizeof(*attrpl); + if ((iph1->mode_cfg->attr_list = vmalloc(alen)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory for mode-cfg attribute list\n"); + return -1; + } + memcpy(iph1->mode_cfg->attr_list->v, attrpl + 1, alen); + } + /* * Call the SA up script hook now that we have the configuration * It is done at the end of phase 1 if ISAKMP mode config is not * requested. */ + if ((iph1->status == PHASE1ST_ESTABLISHED) && - iph1->rmconf->mode_cfg) - script_hook(iph1, SCRIPT_PHASE1_UP); + iph1->rmconf->mode_cfg) { + switch (AUTHMETHOD(iph1)) { + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + /* Unimplemented */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + script_hook(iph1, SCRIPT_PHASE1_UP); + break; + default: + break; + } + } + +#ifdef ENABLE_VPNCONTROL_PORT + if (iph1->status == PHASE1ST_ESTABLISHED) + vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL); +#endif #ifdef ENABLE_ADMINPORT { @@ -435,29 +562,53 @@ isakmp_cfg_reply(iph1, attrpl) } int -isakmp_cfg_request(iph1, attrpl) +isakmp_cfg_request(iph1, attrpl, msg) struct ph1handle *iph1; struct isakmp_pl_attr *attrpl; + vchar_t *msg; { struct isakmp_data *attr; int tlen; size_t alen; char *npp; - vchar_t *payload; + vchar_t *payload = NULL; struct isakmp_pl_attr *reply; vchar_t *reply_attr; int type; int error = -1; + tlen = ntohs(attrpl->h.len); + attr = (struct isakmp_data *)(attrpl + 1); + tlen -= sizeof(*attrpl); + + /* + * if started_by_api then we are a VPN client and if we receive + * a mode-cfg request it needs to go to the VPN controller to + * retrieve the appropriate data (name, pw, pin, etc.) + */ + if (iph1->started_by_api || ike_session_is_client_ph1_rekey(iph1)) { + /* + * if we already received this one - ignore it + * we are waiting for a reply from the vpn control socket + */ + if (iph1->xauth_awaiting_userinput) + return 0; + + /* otherwise - save the msg id and call and send the status notification */ + iph1->pended_xauth_id = attrpl->id; /* network byte order */ + if (vpncontrol_notify_need_authinfo(iph1, attrpl + 1, tlen)) + goto end; + iph1->xauth_awaiting_userinput = 1; + iph1->xauth_awaiting_userinput_msg = vdup(msg); // dup the message for later + ike_session_start_xauth_timer(iph1); + return 0; + } + if ((payload = vmalloc(sizeof(*reply))) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); return -1; } memset(payload->v, 0, sizeof(*reply)); - - tlen = ntohs(attrpl->h.len); - attr = (struct isakmp_data *)(attrpl + 1); - tlen -= sizeof(*attrpl); while (tlen > 0) { reply_attr = NULL; @@ -468,8 +619,8 @@ isakmp_cfg_request(iph1, attrpl) type &= ~ISAKMP_GEN_MASK; plog(LLV_DEBUG, LOCATION, NULL, - "Short attribute %d = %d\n", - type, ntohs(attr->lorv)); + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); switch (type) { case XAUTH_TYPE: @@ -477,7 +628,8 @@ isakmp_cfg_request(iph1, attrpl) break; default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored short attribute %d\n", type); + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -491,19 +643,21 @@ isakmp_cfg_request(iph1, attrpl) continue; } - + type = ntohs(attr->type); alen = ntohs(attr->lorv); /* Check that the attribute fit in the packet */ if (tlen < alen) { plog(LLV_ERROR, LOCATION, NULL, - "Short attribute %d\n", type); + "Short attribute %s\n", + s_isakmp_cfg_type(type)); goto end; } plog(LLV_DEBUG, LOCATION, NULL, - "Attribute %d, len %zu\n", type, alen); + "Attribute %s, len %zu\n", + s_isakmp_cfg_type(type), alen); switch(type) { case INTERNAL_IP4_ADDRESS: @@ -540,6 +694,7 @@ isakmp_cfg_request(iph1, attrpl) case UNITY_FW_TYPE: case UNITY_SPLITDNS_NAME: case UNITY_SPLIT_INCLUDE: + case UNITY_LOCAL_LAN: case UNITY_NATT_PORT: case UNITY_BACKUP_SERVERS: reply_attr = isakmp_unity_req(iph1, attr); @@ -548,7 +703,8 @@ isakmp_cfg_request(iph1, attrpl) case INTERNAL_ADDRESS_EXPIRY: default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -560,7 +716,6 @@ isakmp_cfg_request(iph1, attrpl) payload = buffer_cat(payload, reply_attr); vfree(reply_attr); } - } reply = (struct isakmp_pl_attr *)payload->v; @@ -568,12 +723,33 @@ isakmp_cfg_request(iph1, attrpl) reply->type = ISAKMP_CFG_REPLY; reply->id = attrpl->id; + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG REPLY\n"); + error = isakmp_cfg_send(iph1, payload, - ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg); + + if (iph1->status == PHASE1ST_ESTABLISHED) { + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + /* Unimplemented */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + script_hook(iph1, SCRIPT_PHASE1_UP); + break; + default: + break; + } +#ifdef ENABLE_VPNCONTROL_PORT + vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL); +#endif - /* Reinit the IV */ - oakley_delivm(iph1->mode_cfg->ivm); - iph1->mode_cfg->ivm = NULL; + } + end: vfree(payload); @@ -581,9 +757,10 @@ end: } int -isakmp_cfg_set(iph1, attrpl) +isakmp_cfg_set(iph1, attrpl, msg) struct ph1handle *iph1; struct isakmp_pl_attr *attrpl; + vchar_t *msg; { struct isakmp_data *attr; int tlen; @@ -612,18 +789,22 @@ isakmp_cfg_set(iph1, attrpl) reply_attr = NULL; type = ntohs(attr->type); + plog(LLV_DEBUG, LOCATION, NULL, + "Attribute %s\n", + s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); + switch (type & ~ISAKMP_GEN_MASK) { case XAUTH_STATUS: reply_attr = isakmp_xauth_set(iph1, attr); break; default: plog(LLV_DEBUG, LOCATION, NULL, - "Unexpected SET attribute %d\n", - type & ~ISAKMP_GEN_MASK); + "Unexpected SET attribute %s\n", + s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); break; } - if ((reply_attr = vmalloc(sizeof(*reply_attr))) != NULL) { + if (reply_attr != NULL) { payload = buffer_cat(payload, reply_attr); vfree(reply_attr); } @@ -649,22 +830,25 @@ isakmp_cfg_set(iph1, attrpl) reply->type = ISAKMP_CFG_ACK; reply->id = attrpl->id; + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG ACK\n"); + error = isakmp_cfg_send(iph1, payload, - ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg); if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) { if (iph1->status == PHASE1ST_ESTABLISHED) isakmp_info_send_d1(iph1); remph1(iph1); delph1(iph1); + iph1 = NULL; } -end: vfree(payload); /* - * If required, request ISAKMP mode config information + * If required, request ISAKMP mode config information: ignore rekeys */ - if ((iph1->rmconf->mode_cfg) && (error == 0)) + if ((iph1 != NULL) && (!iph1->is_rekey) && (iph1->rmconf->mode_cfg) && (error == 0)) error = isakmp_cfg_getconfig(iph1); return error; @@ -698,6 +882,7 @@ isakmp_cfg_net(iph1, attr) struct isakmp_data *attr; { int type; + int confsource; in_addr_t addr4; type = ntohs(attr->type); @@ -711,12 +896,30 @@ isakmp_cfg_net(iph1, attr) return NULL; } + confsource = isakmp_cfg_config.confsource; + /* + * If we have to fall back to a local + * configuration source, we will jump + * back to this point. + */ +retry_source: + switch(type) { case INTERNAL_IP4_ADDRESS: - switch(isakmp_cfg_config.confsource) { + switch(confsource) { +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_CONF_LDAP: + if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) + break; + plog(LLV_INFO, LOCATION, NULL, + "No IP from LDAP, using local pool\n"); + /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; +#endif #ifdef HAVE_LIBRADIUS case ISAKMP_CFG_CONF_RADIUS: - if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS) + if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) && (iph1->mode_cfg->addr4.s_addr != htonl(-2))) /* * -2 is 255.255.255.254, RADIUS uses that @@ -726,6 +929,8 @@ isakmp_cfg_net(iph1, attr) plog(LLV_INFO, LOCATION, NULL, "No IP from RADIUS, using local pool\n"); /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; #endif case ISAKMP_CFG_CONF_LOCAL: if (isakmp_cfg_getport(iph1) == -1) { @@ -753,14 +958,26 @@ isakmp_cfg_net(iph1, attr) break; case INTERNAL_IP4_NETMASK: - switch(isakmp_cfg_config.confsource) { + switch(confsource) { +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_CONF_LDAP: + if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN) + break; + plog(LLV_INFO, LOCATION, NULL, + "No mask from LDAP, using local pool\n"); + /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; +#endif #ifdef HAVE_LIBRADIUS case ISAKMP_CFG_CONF_RADIUS: - if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_RADIUS) + if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN) break; plog(LLV_INFO, LOCATION, NULL, "No mask from RADIUS, using local pool\n"); /* FALLTHROUGH */ + confsource = ISAKMP_CFG_CONF_LOCAL; + goto retry_source; #endif case ISAKMP_CFG_CONF_LOCAL: iph1->mode_cfg->mask4.s_addr @@ -777,13 +994,15 @@ isakmp_cfg_net(iph1, attr) break; case INTERNAL_IP4_DNS: - return isakmp_cfg_addr4(iph1, - attr, &isakmp_cfg_config.dns4); + return isakmp_cfg_addr4_list(iph1, + attr, &isakmp_cfg_config.dns4[0], + isakmp_cfg_config.dns4_index); break; case INTERNAL_IP4_NBNS: - return isakmp_cfg_addr4(iph1, - attr, &isakmp_cfg_config.nbns4); + return isakmp_cfg_addr4_list(iph1, + attr, &isakmp_cfg_config.nbns4[0], + isakmp_cfg_config.nbns4_index); break; case INTERNAL_IP4_SUBNET: @@ -795,7 +1014,6 @@ isakmp_cfg_net(iph1, attr) plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type); break; } - return NULL; } @@ -868,17 +1086,16 @@ isakmp_cfg_short(iph1, attr, value) } vchar_t * -isakmp_cfg_string(iph1, attr, string) +isakmp_cfg_varlen(iph1, attr, string, len) struct ph1handle *iph1; struct isakmp_data *attr; char *string; + size_t len; { vchar_t *buffer; struct isakmp_data *new; - size_t len; char *data; - len = strlen(string); if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); return NULL; @@ -894,6 +1111,15 @@ isakmp_cfg_string(iph1, attr, string) return buffer; } +vchar_t * +isakmp_cfg_string(iph1, attr, string) + struct ph1handle *iph1; + struct isakmp_data *attr; + char *string; +{ + size_t len = strlen(string); + return isakmp_cfg_varlen(iph1, attr, string, len); +} static vchar_t * isakmp_cfg_addr4(iph1, attr, addr) @@ -920,6 +1146,51 @@ isakmp_cfg_addr4(iph1, attr, addr) return buffer; } +static vchar_t * +isakmp_cfg_addr4_list(iph1, attr, addr, nbr) + struct ph1handle *iph1; + struct isakmp_data *attr; + in_addr_t *addr; + int nbr; +{ + int error = -1; + vchar_t *buffer = NULL; + vchar_t *bufone = NULL; + struct isakmp_data *new; + size_t len; + int i; + + len = sizeof(*addr); + if ((buffer = vmalloc(0)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + goto out; + } + for(i = 0; i < nbr; i++) { + if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory\n"); + goto out; + } + new = (struct isakmp_data *)bufone->v; + new->type = attr->type; + new->lorv = htons(len); + memcpy(new + 1, &addr[i], len); + new += (len + sizeof(*attr)); + buffer = buffer_cat(buffer, bufone); + vfree(bufone); + } + + error = 0; + +out: + if ((error != 0) && (buffer != NULL)) { + vfree(buffer); + buffer = NULL; + } + + return buffer; +} + struct isakmp_ivm * isakmp_cfg_newiv(iph1, msgid) struct ph1handle *iph1; @@ -937,18 +1208,21 @@ isakmp_cfg_newiv(iph1, msgid) oakley_delivm(ics->ivm); ics->ivm = oakley_newiv2(iph1, msgid); + ics->last_msgid = msgid; return ics->ivm; } /* Derived from isakmp_info_send_common */ int -isakmp_cfg_send(iph1, payload, np, flags, new_exchange) +isakmp_cfg_send(iph1, payload, np, flags, new_exchange, retry_count, msg) struct ph1handle *iph1; vchar_t *payload; u_int32_t np; int flags; int new_exchange; + int retry_count; + vchar_t *msg; { struct ph2handle *iph2 = NULL; vchar_t *hash = NULL; @@ -970,22 +1244,40 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) /* add new entry to isakmp status table */ iph2 = newph2(); - if (iph2 == NULL) + if (iph2 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate ph2"); goto end; + } iph2->dst = dupsaddr(iph1->remote); + if (iph2->dst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to duplicate remote address"); + delph2(iph2); + goto end; + } iph2->src = dupsaddr(iph1->local); + if (iph2->src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to duplicate local address"); + delph2(iph2); + goto end; + } + switch (iph1->remote->sa_family) { case AF_INET: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in *)iph2->dst)->sin_port = 0; ((struct sockaddr_in *)iph2->src)->sin_port = 0; #endif break; #ifdef INET6 case AF_INET6: +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0; ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0; +#endif break; #endif default: @@ -1007,6 +1299,8 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) if (iph1->skeyid_a != NULL) { if (new_exchange) { if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate IV"); delph2(iph2); goto end; } @@ -1015,6 +1309,8 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) /* generate HASH(1) */ hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload); if (hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate HASH"); delph2(iph2); goto end; } @@ -1076,6 +1372,9 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); #endif + + plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n"); + plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l); /* encoding */ if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { @@ -1084,17 +1383,47 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, ics->ivm->ive, ics->ivm->iv); VPTRINIT(iph2->sendbuf); - if (tmp == NULL) + if (tmp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to encrypt packet"); goto err; + } iph2->sendbuf = tmp; } /* HDR*, HASH(1), ATTR */ + + if (retry_count > 0) { + iph2->retry_counter = retry_count; + if (isakmp_ph2resend(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to resend packet"); + VPTRINIT(iph2->sendbuf); + goto err; + } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT, + CONSTSTR("Mode-Config retransmit"), + CONSTSTR(NULL)); + error = 0; + goto end; + } + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); VPTRINIT(iph2->sendbuf); goto err; } - + if (msg) { + /* the sending message is added to the received-list. */ + if (add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg, + PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) { + plog(LLV_ERROR , LOCATION, NULL, + "failed to add a response packet to the tree.\n"); + } + } + plog(LLV_DEBUG, LOCATION, NULL, "sendto mode config %s.\n", s_isakmp_nptype(np)); @@ -1105,10 +1434,18 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) error = 0; VPTRINIT(iph2->sendbuf); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Mode-Config message"), + CONSTSTR(NULL)); + err: - if (iph2->sendbuf != NULL) - vfree(iph2->sendbuf); - + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Mode-Config message"), + CONSTSTR("Failed to transmit Mode-Config message")); + } unbindph12(iph2); remph2(iph2); delph2(iph2); @@ -1131,7 +1468,24 @@ isakmp_cfg_rmstate(iph1) if (state->flags & ISAKMP_CFG_PORT_ALLOCATED) isakmp_cfg_putport(iph1, state->port); + /* Delete the IV if it's still there */ + if(iph1->mode_cfg->ivm) { + oakley_delivm(iph1->mode_cfg->ivm); + iph1->mode_cfg->ivm = NULL; + } + + /* Free any allocated splitnet lists */ + if(iph1->mode_cfg->split_include != NULL) + splitnet_list_free(iph1->mode_cfg->split_include, + &iph1->mode_cfg->include_count); + if(iph1->mode_cfg->split_local != NULL) + splitnet_list_free(iph1->mode_cfg->split_local, + &iph1->mode_cfg->local_count); + xauth_rmstate(&state->xauth); + + if (state->attr_list) + vfree(state->attr_list); racoon_free(state); iph1->mode_cfg = NULL; @@ -1251,6 +1605,9 @@ isakmp_cfg_accounting(iph1, inout) if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) return isakmp_cfg_accounting_radius(iph1, inout); #endif + if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM) + return privsep_accounting_system(iph1->mode_cfg->port, + iph1->remote, iph1->mode_cfg->login, inout); return 0; } @@ -1452,6 +1809,75 @@ isakmp_cfg_radius_common(radius_state, port) return 0; } #endif + +/* + Logs the user into the utmp system files. +*/ + +int +isakmp_cfg_accounting_system(port, raddr, usr, inout) + int port; + struct sockaddr *raddr; + char *usr; + int inout; +{ + int error = 0; + struct utmpx ut; + char term[_UTX_LINESIZE]; + char addr[NI_MAXHOST]; + + if (usr == NULL || usr[0]=='\0') { + plog(LLV_ERROR, LOCATION, NULL, + "system accounting : no login found\n"); + return -1; + } + + snprintf(term, sizeof(term), TERMSPEC, port); + + switch (inout) { + case ISAKMP_CFG_LOGIN: + strlcpy(ut.ut_user, usr, sizeof(ut.ut_user)); + + strlcpy(ut.ut_line, term, sizeof(ut.ut_line)); + + GETNAMEINFO_NULL(raddr, addr); + strlcpy(ut.ut_host, addr, sizeof(ut.ut_host)); + + ut.ut_pid = getpid(); + + ut.ut_type = UTMPX_AUTOFILL_MASK | USER_PROCESS; + + gettimeofday(&ut.ut_tv, NULL); + + plog(LLV_INFO, LOCATION, NULL, + "Accounting : '%s' logging on '%s' from %s.\n", + ut.ut_user, ut.ut_line, ut.ut_host); + + if (pututxline(&ut) == NULL) + return -1; + + break; + case ISAKMP_CFG_LOGOUT: + + plog(LLV_INFO, LOCATION, NULL, + "Accounting : '%s' unlogging from '%s'.\n", + usr, term); + + ut.ut_type = UTMPX_AUTOFILL_MASK | DEAD_PROCESS; + + gettimeofday(&ut.ut_tv, NULL); + + if (pututxline(&ut) == NULL) + return -1; + + break; + default: + plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); + break; + } + + return 0; +} int isakmp_cfg_getconfig(iph1) @@ -1461,6 +1887,7 @@ isakmp_cfg_getconfig(iph1) struct isakmp_pl_attr *attrpl; struct isakmp_data *attr; size_t len; + vchar_t *version = NULL; int error; int attrcount; int i; @@ -1469,13 +1896,37 @@ isakmp_cfg_getconfig(iph1) INTERNAL_IP4_NETMASK, INTERNAL_IP4_DNS, INTERNAL_IP4_NBNS, - UNITY_BANNER, + INTERNAL_ADDRESS_EXPIRY, APPLICATION_VERSION, + UNITY_BANNER, + UNITY_DEF_DOMAIN, + UNITY_SPLITDNS_NAME, + UNITY_SPLIT_INCLUDE, + UNITY_LOCAL_LAN, }; attrcount = sizeof(attrlist) / sizeof(*attrlist); len = sizeof(*attrpl) + sizeof(*attr) * attrcount; - + + if (iph1->started_by_api) { + if (iph1->remote->sa_family == AF_INET) { + struct vpnctl_socket_elem *sock_elem; + struct bound_addr *bound_addr; + u_int32_t address; + + address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; + LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) { + LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) { + if (bound_addr->address == address) { + if (version = bound_addr->version) + len += bound_addr->version->l; + break; + } + } + } + } + } + if ((buffer = vmalloc(len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); return -1; @@ -1489,13 +1940,28 @@ isakmp_cfg_getconfig(iph1) attr = (struct isakmp_data *)(attrpl + 1); for (i = 0; i < attrcount; i++) { - attr->type = htons(attrlist[i]); - attr->lorv = htons(0); - attr++; + switch (attrlist[i]) { + case APPLICATION_VERSION: + if (version) { + attr->type = htons(attrlist[i]); + attr->lorv = htons(version->l); + memcpy(attr + 1, version->v, version->l); + attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l); + break; + } else /* fall thru */; + default: + attr->type = htons(attrlist[i]); + attr->lorv = htons(0); + attr++; + break; + } } + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG REQUEST\n"); + error = isakmp_cfg_send(iph1, buffer, - ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL); vfree(buffer); @@ -1521,22 +1987,113 @@ isakmp_cfg_getaddr4(attr, ip) return; } +static void +isakmp_cfg_appendaddr4(attr, ip, num, max) + struct isakmp_data *attr; + struct in_addr *ip; + int *num; + int max; +{ + size_t alen = ntohs(attr->lorv); + in_addr_t *addr; + + if (alen != sizeof(*ip)) { + plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n"); + return; + } + if (*num == max) { + plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n"); + return; + } + + addr = (in_addr_t *)(attr + 1); + ip->s_addr = *addr; + (*num)++; + + return; +} + +static void +isakmp_cfg_getstring(attr, str) + struct isakmp_data *attr; + char *str; +{ + size_t alen = ntohs(attr->lorv); + char *src; + src = (char *)(attr + 1); + + memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen)); + + return; +} + +#define IP_MAX 40 + +void +isakmp_cfg_iplist_to_str(dest, count, addr, withmask) + char *dest; + int count; + void *addr; + int withmask; +{ + int i; + int p; + int l; + struct unity_network tmp; + for(i = 0, p = 0; i < count; i++) { + if(withmask == 1) + l = sizeof(struct unity_network); + else + l = sizeof(struct in_addr); + memcpy(&tmp, addr, l); + addr += l; + if((uint32_t)tmp.addr4.s_addr == 0) + break; + + inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX); + p += strlen(dest + p); + if(withmask == 1) { + dest[p] = '/'; + p++; + inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX); + p += strlen(dest + p); + } + dest[p] = ' '; + p++; + } + if(p > 0) + dest[p-1] = '\0'; + else + dest[0] = '\0'; +} + int isakmp_cfg_setenv(iph1, envp, envc) struct ph1handle *iph1; char ***envp; int *envc; { -#define IP_MAX 40 char addrstr[IP_MAX]; + char addrlist[IP_MAX * MAXNS + MAXNS]; + char *splitlist = addrlist; + char defdom[MAXPATHLEN + 1]; + int cidr, tmp; + char cidrstr[4]; + int i, p; + int test; + + plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n"); /* * Internal IPv4 address, either if * we are a client or a server. */ if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) || +#ifdef HAVE_LIBLDAP + (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) || +#endif #ifdef HAVE_LIBRADIUS - (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS) || + (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) || #endif (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) { inet_ntop(AF_INET, &iph1->mode_cfg->addr4, @@ -1549,6 +2106,15 @@ isakmp_cfg_setenv(iph1, envp, envc) return -1; } + if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) { + if (script_env_append(envp, envc, "XAUTH_USER", + iph1->mode_cfg->xauth.authdata.generic.usr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set XAUTH_USER\n"); + return -1; + } + } + /* Internal IPv4 mask */ if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) inet_ntop(AF_INET, &iph1->mode_cfg->mask4, @@ -1556,45 +2122,250 @@ isakmp_cfg_setenv(iph1, envp, envc) else addrstr[0] = '\0'; - /* - * During several releases, documentation adverised INTERNAL_NETMASK4 - * while code was using INTERNAL_MASK4. We now do both. - */ - if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { - plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n"); - return -1; - } - - if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { - plog(LLV_ERROR, LOCATION, NULL, - "Cannot set INTERNAL_NETMASK4\n"); - return -1; - } + /* + * During several releases, documentation adverised INTERNAL_NETMASK4 + * while code was using INTERNAL_MASK4. We now do both. + */ + if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n"); + return -1; + } + + if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_NETMASK4\n"); + return -1; + } + + tmp = ntohl(iph1->mode_cfg->mask4.s_addr); + for (cidr = 0; tmp != 0; cidr++) + tmp <<= 1; + snprintf(cidrstr, 3, "%d", cidr); + + if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n"); + return -1; + } /* Internal IPv4 DNS */ - if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) - inet_ntop(AF_INET, &iph1->mode_cfg->dns4, + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) { + /* First Internal IPv4 DNS (for compatibilty with older code */ + inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0], addrstr, IP_MAX); - else + + /* Internal IPv4 DNS - all */ + isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index, + (void *)iph1->mode_cfg->dns4, 0); + } else { addrstr[0] = '\0'; + addrlist[0] = '\0'; + } - if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) { + if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) { plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n"); return -1; } - + if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_DNS4_LIST\n"); + return -1; + } + /* Internal IPv4 WINS */ - if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) - inet_ntop(AF_INET, &iph1->mode_cfg->wins4, + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) { + /* + * First Internal IPv4 WINS + * (for compatibilty with older code + */ + inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0], addrstr, IP_MAX); - else + + /* Internal IPv4 WINS - all */ + isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index, + (void *)iph1->mode_cfg->wins4, 0); + } else { addrstr[0] = '\0'; + addrlist[0] = '\0'; + } - if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) { - plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_WINS4\n"); + if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_WINS4\n"); + return -1; + } + if (script_env_append(envp, envc, + "INTERNAL_WINS4_LIST", addrlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set INTERNAL_WINS4_LIST\n"); return -1; } + /* Deault domain */ + if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) + strlcpy(defdom, + iph1->mode_cfg->default_domain, + sizeof(defdom)); + else + defdom[0] = '\0'; + + if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot set DEFAULT_DOMAIN\n"); + return -1; + } + + /* Split networks */ + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) + splitlist = splitnet_list_2str(iph1->mode_cfg->split_include); + else { + splitlist = addrlist; + addrlist[0] = '\0'; + } + + if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n"); + return -1; + } + if (splitlist != addrlist) + racoon_free(splitlist); + + if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) + splitlist = splitnet_list_2str(iph1->mode_cfg->split_local); + else { + splitlist = addrlist; + addrlist[0] = '\0'; + } + + if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n"); + return -1; + } + if (splitlist != addrlist) + racoon_free(splitlist); + return 0; } + +int +isakmp_cfg_resize_pool(size) + int size; +{ + struct isakmp_cfg_port *new_pool; + size_t len; + int i; + + if (size == isakmp_cfg_config.pool_size) + return 0; + + plog(LLV_INFO, LOCATION, NULL, + "Resize address pool from %zu to %d\n", + isakmp_cfg_config.pool_size, size); + + /* If a pool already exists, check if we can shrink it */ + if ((isakmp_cfg_config.port_pool != NULL) && + (size < isakmp_cfg_config.pool_size)) { + for (i = isakmp_cfg_config.pool_size; i >= size; --i) { + if (isakmp_cfg_config.port_pool[i].used) { + plog(LLV_ERROR, LOCATION, NULL, + "resize pool from %zu to %d impossible " + "port %d is in use\n", + isakmp_cfg_config.pool_size, size, i); + size = i; + break; + } + } + } + + len = size * sizeof(*isakmp_cfg_config.port_pool); + new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len); + if (new_pool == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "resize pool from %zu to %d impossible: %s", + isakmp_cfg_config.pool_size, size, strerror(errno)); + return -1; + } + + /* If size increase, intialize correctly the new records */ + if (size > isakmp_cfg_config.pool_size) { + size_t unit; + size_t old_size; + + unit = sizeof(*isakmp_cfg_config.port_pool); + old_size = isakmp_cfg_config.pool_size; + + bzero((char *)new_pool + (old_size * unit), + (size - old_size) * unit); + } + + isakmp_cfg_config.port_pool = new_pool; + isakmp_cfg_config.pool_size = size; + + return 0; +} + +int +isakmp_cfg_init(cold) + int cold; +{ + int i; + int error; + + isakmp_cfg_config.network4 = (in_addr_t)0x00000000; + isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000; + for (i = 0; i < MAXNS; i++) + isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000; + isakmp_cfg_config.dns4_index = 0; + for (i = 0; i < MAXWINS; i++) + isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000; + isakmp_cfg_config.nbns4_index = 0; + if (cold != ISAKMP_CFG_INIT_COLD) { + if (isakmp_cfg_config.port_pool) { + racoon_free(isakmp_cfg_config.port_pool); + } + } + isakmp_cfg_config.port_pool = NULL; + isakmp_cfg_config.pool_size = 0; + isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM; + isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM; + if (cold != ISAKMP_CFG_INIT_COLD) { + if (isakmp_cfg_config.grouplist != NULL) { + for (i = 0; i < isakmp_cfg_config.groupcount; i++) + racoon_free(isakmp_cfg_config.grouplist[i]); + racoon_free(isakmp_cfg_config.grouplist); + } + } + isakmp_cfg_config.grouplist = NULL; + isakmp_cfg_config.groupcount = 0; + isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL; + isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE; + isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY; + strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN, + sizeof(isakmp_cfg_config.default_domain)); + strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd)); + + if (cold != ISAKMP_CFG_INIT_COLD ) + if (isakmp_cfg_config.splitnet_list != NULL) + splitnet_list_free(isakmp_cfg_config.splitnet_list, + &isakmp_cfg_config.splitnet_count); + isakmp_cfg_config.splitnet_list = NULL; + isakmp_cfg_config.splitnet_count = 0; + isakmp_cfg_config.splitnet_type = 0; + + isakmp_cfg_config.pfs_group = 0; + isakmp_cfg_config.save_passwd = 0; + + if (cold != ISAKMP_CFG_INIT_COLD ) + if (isakmp_cfg_config.splitdns_list != NULL) + racoon_free(isakmp_cfg_config.splitdns_list); + isakmp_cfg_config.splitdns_list = NULL; + isakmp_cfg_config.splitdns_len = 0; + + if (cold == ISAKMP_CFG_INIT_COLD) { + if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0) + return error; + } + + return 0; +} + diff --git a/ipsec-tools/racoon/isakmp_cfg.h b/ipsec-tools/racoon/isakmp_cfg.h index ba45ef8..1a0ce03 100644 --- a/ipsec-tools/racoon/isakmp_cfg.h +++ b/ipsec-tools/racoon/isakmp_cfg.h @@ -1,3 +1,5 @@ +/* $NetBSD: isakmp_cfg.h,v 1.6 2006/09/09 16:22:09 manu Exp $ */ + /* $KAME$ */ /* @@ -30,12 +32,8 @@ */ #ifdef HAVE_LIBPAM -#ifdef __APPLE__ -#include -#else #include #endif -#endif /* * XXX don't forget to update @@ -61,12 +59,14 @@ #define INTERNAL_IP6_SUBNET 15 /* For APPLICATION_VERSION */ -#define ISAKMP_CFG_RACOON_VERSION "KAME/racoon " \ - "+ Hybrid auth Patches " +#define ISAKMP_CFG_RACOON_VERSION "racoon / IPsec-tools" + +/* For the wins servers -- XXX find the value somewhere ? */ +#define MAXWINS 4 /* * Global configuration for ISAKMP mode confiration address allocation - * Readen from the mode_cfg section of racoon.conf + * Read from the mode_cfg section of racoon.conf */ struct isakmp_cfg_port { char used; @@ -76,34 +76,57 @@ struct isakmp_cfg_port { }; struct isakmp_cfg_config { - in_addr_t network4; - in_addr_t netmask4; - in_addr_t dns4; - in_addr_t nbns4; - struct isakmp_cfg_port *port_pool; - int authsource; - int confsource; - int accounting; - size_t pool_size; - int auth_throttle; - char motd[MAXPATHLEN + 1]; - int pfs_group; - int save_passwd; + in_addr_t network4; + in_addr_t netmask4; + in_addr_t dns4[MAXNS]; + int dns4_index; + in_addr_t nbns4[MAXWINS]; + int nbns4_index; + struct isakmp_cfg_port *port_pool; + int authsource; + int groupsource; + char **grouplist; + int groupcount; + int confsource; + int accounting; + size_t pool_size; + int auth_throttle; + /* XXX move this to a unity specific sub-structure */ + char default_domain[MAXPATHLEN + 1]; + char motd[MAXPATHLEN + 1]; + struct unity_netentry *splitnet_list; + int splitnet_count; + int splitnet_type; + char *splitdns_list; + int splitdns_len; + int pfs_group; + int save_passwd; }; +/* For utmp updating */ +#define TERMSPEC "vpn%d" + /* For authsource */ #define ISAKMP_CFG_AUTH_SYSTEM 0 #define ISAKMP_CFG_AUTH_RADIUS 1 #define ISAKMP_CFG_AUTH_PAM 2 +#define ISAKMP_CFG_AUTH_LDAP 4 + +/* For groupsource */ +#define ISAKMP_CFG_GROUP_SYSTEM 0 +#define ISAKMP_CFG_GROUP_LDAP 1 /* For confsource */ #define ISAKMP_CFG_CONF_LOCAL 0 #define ISAKMP_CFG_CONF_RADIUS 1 +#define ISAKMP_CFG_CONF_LDAP 2 /* For accounting */ #define ISAKMP_CFG_ACCT_NONE 0 #define ISAKMP_CFG_ACCT_RADIUS 1 #define ISAKMP_CFG_ACCT_PAM 2 +#define ISAKMP_CFG_ACCT_LDAP 3 +#define ISAKMP_CFG_ACCT_SYSTEM 4 /* For pool_size */ #define ISAKMP_CFG_MAX_CNX 255 @@ -111,6 +134,9 @@ struct isakmp_cfg_config { /* For motd */ #define ISAKMP_CFG_MOTD "/etc/motd" +/* For default domain */ +#define ISAKMP_CFG_DEFAULT_DOMAIN "" + extern struct isakmp_cfg_config isakmp_cfg_config; /* @@ -123,18 +149,29 @@ struct isakmp_cfg_state { char login[LOGINLEN + 1]; /* login */ struct in_addr addr4; /* IPv4 address */ struct in_addr mask4; /* IPv4 netmask */ - struct in_addr dns4; /* IPv4 DNS (when client only) */ - struct in_addr wins4; /* IPv4 WINS (when client only) */ + struct in_addr dns4[MAXNS]; /* IPv4 DNS (when client only) */ + int dns4_index; /* Number of IPv4 DNS (client only) */ + struct in_addr wins4[MAXWINS]; /* IPv4 WINS (when client only) */ + int wins4_index; /* Number of IPv4 WINS (client only) */ + char default_domain[MAXPATHLEN + 1]; /* Default domain recieved */ + struct unity_netentry + *split_include; /* UNITY_SPLIT_INCLUDE */ + int include_count; /* Number of SPLIT_INCLUDES */ + struct unity_netentry + *split_local; /* UNITY_LOCAL_LAN */ + int local_count; /* Number of SPLIT_LOCAL */ struct xauth_state xauth; /* Xauth state, if revelant */ struct isakmp_ivm *ivm; /* XXX Use iph1's ivm? */ + u_int32_t last_msgid; /* Last message-ID */ + vchar_t *attr_list; /* list of mode config attributes - used when started by api */ }; /* flags */ #define ISAKMP_CFG_VENDORID_XAUTH 0x01 /* Supports Xauth */ #define ISAKMP_CFG_VENDORID_UNITY 0x02 /* Cisco Unity compliant */ #define ISAKMP_CFG_PORT_ALLOCATED 0x04 /* Port allocated */ -#define ISAKMP_CFG_ADDR4_RADIUS 0x08 /* Address from RADIUS */ -#define ISAKMP_CFG_MASK4_RADIUS 0x10 /* Netmask from RADIUS */ +#define ISAKMP_CFG_ADDR4_EXTERN 0x08 /* Address from external config */ +#define ISAKMP_CFG_MASK4_EXTERN 0x10 /* Netmask from external config */ #define ISAKMP_CFG_ADDR4_LOCAL 0x20 /* Address from local pool */ #define ISAKMP_CFG_MASK4_LOCAL 0x40 /* Netmask from local pool */ #define ISAKMP_CFG_GOT_ADDR4 0x80 /* Client got address */ @@ -142,27 +179,36 @@ struct isakmp_cfg_state { #define ISAKMP_CFG_GOT_DNS4 0x200 /* Client got DNS */ #define ISAKMP_CFG_GOT_WINS4 0x400 /* Client got WINS */ #define ISAKMP_CFG_DELETE_PH1 0x800 /* phase 1 should be deleted */ +#define ISAKMP_CFG_GOT_DEFAULT_DOMAIN 0x1000 /* Client got default domain */ +#define ISAKMP_CFG_GOT_SPLIT_INCLUDE 0x2000 /* Client got a split network config */ +#define ISAKMP_CFG_GOT_SPLIT_LOCAL 0x4000 /* Client got a split LAN config */ +#define ISAKMP_CFG_GOT_REPLY 0x8000 /* got config data from reply - don't process again */ struct isakmp_pl_attr; struct ph1handle; struct isakmp_ivm; void isakmp_cfg_r(struct ph1handle *, vchar_t *); -int isakmp_cfg_attr_r(struct ph1handle *, u_int32_t, struct isakmp_pl_attr *); +int isakmp_cfg_attr_r(struct ph1handle *, u_int32_t, struct isakmp_pl_attr *, vchar_t *); int isakmp_cfg_reply(struct ph1handle *, struct isakmp_pl_attr *); -int isakmp_cfg_request(struct ph1handle *, struct isakmp_pl_attr *); -int isakmp_cfg_set(struct ph1handle *, struct isakmp_pl_attr *); -int isakmp_cfg_send(struct ph1handle *, vchar_t *, u_int32_t, int, int); +int isakmp_cfg_request(struct ph1handle *, struct isakmp_pl_attr *, vchar_t *); +int isakmp_cfg_set(struct ph1handle *, struct isakmp_pl_attr *, vchar_t *); +int isakmp_cfg_send(struct ph1handle *, vchar_t *, u_int32_t, int, int, int, vchar_t *); struct isakmp_ivm *isakmp_cfg_newiv(struct ph1handle *, u_int32_t); void isakmp_cfg_rmstate(struct ph1handle *); struct isakmp_cfg_state *isakmp_cfg_mkstate(void); vchar_t *isakmp_cfg_copy(struct ph1handle *, struct isakmp_data *); vchar_t *isakmp_cfg_short(struct ph1handle *, struct isakmp_data *, int); +vchar_t *isakmp_cfg_varlen(struct ph1handle *, struct isakmp_data *, char *, size_t); vchar_t *isakmp_cfg_string(struct ph1handle *, struct isakmp_data *, char *); int isakmp_cfg_getconfig(struct ph1handle *); int isakmp_cfg_setenv(struct ph1handle *, char ***, int *); -int isakmp_cfg_getport(struct ph1handle *); +int isakmp_cfg_resize_pool(int); +int isakmp_cfg_getport(struct ph1handle *); int isakmp_cfg_putport(struct ph1handle *, unsigned int); +int isakmp_cfg_init(int); +#define ISAKMP_CFG_INIT_COLD 1 +#define ISAKMP_CFG_INIT_WARM 0 #ifdef HAVE_LIBRADIUS struct rad_handle; @@ -174,3 +220,5 @@ int isakmp_cfg_radius_common(struct rad_handle *, int); int isakmp_cfg_accounting_pam(int, int); void cleanup_pam(int); #endif + +int isakmp_cfg_accounting_system(int, struct sockaddr *, char *, int); diff --git a/ipsec-tools/racoon/isakmp_frag.c b/ipsec-tools/racoon/isakmp_frag.c index e728c74..6422823 100644 --- a/ipsec-tools/racoon/isakmp_frag.c +++ b/ipsec-tools/racoon/isakmp_frag.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp $ */ +/* $NetBSD: isakmp_frag.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -147,10 +149,10 @@ isakmp_sendfrags(iph1, buf) memcpy(data, sdata, datalen); if (isakmp_send(iph1, frag) < 0) { - plog(LLV_ERROR, LOCATION, NULL, "isakmp_send failed\n"); + plog(LLV_ERROR, LOCATION, iph1->remote, "isakmp_send failed\n"); return -1; } - + vfree(frag); len -= datalen; diff --git a/ipsec-tools/racoon/isakmp_frag.h b/ipsec-tools/racoon/isakmp_frag.h index 52ee10a..f2d4c33 100644 --- a/ipsec-tools/racoon/isakmp_frag.h +++ b/ipsec-tools/racoon/isakmp_frag.h @@ -1,4 +1,6 @@ -/* $Id: isakmp_frag.h,v 1.2 2004/10/24 16:51:24 manubsd Exp $ */ +/* $NetBSD: isakmp_frag.h,v 1.5 2006/09/18 20:32:40 manu Exp $ */ + +/* Id: isakmp_frag.h,v 1.3 2005/04/09 16:25:24 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -29,7 +31,14 @@ * SUCH DAMAGE. */ +/* These are the values from parsing "remote {}" + block of the config file. */ +#define ISAKMP_FRAG_OFF FLASE /* = 0 */ +#define ISAKMP_FRAG_ON TRUE /* = 1 */ +#define ISAKMP_FRAG_FORCE 2 + /* IKE fragmentation capabilities */ +#define VENDORID_FRAG_IDENT 0x80000000 #define VENDORID_FRAG_BASE 0x40000000 #define VENDORID_FRAG_AGG 0x80000000 diff --git a/ipsec-tools/racoon/isakmp_ident.c b/ipsec-tools/racoon/isakmp_ident.c index d9e6cf9..6488207 100644 --- a/ipsec-tools/racoon/isakmp_ident.c +++ b/ipsec-tools/racoon/isakmp_ident.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_ident.c,v 1.13.2.2 2005/11/21 09:46:23 vanhu Exp $ */ +/* $NetBSD: isakmp_ident.c,v 1.6 2006/10/02 21:41:59 manu Exp $ */ + +/* Id: isakmp_ident.c,v 1.21 2006/04/06 16:46:08 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -79,9 +81,19 @@ #ifdef HAVE_GSSAPI #include "gssapi.h" #endif +#ifdef ENABLE_HYBRID +#include +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#ifdef ENABLE_FRAG +#include "isakmp_frag.h" +#endif #include "vpn_control.h" #include "vpn_control_var.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" static vchar_t *ident_ir2mx __P((struct ph1handle *)); static vchar_t *ident_ir3mx __P((struct ph1handle *)); @@ -107,6 +119,13 @@ ident_i1send(iph1, msg) vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; int i; #endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif #ifdef ENABLE_DPD vchar_t *vid_dpd = NULL; #endif @@ -128,8 +147,11 @@ ident_i1send(iph1, msg) /* create SA payload for my proposal */ iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal); - if (iph1->sa == NULL) + if (iph1->sa == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set proposal"); goto end; + } /* set SA payload to propose */ plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA); @@ -139,12 +161,53 @@ ident_i1send(iph1, msg) if (iph1->rmconf->nat_traversal) plist = isakmp_plist_append_natt_vids(plist, vid_natt); #endif +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (RMAUTHMETHOD(iph1)) { + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Xauth vendor ID generation failed\n"); + else + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Unity vendor ID generation failed\n"); + else + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + break; + default: + break; + } +#endif +#ifdef ENABLE_FRAG + if (iph1->rmconf->ike_frag) { + if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + } else { + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_IDENT); + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } + } +#endif #ifdef ENABLE_DPD if(iph1->rmconf->dpd){ vid_dpd = set_vendorid(VENDORID_DPD); if (vid_dpd != NULL) plist = isakmp_plist_append(plist, vid_dpd, - ISAKMP_NPTYPE_VID); + ISAKMP_NPTYPE_VID); } #endif @@ -156,18 +219,42 @@ ident_i1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } iph1->status = PHASE1ST_MSG1SENT; error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Main-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 1"), + CONSTSTR("Failed to transmit Main-Mode Message 1")); + } +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif #ifdef ENABLE_NATT for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) vfree(vid_natt[i]); #endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif #ifdef ENABLE_DPD if (vid_dpd != NULL) vfree(vid_dpd); @@ -212,8 +299,11 @@ ident_i2recv(iph1, msg) * NOTE: even if there's multiple VID/N, we'll ignore them. */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } pa = (struct isakmp_parse_t *)pbuf->v; /* SA payload is fixed postion */ @@ -224,8 +314,11 @@ ident_i2recv(iph1, msg) pa->type, ISAKMP_NPTYPE_SA); goto end; } - if (isakmp_p2ph(&satmp, pa->ptr) < 0) + if (isakmp_p2ph(&satmp, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SA payload"); goto end; + } pa++; for (/*nothing*/; @@ -239,6 +332,22 @@ ident_i2recv(iph1, msg) if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric)) natt_handle_vendorid(iph1, vid_numeric); #endif +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif #ifdef ENABLE_DPD if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) iph1->dpd_support=1; @@ -278,7 +387,18 @@ ident_i2recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Main-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 2"), + CONSTSTR("Failed to process Main-Mode Message 2")); + } if (pbuf) vfree(pbuf); if (satmp) @@ -315,24 +435,36 @@ ident_i2send(iph1, msg) /* generate DH public value */ if (oakley_dh_generate(iph1->approval->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate DH"); goto end; + } /* generate NONCE value */ iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); - if (iph1->nonce == NULL) + if (iph1->nonce == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NONCE"); goto end; + } #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && - gssapi_get_itoken(iph1, NULL) < 0) + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + gssapi_get_itoken(iph1, NULL) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get GSS token"); goto end; + } #endif /* create buffer to send isakmp payload */ iph1->sendbuf = ident_ir2mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to create send buffer"); goto end; + } #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -340,11 +472,15 @@ ident_i2send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -354,7 +490,18 @@ ident_i2send(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Main-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 3"), + CONSTSTR("Failed to transmit Main-Mode Message 3")); + } return error; } @@ -374,6 +521,7 @@ ident_i3recv(iph1, msg) vchar_t *pbuf = NULL; struct isakmp_parse_t *pa; int error = -1; + int vid_numeric; #ifdef HAVE_GSSAPI vchar_t *gsstoken = NULL; #endif @@ -391,8 +539,11 @@ ident_i3recv(iph1, msg) /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; @@ -400,24 +551,57 @@ ident_i3recv(iph1, msg) switch (pa->type) { case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_VID: - (void)check_vendorid(pa->ptr); + vid_numeric = check_vendorid(pa->ptr); +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif +#ifdef ENABLE_DPD + if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) + iph1->dpd_support=1; +#endif + break; case ISAKMP_NPTYPE_CR: - if (oakley_savecr(iph1, pa->ptr) < 0) + if (oakley_savecr(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CR payload"); goto end; + } break; #ifdef HAVE_GSSAPI case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process GSS payload"); goto end; + } gssapi_save_received_token(iph1, gsstoken); break; #endif @@ -431,8 +615,11 @@ ident_i3recv(iph1, msg) if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && pa->type == iph1->natt_options->payload_nat_d) { natd_received = NULL; - if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NATD payload"); goto end; + } /* set both bits first so that we can clear them upon verifying hashes */ @@ -494,7 +681,22 @@ ident_i3recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Main-Mode message 4"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 4"), + CONSTSTR("Failed to process Main-Mode Message 4")); + } +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (pbuf) vfree(pbuf); if (error) { @@ -536,29 +738,50 @@ ident_i3send(iph1, msg0) /* compute sharing secret of DH */ if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, - iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute DH"); goto end; + } /* generate SKEYIDs & IV & final cipher key */ - if (oakley_skeyid(iph1) < 0) + if (oakley_skeyid(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID"); goto end; - if (oakley_skeyid_dae(iph1) < 0) + } + if (oakley_skeyid_dae(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID-DAE"); goto end; - if (oakley_compute_enckey(iph1) < 0) + } + if (oakley_compute_enckey(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate ENCKEY"); goto end; - if (oakley_newiv(iph1) < 0) + } + if (oakley_newiv(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate IV"); goto end; + } /* make ID payload into isakmp status */ - if (ipsecdoi_setid1(iph1) < 0) + if (ipsecdoi_setid1(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ID"); goto end; + } #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && gssapi_more_tokens(iph1)) { plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n"); - if (gssapi_get_itoken(iph1, &len) < 0) + if (gssapi_get_itoken(iph1, &len) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get GSSAPI token"); goto end; + } if (len != 0) dohash = 0; } @@ -567,8 +790,11 @@ ident_i3send(iph1, msg0) /* generate HASH to send */ if (dohash) { iph1->hash = oakley_ph1hash_common(iph1, GENERATE); - if (iph1->hash == NULL) + if (iph1->hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate HASH"); goto end; + } } else iph1->hash = NULL; @@ -577,16 +803,23 @@ ident_i3send(iph1, msg0) /* create HDR;ID;HASH payload */ iph1->sendbuf = ident_ir3mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate send buffer"); goto end; + } /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -599,7 +832,18 @@ ident_i3send(iph1, msg0) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Main-Mode message 5"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 5"), + CONSTSTR("Failed to transmit Main-Mode Message 5")); + } return error; } @@ -621,6 +865,7 @@ ident_i4recv(iph1, msg0) vchar_t *msg = NULL; int error = -1; int type; + int vid_numeric; #ifdef HAVE_GSSAPI vchar_t *gsstoken = NULL; #endif @@ -640,13 +885,19 @@ ident_i4recv(iph1, msg0) goto end; } msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt"); goto end; + } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } iph1->pl_hash = NULL; @@ -656,30 +907,46 @@ ident_i4recv(iph1, msg0) switch (pa->type) { case ISAKMP_NPTYPE_ID: - if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process ID payload"); goto end; + } break; case ISAKMP_NPTYPE_HASH: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; break; case ISAKMP_NPTYPE_CERT: - if (oakley_savecert(iph1, pa->ptr) < 0) + if (oakley_savecert(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CERT payload"); goto end; + } break; case ISAKMP_NPTYPE_SIG: - if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SIG payload"); goto end; + } break; #ifdef HAVE_GSSAPI case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process GSS payload"); goto end; + } gssapi_save_received_token(iph1, gsstoken); break; #endif case ISAKMP_NPTYPE_VID: - (void)check_vendorid(pa->ptr); - break; + vid_numeric = check_vendorid(pa->ptr); +#ifdef ENABLE_DPD + if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) + iph1->dpd_support=1; +#endif + break; case ISAKMP_NPTYPE_N: isakmp_check_notify(pa->ptr, iph1); break; @@ -708,6 +975,10 @@ ident_i4recv(iph1, msg0) #endif type = oakley_validate_auth(iph1); if (type != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Initiator, Main-Mode Message 6"), + CONSTSTR("Failed to authenticate Main-Mode Message 6")); if (type == -1) { /* msg printed inner oakley_validate_auth() */ goto end; @@ -717,6 +988,10 @@ ident_i4recv(iph1, msg0) isakmp_info_send_n1(iph1, type, NULL); goto end; } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Initiator, Main-Mode Message 6"), + CONSTSTR(NULL)); #ifdef HAVE_GSSAPI } #endif @@ -744,7 +1019,18 @@ ident_i4recv(iph1, msg0) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Main-Mode message 6"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 6"), + CONSTSTR("Failed to transmit Main-Mode Message 6")); + } if (pbuf) vfree(pbuf); if (msg) @@ -788,6 +1074,11 @@ ident_i4send(iph1, msg) iph1->status = PHASE1ST_ESTABLISHED; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC, + CONSTSTR("Initiator, Main-Mode"), + CONSTSTR(NULL)); + error = 0; end: @@ -823,8 +1114,11 @@ ident_r1recv(iph1, msg) * NOTE: XXX even if multiple VID, we'll silently ignore those. */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } pa = (struct isakmp_parse_t *)pbuf->v; /* check the position of SA payload */ @@ -835,8 +1129,11 @@ ident_r1recv(iph1, msg) pa->type, ISAKMP_NPTYPE_SA); goto end; } - if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SA payload"); goto end; + } pa++; for (/*nothing*/; @@ -850,6 +1147,27 @@ ident_r1recv(iph1, msg) if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric)) natt_handle_vendorid(iph1, vid_numeric); #endif +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT)) + iph1->frag = 1; +#endif +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif #ifdef ENABLE_DPD if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) iph1->dpd_support=1; @@ -890,7 +1208,18 @@ ident_r1recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Main-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Main-Mode Message 1"), + CONSTSTR("Failed to process Main-Mode Message 1")); + } if (pbuf) vfree(pbuf); if (error) { @@ -915,13 +1244,22 @@ ident_r1send(iph1, msg) struct payload_list *plist = NULL; int error = -1; vchar_t *gss_sa = NULL; - vchar_t *vid = NULL; +#ifdef HAVE_GSSAPI + int free_gss_sa = 0; +#endif #ifdef ENABLE_NATT vchar_t *vid_natt = NULL; #endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif #ifdef ENABLE_DPD vchar_t *vid_dpd = NULL; #endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif /* validity check */ if (iph1->status != PHASE1ST_MSG1RECEIVED) { @@ -934,19 +1272,39 @@ ident_r1send(iph1, msg) isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); #ifdef HAVE_GSSAPI - if (iph1->approval->gssid != NULL) + if (iph1->approval->gssid != NULL) { gss_sa = ipsecdoi_setph1proposal(iph1->approval); - else + if (gss_sa != iph1->sa_ret) + free_gss_sa = 1; + } else #endif gss_sa = iph1->sa_ret; /* set SA payload to reply */ plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA); - /* Set Vendor ID, if necessary. */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n"); + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Xauth vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + } + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot create Unity vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + } +#endif #ifdef ENABLE_NATT /* Has the peer announced NAT-T? */ if (NATT_AVAILABLE(iph1)) @@ -963,6 +1321,20 @@ ident_r1send(iph1, msg) plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); } #endif +#ifdef ENABLE_FRAG + if (iph1->frag) { + vid_frag = set_vendorid(VENDORID_FRAG); + if (vid_frag != NULL) + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_IDENT); + if (vid_frag == NULL) + plog(LLV_ERROR, LOCATION, NULL, + "Frag vendorID construction failed\n"); + else + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } +#endif iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); @@ -972,11 +1344,15 @@ ident_r1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -990,22 +1366,40 @@ ident_r1send(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Main-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Main-Mode Message 2"), + CONSTSTR("Failed to transmit Main-Mode Message 2")); + } #ifdef HAVE_GSSAPI - if (gss_sa != iph1->sa_ret) + if (free_gss_sa) vfree(gss_sa); #endif - if (vid) - vfree(vid); - #ifdef ENABLE_NATT if (vid_natt) vfree(vid_natt); #endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif #ifdef ENABLE_DPD if (vid_dpd != NULL) vfree(vid_dpd); #endif +#ifdef ENABLE_FRAG + if (vid_frag != NULL) + vfree(vid_frag); +#endif return error; } @@ -1043,20 +1437,29 @@ ident_r2recv(iph1, msg) /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; pa++) { switch (pa->type) { case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_VID: (void)check_vendorid(pa->ptr); @@ -1068,8 +1471,11 @@ ident_r2recv(iph1, msg) break; #ifdef HAVE_GSSAPI case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process GSS payload"); goto end; + } gssapi_save_received_token(iph1, gsstoken); break; #endif @@ -1086,8 +1492,11 @@ ident_r2recv(iph1, msg) vchar_t *natd_received = NULL; int natd_verified; - if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NATD payload"); goto end; + } if (natd_seq == 0) iph1->natt_flags |= NAT_DETECTED; @@ -1137,7 +1546,18 @@ ident_r2recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Main-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Main-Mode Message 3"), + CONSTSTR("Failed to process Main-Mode Message 3")); + } if (pbuf) vfree(pbuf); #ifdef HAVE_GSSAPI @@ -1178,23 +1598,32 @@ ident_r2send(iph1, msg) /* generate DH public value */ if (oakley_dh_generate(iph1->approval->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate DH"); goto end; + } /* generate NONCE value */ iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); - if (iph1->nonce == NULL) + if (iph1->nonce == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NONCE"); goto end; + } #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_rtoken(iph1, NULL); #endif /* create HDR;KE;NONCE payload */ iph1->sendbuf = ident_ir2mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate send buffer"); goto end; + } #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -1202,11 +1631,15 @@ ident_r2send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -1214,24 +1647,50 @@ ident_r2send(iph1, msg) /* compute sharing secret of DH */ if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, - iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute DH"); goto end; + } /* generate SKEYIDs & IV & final cipher key */ - if (oakley_skeyid(iph1) < 0) + if (oakley_skeyid(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID"); goto end; - if (oakley_skeyid_dae(iph1) < 0) + } + if (oakley_skeyid_dae(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate SKEYID-DAE"); goto end; - if (oakley_compute_enckey(iph1) < 0) + } + if (oakley_compute_enckey(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate ENCKEY"); goto end; - if (oakley_newiv(iph1) < 0) + } + if (oakley_newiv(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate IV"); goto end; + } iph1->status = PHASE1ST_MSG2SENT; error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Main-Mode message 4"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Main-Mode Message 4"), + CONSTSTR("Failed to transmit Main-Mode Message 4")); + } return error; } @@ -1272,13 +1731,19 @@ ident_r3recv(iph1, msg0) goto end; } msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt"); goto end; + } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } iph1->pl_hash = NULL; @@ -1288,28 +1753,43 @@ ident_r3recv(iph1, msg0) switch (pa->type) { case ISAKMP_NPTYPE_ID: - if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process ID payload"); goto end; + } break; case ISAKMP_NPTYPE_HASH: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; break; case ISAKMP_NPTYPE_CR: - if (oakley_savecr(iph1, pa->ptr) < 0) + if (oakley_savecr(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CR payload"); goto end; + } break; case ISAKMP_NPTYPE_CERT: - if (oakley_savecert(iph1, pa->ptr) < 0) + if (oakley_savecert(iph1, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process CERT payload"); goto end; + } break; case ISAKMP_NPTYPE_SIG: - if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SIG payload"); goto end; + } break; #ifdef HAVE_GSSAPI case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process GSS payload"); goto end; + } gssapi_save_received_token(iph1, gsstoken); break; #endif @@ -1334,18 +1814,31 @@ ident_r3recv(iph1, msg0) { int ng = 0; - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: +#endif if (iph1->id_p == NULL || iph1->pl_hash == NULL) ng++; break; case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif if (iph1->id_p == NULL || iph1->sig_p == NULL) ng++; break; case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif if (iph1->pl_hash == NULL) ng++; break; @@ -1381,6 +1874,10 @@ ident_r3recv(iph1, msg0) #endif type = oakley_validate_auth(iph1); if (type != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Responder, Main-Mode Message 5"), + CONSTSTR("Failed to authenticate Main-Mode Message 5")); if (type == -1) { /* msg printed inner oakley_validate_auth() */ goto end; @@ -1390,6 +1887,10 @@ ident_r3recv(iph1, msg0) isakmp_info_send_n1(iph1, type, NULL); goto end; } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Responder, Main-Mode Message 5"), + CONSTSTR(NULL)); #ifdef HAVE_GSSAPI } #endif @@ -1419,7 +1920,18 @@ ident_r3recv(iph1, msg0) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Main-Mode message 5"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Main-Mode Message 5"), + CONSTSTR("Failed to process Main-Mode Message 5")); + } if (pbuf) vfree(pbuf); if (msg) @@ -1470,11 +1982,14 @@ ident_r3send(iph1, msg) } /* make ID payload into isakmp status */ - if (ipsecdoi_setid1(iph1) < 0) + if (ipsecdoi_setid1(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ID"); goto end; + } #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && gssapi_more_tokens(iph1)) { gssapi_get_rtoken(iph1, &len); if (len != 0) @@ -1486,8 +2001,11 @@ ident_r3send(iph1, msg) /* generate HASH to send */ plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n"); iph1->hash = oakley_ph1hash_common(iph1, GENERATE); - if (iph1->hash == NULL) + if (iph1->hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate HASH"); goto end; + } } else iph1->hash = NULL; @@ -1496,15 +2014,22 @@ ident_r3send(iph1, msg) /* create HDR;ID;HASH payload */ iph1->sendbuf = ident_ir3mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to create send buffer"); goto end; + } /* send HDR;ID;HASH to responder */ - if (isakmp_send(iph1, iph1->sendbuf) < 0) + if (isakmp_send(iph1, iph1->sendbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { + if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -1515,9 +2040,25 @@ ident_r3send(iph1, msg) iph1->status = PHASE1ST_ESTABLISHED; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC, + CONSTSTR("Responder, Main-Mode"), + CONSTSTR(NULL)); + error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Main-Mode message 6"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Main-Mode Message 6"), + CONSTSTR("Failed to process Main-Mode Message 6")); + } return error; } @@ -1568,7 +2109,7 @@ ident_ir2mx(iph1) } #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) gssapi_get_token_to_send(iph1, &gsstoken); #endif @@ -1579,7 +2120,7 @@ ident_ir2mx(iph1) plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); #endif @@ -1681,8 +2222,14 @@ ident_ir3mx(iph1) vchar_t *gsshash = NULL; #endif - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: +#endif /* create isakmp ID payload */ plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); @@ -1691,11 +2238,25 @@ ident_ir3mx(iph1) break; case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: - if (oakley_getmycert(iph1) < 0) +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: +#endif + if (oakley_getmycert(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get mycert"); goto end; + } - if (oakley_getsign(iph1) < 0) + if (oakley_getsign(iph1) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get sign"); goto end; + } /* create CR if need */ if (iph1->side == INITIATOR @@ -1706,7 +2267,7 @@ ident_ir3mx(iph1) cr = oakley_getcr(iph1); if (cr == NULL) { plog(LLV_ERROR, LOCATION, NULL, - "failed to get cr buffer.\n"); + "failed to get CR"); goto end; } } @@ -1731,8 +2292,11 @@ ident_ir3mx(iph1) case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: if (iph1->hash != NULL) { gsshash = gssapi_wraphash(iph1); - if (gsshash == NULL) + if (gsshash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate GSSAPI HASH"); goto end; + } } else { gssapi_get_token_to_send(iph1, &gsstoken); } @@ -1752,6 +2316,12 @@ ident_ir3mx(iph1) #endif case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif plog(LLV_ERROR, LOCATION, NULL, "not supported authentication type %d\n", iph1->approval->authmethod); @@ -1771,8 +2341,11 @@ ident_ir3mx(iph1) /* encoding */ new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv); - if (new == NULL) + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to encrypt"); goto end; + } vfree(buf); @@ -1781,6 +2354,10 @@ ident_ir3mx(iph1) error = 0; end: +#ifdef HAVE_GSSAPI + if (gsstoken) + vfree(gsstoken); +#endif if (cr) vfree(cr); if (error && buf != NULL) { diff --git a/ipsec-tools/racoon/isakmp_inf.c b/ipsec-tools/racoon/isakmp_inf.c index a681061..af7d93b 100644 --- a/ipsec-tools/racoon/isakmp_inf.c +++ b/ipsec-tools/racoon/isakmp_inf.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_inf.c,v 1.14.4.9 2005/08/02 15:09:26 vanhu Exp $ */ +/* $NetBSD: isakmp_inf.c,v 1.14.4.8 2007/08/01 11:52:20 vanhu Exp $ */ + +/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -62,6 +64,9 @@ # include # endif #endif +#ifdef ENABLE_HYBRID +#include +#endif #include "libpfkey.h" @@ -76,16 +81,19 @@ #include "localconf.h" #include "remoteconf.h" #include "sockmisc.h" +#include "handler.h" +#include "policy.h" +#include "proposal.h" #include "isakmp_var.h" #include "evt.h" #include "isakmp.h" #ifdef ENABLE_HYBRID #include "isakmp_xauth.h" +#include "isakmp_unity.h" #include "isakmp_cfg.h" #endif #include "isakmp_inf.h" #include "oakley.h" -#include "handler.h" #include "ipsec_doi.h" #include "crypto_openssl.h" #include "pfkey.h" @@ -99,17 +107,19 @@ #endif #include "vpn_control_var.h" #include "vpn_control.h" +#include "ike_session.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" /* information exchange */ -static int isakmp_info_recv_n __P((struct ph1handle *, vchar_t *, int)); -static int isakmp_info_recv_d __P((struct ph1handle *, vchar_t *)); +static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int); +static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int); #ifdef ENABLE_DPD static int isakmp_info_recv_r_u __P((struct ph1handle *, struct isakmp_pl_ru *, u_int32_t)); static int isakmp_info_recv_r_u_ack __P((struct ph1handle *, struct isakmp_pl_ru *, u_int32_t)); -static void isakmp_info_send_r_u __P((void *)); #endif #ifdef ENABLE_VPNCONTROL_PORT @@ -117,9 +127,64 @@ static int isakmp_info_recv_lb __P((struct ph1handle *, struct isakmp_pl_lb *lb, #endif static void purge_isakmp_spi __P((int, isakmp_index *, size_t)); -static void purge_ipsec_spi __P((struct sockaddr *, int, u_int32_t *, size_t)); static void info_recv_initialcontact __P((struct ph1handle *)); +static int +isakmp_ph1_responder_lifetime (struct ph1handle *iph1, + struct isakmp_pl_resp_lifetime *notify) +{ + char *spi; + + if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid spi_size in notification payload.\n"); + return -1; + } + spi = val2str((char *)(notify + 1), notify->spi_size); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "notification message ISAKMP-SA RESPONDER-LIFETIME, " + "doi=%d proto_id=%d spi=%s(size=%d).\n", + ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); + + /* TODO */ + #if 0 + struct isakmp_pl_attr *attrpl; + int len = ntohs(notify->h.len) - (sizeof(*notify) + notify->spi_size); + + attrpl = (struct isakmp_pl_attr *)((char *)(notify + 1) + notify->spi_size); + while (len > 0) { + } + #endif + + racoon_free(spi); + return 0; +} + +static int +isakmp_ph2_responder_lifetime (struct ph2handle *iph2, + struct isakmp_pl_resp_lifetime *notify) +{ + char *spi; + + if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { + plog(LLV_ERROR, LOCATION, iph2->dst, + "invalid spi_size in notification payload.\n"); + return -1; + } + spi = val2str((char *)(notify + 1), notify->spi_size); + + plog(LLV_DEBUG, LOCATION, iph2->dst, + "notification message IPSEC-SA RESPONDER-LIFETIME, " + "doi=%d proto_id=%d spi=%s(size=%d).\n", + ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); + + /* TODO */ + + racoon_free(spi); + return 0; +} + /* %%% * Information Exchange */ @@ -132,33 +197,60 @@ isakmp_info_recv(iph1, msg0) vchar_t *msg0; { vchar_t *msg = NULL; + vchar_t *pbuf = NULL; + u_int32_t msgid = 0; int error = -1; struct isakmp *isakmp; struct isakmp_gen *gen; + struct isakmp_parse_t *pa, *pap; void *p; vchar_t *hash, *payload; struct isakmp_gen *nd; u_int8_t np; int encrypted; + int flag; plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n"); encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E); + msgid = ((struct isakmp *)msg0->v)->msgid; /* Use new IV to decrypt Informational message. */ if (encrypted) { - struct isakmp_ivm *ivm; + if (iph1->ivm == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n"); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to process Information Message (no IV)")); + return -1; + } + /* compute IV */ ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid); - if (ivm == NULL) + if (ivm == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute IV"); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to process Information Message (can't compute IV)")); return -1; + } msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive); oakley_delivm(ivm); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt packet"); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to decrypt Information message")); return -1; + } } else msg = vdup(msg0); @@ -183,7 +275,8 @@ isakmp_info_recv(iph1, msg0) goto end; } - if (iph1->status != PHASE1ST_ESTABLISHED) { + if (iph1->status != PHASE1ST_ESTABLISHED && + (!iph1->approval || !iph1->skeyid_a)) { plog(LLV_ERROR, LOCATION, NULL, "ignore information because ISAKMP-SA " "has not been established yet.\n"); @@ -257,7 +350,7 @@ isakmp_info_recv(iph1, msg0) vfree(hash); vfree(payload); } else { - /* make sure the packet were encrypted after the beginning of phase 1. */ + /* make sure the packet was encrypted after the beginning of phase 1. */ switch (iph1->etype) { case ISAKMP_ETYPE_AGG: case ISAKMP_ETYPE_BASE: @@ -271,40 +364,350 @@ isakmp_info_recv(iph1, msg0) plog(LLV_ERROR, LOCATION, iph1->remote, "%s message must be encrypted\n", s_isakmp_nptype(np)); + error = 0; goto end; } } - switch (np) { - case ISAKMP_NPTYPE_N: - isakmp_info_recv_n(iph1, msg, encrypted); + if (!(pbuf = isakmp_parse(msg))) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); + error = -1; + goto end; + } + + error = 0; + for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { + switch (pa->type) { + case ISAKMP_NPTYPE_HASH: + /* Handled above */ + break; + case ISAKMP_NPTYPE_N: + error = isakmp_info_recv_n(iph1, + (struct isakmp_pl_n *)pa->ptr, + msgid, encrypted); + break; + case ISAKMP_NPTYPE_D: + error = isakmp_info_recv_d(iph1, + (struct isakmp_pl_d *)pa->ptr, + msgid, encrypted); + break; + case ISAKMP_NPTYPE_NONCE: + /* XXX to be 6.4.2 ike-01.txt */ + /* XXX IV is to be synchronized. */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "ignore Acknowledged Informational\n"); + break; + default: + /* don't send information, see isakmp_ident_r1() */ + error = 0; + plog(LLV_ERROR, LOCATION, iph1->remote, + "reject the packet, " + "received unexpected payload type %s.\n", + s_isakmp_nptype(gen->np)); + } + if(error < 0) { + break; + } else { + flag |= error; + } + } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Information message"), + CONSTSTR(NULL)); + +end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to process Information Message")); + } + if (msg != NULL) + vfree(msg); + if (pbuf != NULL) + vfree(pbuf); + return error; +} + +/* + * handling of Notification payload + */ +static int +isakmp_info_recv_n(iph1, notify, msgid, encrypted) + struct ph1handle *iph1; + struct isakmp_pl_n *notify; + u_int32_t msgid; + int encrypted; +{ + u_int type; + vchar_t *pbuf; + vchar_t *ndata; + char *nraw; + size_t l; + char *spi; + + type = ntohs(notify->type); + + switch (type) { + case ISAKMP_NTYPE_CONNECTED: + case ISAKMP_NTYPE_REPLAY_STATUS: +#ifdef ENABLE_HYBRID + case ISAKMP_NTYPE_UNITY_HEARTBEAT: +#endif + /* do something */ break; - case ISAKMP_NPTYPE_D: + case ISAKMP_NTYPE_RESPONDER_LIFETIME: + if (encrypted) { + return(isakmp_ph1_responder_lifetime(iph1, + (struct isakmp_pl_resp_lifetime *)notify)); + } + break; + case ISAKMP_NTYPE_INITIAL_CONTACT: if (encrypted) - isakmp_info_recv_d(iph1, msg); - else - plog(LLV_ERROR, LOCATION, iph1->remote, - "unencrypted information message with delete payload received\n"); + info_recv_initialcontact(iph1); + return 0; break; - case ISAKMP_NPTYPE_NONCE: - /* XXX to be 6.4.2 ike-01.txt */ - /* XXX IV is to be synchronized. */ - plog(LLV_ERROR, LOCATION, iph1->remote, - "ignore Acknowledged Informational\n"); +#ifdef ENABLE_DPD + case ISAKMP_NTYPE_R_U_THERE: + if (encrypted) + return isakmp_info_recv_r_u(iph1, + (struct isakmp_pl_ru *)notify, msgid); + break; + case ISAKMP_NTYPE_R_U_THERE_ACK: + if (encrypted) + return isakmp_info_recv_r_u_ack(iph1, + (struct isakmp_pl_ru *)notify, msgid); break; +#endif +#ifdef ENABLE_VPNCONTROL_PORT + case ISAKMP_NTYPE_LOAD_BALANCE: + isakmp_info_recv_lb(iph1, (struct isakmp_pl_lb *)notify, encrypted); + break; +#endif + default: - /* don't send information, see isakmp_ident_r1() */ - error = 0; + { + /* XXX there is a potential of dos attack. */ + if(type >= ISAKMP_NTYPE_MINERROR && + type <= ISAKMP_NTYPE_MAXERROR) { + if (msgid == 0) { + /* don't think this realy deletes ph1 ? */ + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete phase1 handle.\n"); + return -1; + } else { + if (getph2bymsgid(iph1, msgid) == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "fatal %s notify messsage, " + "phase1 should be deleted.\n", + s_isakmp_notify_msg(type)); + } else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "fatal %s notify messsage, " + "phase2 should be deleted.\n", + s_isakmp_notify_msg(type)); + } + } + } else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "unhandled notify message %s, " + "no phase2 handle found.\n", + s_isakmp_notify_msg(type)); + } + } + break; + } + + /* get spi if specified and allocate */ + if(notify->spi_size > 0) { + if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "invalid spi_size in notification payload.\n"); + return -1; + } + spi = val2str((char *)(notify + 1), notify->spi_size); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "notification message %d:%s, " + "doi=%d proto_id=%d spi=%s(size=%d).\n", + type, s_isakmp_notify_msg(type), + ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); + + racoon_free(spi); + } + + /* Send the message data to the logs */ + if(type >= ISAKMP_NTYPE_MINERROR && + type <= ISAKMP_NTYPE_MAXERROR) { + l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size; + if (l > 0) { + nraw = (char*)notify; + nraw += sizeof(*notify) + notify->spi_size; + if ((ndata = vmalloc(l)) != NULL) { + memcpy(ndata->v, nraw, ndata->l); + plog(LLV_ERROR, LOCATION, iph1->remote, + "Message: '%s'.\n", + binsanitize(ndata->v, ndata->l)); + vfree(ndata); + } else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cannot allocate memory\n"); + } + } + } + return 0; +} + +/* + * handling of Deletion payload + */ +static int +isakmp_info_recv_d(iph1, delete, msgid, encrypted) + struct ph1handle *iph1; + struct isakmp_pl_d *delete; + u_int32_t msgid; + int encrypted; +{ + int tlen, num_spi; + vchar_t *pbuf; + int protected = 0; + struct ph1handle *del_ph1; + struct ph2handle *iph2; + union { + u_int32_t spi32; + u_int16_t spi16[2]; + } spi; + + if (ntohl(delete->doi) != IPSEC_DOI) { plog(LLV_ERROR, LOCATION, iph1->remote, - "reject the packet, " - "received unexpecting payload type %d.\n", - gen->np); + "delete payload with invalid doi:%d.\n", + ntohl(delete->doi)); +#ifdef ENABLE_HYBRID + /* + * At deconnexion time, Cisco VPN client does this + * with a zero DOI. Don't give up in that situation. + */ + if (((iph1->mode_cfg->flags & + ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0)) + return 0; +#else + return 0; +#endif + } + + num_spi = ntohs(delete->num_spi); + tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d); + + if (tlen != num_spi * delete->spi_size) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "deletion payload with invalid length.\n"); + return 0; + } + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "delete payload for protocol %s\n", + s_ipsecdoi_proto(delete->proto_id)); + + if(!iph1->rmconf->weak_phase1_check && !encrypted) { + plog(LLV_WARNING, LOCATION, iph1->remote, + "Ignoring unencrypted delete payload " + "(check the weak_phase1_check option)\n"); + return 0; + } + + switch (delete->proto_id) { + case IPSECDOI_PROTO_ISAKMP: + if (delete->spi_size != sizeof(isakmp_index)) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete payload with strange spi " + "size %d(proto_id:%d)\n", + delete->spi_size, delete->proto_id); + return 0; + } + + del_ph1=getph1byindex((isakmp_index *)(delete + 1)); + if(del_ph1 != NULL){ + + // hack: start a rekey now, if one was pending (only for client). + if (del_ph1->sce_rekey && + del_ph1->parent_session && + del_ph1->parent_session->is_client && + del_ph1->parent_session->established) { + isakmp_ph1rekeyexpire(del_ph1); + } + + EVT_PUSH(del_ph1->local, del_ph1->remote, + EVTT_PEERPH1_NOPROP, NULL); + if (del_ph1->scr) + SCHED_KILL(del_ph1->scr); + + /* + * Do not delete IPsec SAs when receiving an IKE delete notification. + * Just delete the IKE SA. + */ +#ifdef ENABLE_VPNCONTROL_PORT + + if (del_ph1->started_by_api) + if (islast_ph1(del_ph1)) { + u_int32_t address; + + /* notify the API that we have received the delete */ + if (iph1->remote->sa_family == AF_INET) + address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr; + else + address = 0; + vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE, FROM_REMOTE, address, 0, NULL); + } +#endif + isakmp_ph1expire(del_ph1); + } + break; + + case IPSECDOI_PROTO_IPSEC_AH: + case IPSECDOI_PROTO_IPSEC_ESP: + if (delete->spi_size != sizeof(u_int32_t)) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete payload with strange spi " + "size %d(proto_id:%d)\n", + delete->spi_size, delete->proto_id); + return 0; + } + EVT_PUSH(iph1->local, iph1->remote, + EVTT_PEER_DELETE, NULL); + purge_ipsec_spi(iph1->remote, delete->proto_id, + (u_int32_t *)(delete + 1), num_spi); break; + + case IPSECDOI_PROTO_IPCOMP: + /* need to handle both 16bit/32bit SPI */ + memset(&spi, 0, sizeof(spi)); + if (delete->spi_size == sizeof(spi.spi16[1])) { + memcpy(&spi.spi16[1], delete + 1, + sizeof(spi.spi16[1])); + } else if (delete->spi_size == sizeof(spi.spi32)) + memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32)); + else { + plog(LLV_ERROR, LOCATION, iph1->remote, + "delete payload with strange spi " + "size %d(proto_id:%d)\n", + delete->spi_size, delete->proto_id); + return 0; + } + purge_ipsec_spi(iph1->remote, delete->proto_id, + &spi.spi32, num_spi); + break; + + default: + plog(LLV_ERROR, LOCATION, iph1->remote, + "deletion message received, " + "invalid proto_id: %d\n", + delete->proto_id); + return 0; } - end: - if (msg != NULL) - vfree(msg); + plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); return 0; } @@ -348,6 +751,17 @@ isakmp_info_send_d1(iph1) error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_D, 0); vfree(payload); + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("Delete ISAKMP-SA"), + CONSTSTR("Failed to transmit Delete-ISAKMP-SA message")); + } else { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + CONSTSTR("Delete ISAKMP-SA"), + CONSTSTR(NULL)); + } return error; } @@ -375,9 +789,23 @@ isakmp_info_send_d2(iph2) * don't send delete information if there is no phase 1 handler. * It's nonsensical to negotiate phase 1 to send the information. */ - iph1 = getph1byaddr(iph2->src, iph2->dst); - if (iph1 == NULL) + iph1 = ike_session_get_established_ph1(iph2->parent_session); + if (!iph1) { + iph1 = getph1byaddr(iph2->src, iph2->dst); + } + if (iph1 == NULL){ + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information message")); + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("Delete IPSEC-SA"), + CONSTSTR("Failed to transmit Delete-IPSEC-SA message")); + plog(LLV_DEBUG2, LOCATION, NULL, + "No ph1 handler found, could not send DELETE_SA\n"); return 0; + } /* create delete payload */ for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { @@ -392,6 +820,14 @@ isakmp_info_send_d2(iph2) tlen = sizeof(*d) + pr->spisize; payload = vmalloc(tlen); if (payload == NULL) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information message")); + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("Delete IPSEC-SA"), + CONSTSTR("Failed to transmit Delete-IPSEC-SA message")); plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer for payload.\n"); return errno; @@ -416,6 +852,17 @@ isakmp_info_send_d2(iph2) error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_D, 0); vfree(payload); + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("Delete IPSEC-SA"), + CONSTSTR("Failed to transmit Delete-IPSEC-SA")); + } else { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + CONSTSTR("Delete IPSEC-SA"), + CONSTSTR(NULL)); + } } return error; @@ -438,10 +885,15 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) int error = -1; struct isakmp_pl_n *n; int spisiz = 0; /* see below */ + ike_session_t *sess = ike_session_get_session(local, remote, FALSE); /* search appropreate configuration */ rmconf = getrmconf(remote); if (rmconf == NULL) { + IPSECSESSIONTRACEREVENT(sess, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information message (no remote configuration)")); plog(LLV_ERROR, LOCATION, remote, "no configuration found for peer address.\n"); goto end; @@ -449,20 +901,43 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) /* add new entry to isakmp status table. */ iph1 = newph1(); - if (iph1 == NULL) + if (iph1 == NULL) { + IPSECSESSIONTRACEREVENT(sess, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information message (no new phase1)")); + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate ph1"); return -1; + } memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t)); isakmp_newcookie((char *)&iph1->index.r_ck, remote, local); iph1->status = PHASE1ST_START; iph1->rmconf = rmconf; +#ifdef __APPLE__ + if (link_rmconf_to_ph1(rmconf) < 0) { + IPSECSESSIONTRACEREVENT(sess, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information message (can't link remote configuration to phase1)")); + plog(LLV_ERROR, LOCATION, remote, + "couldn't link " + "configuration.\n"); + iph1->rmconf = NULL; + error = -1; + goto end; + } +#endif iph1->side = INITIATOR; iph1->version = isakmp->v; iph1->flags = 0; iph1->msgid = 0; /* XXX */ #ifdef ENABLE_HYBRID - if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) - return -1; + if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { + error = -1; + goto end; + } #endif #ifdef ENABLE_FRAG iph1->frag = 0; @@ -470,16 +945,29 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) #endif /* copy remote address */ - if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) - return -1; + if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + IPSECSESSIONTRACEREVENT(sess, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information Message (can't copy phase1 addresses)")); + plog(LLV_ERROR, LOCATION, NULL, + "failed to copy ph1 addresses"); + error = -1; + goto end; + } tlen = sizeof(*n) + spisiz; if (data) tlen += data->l; payload = vmalloc(tlen); if (payload == NULL) { + IPSECSESSIONTRACEREVENT(sess, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information Message (can't allocate payload)")); plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer to send.\n"); + error = -1; goto end; } @@ -491,7 +979,7 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) n->spi_size = spisiz; n->type = htons(type); if (spisiz) - memset(n + 1, 0, spisiz); /*XXX*/ + memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */ if (data) memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); @@ -512,7 +1000,18 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); vfree(payload); - + if (error) { + IPSECSESSIONTRACEREVENT(sess, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("Without ISAKMP-SA"), + CONSTSTR("Failed to transmit Without-ISAKMP-SA message")); + } else { + IPSECSESSIONTRACEREVENT(sess, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + CONSTSTR("Without ISAKMP-SA"), + CONSTSTR(NULL)); + } + end: if (iph1 != NULL) delph1(iph1); @@ -556,6 +1055,10 @@ isakmp_info_send_n1(iph1, type, data) tlen += data->l; payload = vmalloc(tlen); if (payload == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("ISAKMP-SA"), + CONSTSTR("Failed to transmit ISAKMP-SA message (can't allocate payload)")); plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer to send.\n"); return errno; @@ -591,6 +1094,17 @@ isakmp_info_send_n1(iph1, type, data) error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags); vfree(payload); + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("ISAKMP-SA"), + CONSTSTR("Can't transmit ISAKMP-SA message")); + } else { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + CONSTSTR("ISAKMP-SA"), + CONSTSTR(NULL)); + } return error; } @@ -622,6 +1136,10 @@ isakmp_info_send_n2(iph2, type, data) tlen += data->l; payload = vmalloc(tlen); if (payload == NULL) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("IPSEC-SA"), + CONSTSTR("Failed to transmit IPSEC-SA message (can't allocate payload)")); plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer to send.\n"); return errno; @@ -641,7 +1159,18 @@ isakmp_info_send_n2(iph2, type, data) iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */ error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags); vfree(payload); - + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("IPSEC-SA"), + CONSTSTR("Failed to transmit IPSEC-SA message")); + } else { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + CONSTSTR("IPSEC-SA"), + CONSTSTR(NULL)); + } + return error; } @@ -666,22 +1195,39 @@ isakmp_info_send_common(iph1, payload, np, flags) /* add new entry to isakmp status table */ iph2 = newph2(); - if (iph2 == NULL) + if (iph2 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate ph2"); goto end; + } iph2->dst = dupsaddr(iph1->remote); + if (iph2->dst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to duplicate remote address"); + delph2(iph2); + goto end; + } iph2->src = dupsaddr(iph1->local); + if (iph2->src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to duplicate local address"); + delph2(iph2); + goto end; + } switch (iph1->remote->sa_family) { case AF_INET: -#ifndef ENABLE_NATT +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in *)iph2->dst)->sin_port = 0; ((struct sockaddr_in *)iph2->src)->sin_port = 0; #endif break; #ifdef INET6 case AF_INET6: +#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0; ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0; +#endif break; #endif default: @@ -699,6 +1245,8 @@ isakmp_info_send_common(iph1, payload, np, flags) if (iph1->skeyid_a != NULL) { iph2->ivm = oakley_newiv2(iph1, iph2->msgid); if (iph2->ivm == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate IV"); delph2(iph2); goto end; } @@ -706,6 +1254,8 @@ isakmp_info_send_common(iph1, payload, np, flags) /* generate HASH(1) */ hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload); if (hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate HASH"); delph2(iph2); goto end; } @@ -775,13 +1325,18 @@ isakmp_info_send_common(iph1, payload, np, flags) tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive, iph2->ivm->iv); VPTRINIT(iph2->sendbuf); - if (tmp == NULL) + if (tmp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to encrypt packet"); goto err; + } iph2->sendbuf = tmp; } /* HDR*, HASH(1), N */ if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); VPTRINIT(iph2->sendbuf); goto err; } @@ -797,9 +1352,20 @@ isakmp_info_send_common(iph1, payload, np, flags) /* XXX If Acknowledged Informational required, don't delete ph2handle */ error = 0; VPTRINIT(iph2->sendbuf); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Information message"), + CONSTSTR(NULL)); + goto err; /* XXX */ end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Information message"), + CONSTSTR("Failed to transmit Information message")); + } if (hash) vfree(hash); return error; @@ -865,157 +1431,7 @@ isakmp_add_pl_n(buf0, np_p, type, pr, data) return buf; } -/* - * handling to receive Notification payload - */ -static int -isakmp_info_recv_n(iph1, msg, encrypted) - struct ph1handle *iph1; - vchar_t *msg; - int encrypted; -{ - struct isakmp_pl_n *n = NULL; - u_int type; - vchar_t *pbuf; - struct isakmp_parse_t *pa, *pap; - char *spi; - - if (!(pbuf = isakmp_parse(msg))) - return -1; - pa = (struct isakmp_parse_t *)pbuf->v; - for (pap = pa; pap->type; pap++) { - switch (pap->type) { - case ISAKMP_NPTYPE_HASH: - /* do something here */ - break; - case ISAKMP_NPTYPE_NONCE: - /* send to ack */ - break; - case ISAKMP_NPTYPE_N: - n = (struct isakmp_pl_n *)pap->ptr; - break; - default: - vfree(pbuf); - return -1; - } - } - vfree(pbuf); - if (!n) - return -1; - - type = ntohs(n->type); - - switch (type) { - case ISAKMP_NTYPE_CONNECTED: - case ISAKMP_NTYPE_RESPONDER_LIFETIME: - case ISAKMP_NTYPE_REPLAY_STATUS: - /* do something */ - break; - case ISAKMP_NTYPE_INITIAL_CONTACT: - if (encrypted) - info_recv_initialcontact(iph1); - else - plog(LLV_ERROR, LOCATION, iph1->remote, - "unencrypted INITIAL_CONTACT message received"); - break; -#ifdef ENABLE_DPD - case ISAKMP_NTYPE_R_U_THERE: - if (encrypted) - isakmp_info_recv_r_u(iph1, (struct isakmp_pl_ru *)n, - ((struct isakmp *)msg->v)->msgid); - else - plog(LLV_ERROR, LOCATION, iph1->remote, - "unencrypted R_U_THERE message received"); - break; - case ISAKMP_NTYPE_R_U_THERE_ACK: - if (encrypted) - isakmp_info_recv_r_u_ack(iph1, (struct isakmp_pl_ru *)n, - ((struct isakmp *)msg->v)->msgid); - else - plog(LLV_ERROR, LOCATION, iph1->remote, - "unencrypted R_U_THERE_ACK received"); - break; -#endif - -#ifdef ENABLE_VPNCONTROL_PORT - case ISAKMP_NTYPE_LOAD_BALANCE: - isakmp_info_recv_lb(iph1, (struct isakmp_pl_lb *)n, encrypted); - break; -#endif - - default: - if (encrypted) { - u_int32_t msgid = ((struct isakmp *)msg->v)->msgid; - struct ph2handle *iph2; - - /* XXX there is a potential of dos attack. */ - if (msgid == 0) { - /* delete ph1 */ - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete phase1 handle.\n"); - return -1; - } else { - iph2 = getph2bymsgid(iph1, msgid); - if (iph2 == NULL) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "unknown notify message, " - "no phase2 handle found.\n"); - } else { - /* sanity check */ - if (n->h.len < (sizeof(struct isakmp_pl_n) + n->spi_size)) - plog(LLV_ERROR, LOCATION, iph1->remote, - "notification payload length invalid.\n"); - else { - -#ifdef ENABLE_VPNCONTROL_PORT - - u_int32_t address; - u_int16_t data_len = n->h.len - (sizeof(struct isakmp_pl_n) + n->spi_size); - u_int8_t *data_ptr = ((u_int8_t *)n) + (n->h.len - data_len); - - if (type == ISAKMP_INTERNAL_ERROR || - type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) { - if (iph1->remote->sa_family == AF_INET) - address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; - else - address = 0; - - vpncontrol_notify_ike_failed(type, FROM_REMOTE, address, data_len, data_ptr); - } -#endif - /* delete ph2 */ - unbindph12(iph2); - remph2(iph2); - delph2(iph2); - } - } - } - } else - plog(LLV_ERROR, LOCATION, iph1->remote, - "unencrypted notification message received"); - break; - } - - /* get spi and allocate */ - if (ntohs(n->h.len) < sizeof(*n) + n->spi_size) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "invalid spi_size in notification payload.\n"); - return -1; - } - spi = val2str((char *)(n + 1), n->spi_size); - - plog(LLV_DEBUG, LOCATION, iph1->remote, - "notification message %d:%s, " - "doi=%d proto_id=%d spi=%s(size=%d).\n", - type, s_isakmp_notify_msg(type), - ntohl(n->doi), n->proto_id, spi, n->spi_size); - - racoon_free(spi); - - return(0); -} - -void +static void purge_isakmp_spi(proto, spi, n) int proto; isakmp_index *spi; /*network byteorder*/ @@ -1034,14 +1450,17 @@ purge_isakmp_spi(proto, spi, n) s_ipsecdoi_proto(proto), isakmp_pindex(&spi[i], 0)); - if (iph1->sce) - SCHED_KILL(iph1->sce); + SCHED_KILL(iph1->sce); + SCHED_KILL(iph1->sce_rekey); iph1->status = PHASE1ST_EXPIRED; + ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); } } -static void + + +void purge_ipsec_spi(dst0, proto, spi, n) struct sockaddr *dst0; int proto; @@ -1051,11 +1470,18 @@ purge_ipsec_spi(dst0, proto, spi, n) vchar_t *buf = NULL; struct sadb_msg *msg, *next, *end; struct sadb_sa *sa; + struct sadb_lifetime *lt; struct sockaddr *src, *dst; struct ph2handle *iph2; + u_int64_t created; size_t i; caddr_t mhp[SADB_EXT_MAX + 1]; + plog(LLV_DEBUG2, LOCATION, NULL, + "purge_ipsec_spi:\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0)); + plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0])); + buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto)); if (buf == NULL) { plog(LLV_DEBUG, LOCATION, NULL, @@ -1091,18 +1517,27 @@ purge_ipsec_spi(dst0, proto, spi, n) } src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + if(lt != NULL) + created = lt->sadb_lifetime_addtime; + else + created = 0; if (sa->sadb_sa_state != SADB_SASTATE_MATURE && sa->sadb_sa_state != SADB_SASTATE_DYING) { msg = next; continue; } + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst)); + + /* XXX n^2 algorithm, inefficient */ /* don't delete inbound SAs at the moment */ /* XXX should we remove SAs with opposite direction as well? */ - if (CMPSADDR(dst0, dst)) { + if (CMPSADDR2(dst0, dst)) { msg = next; continue; } @@ -1125,7 +1560,7 @@ purge_ipsec_spi(dst0, proto, spi, n) * exists. */ iph2 = getph2bysaidx(src, dst, proto, spi[i]); - if (iph2) { + if(iph2 != NULL){ delete_spd(iph2); unbindph12(iph2); remph2(iph2); @@ -1170,9 +1605,12 @@ info_recv_initialcontact(iph1) if (f_local) return; + // TODO: make sure that is_rekey is cleared for this. and session indicates the same #if 0 - loc = strdup(saddrwop2str(iph1->local)); - rem = strdup(saddrwop2str(iph1->remote)); + loc = racoon_strdup(saddrwop2str(iph1->local)); + rem = racoon_strdup(saddrwop2str(iph1->remote)); + STRDUP_FATAL(loc); + STRDUP_FATAL(rem); /* * Purge all IPSEC-SAs for the peer. We can do this @@ -1347,162 +1785,6 @@ info_recv_initialcontact(iph1) vfree(buf); } -/* - * handling to receive Deletion payload - */ -static int -isakmp_info_recv_d(iph1, msg) - struct ph1handle *iph1; - vchar_t *msg; -{ - struct isakmp_pl_d *d; - int tlen, num_spi; - vchar_t *pbuf; - struct isakmp_parse_t *pa, *pap; - int protected = 0; - union { - u_int32_t spi32; - u_int16_t spi16[2]; - } spi; - - /* validate the type of next payload */ - if (!(pbuf = isakmp_parse(msg))) - return -1; - pa = (struct isakmp_parse_t *)pbuf->v; - for (pap = pa; pap->type; pap++) { - switch (pap->type) { - case ISAKMP_NPTYPE_D: - break; - case ISAKMP_NPTYPE_HASH: - if (pap == pa) { - protected++; - break; - } - plog(LLV_ERROR, LOCATION, iph1->remote, - "received next payload type %d " - "in wrong place (must be the first payload).\n", - pap->type); - vfree(pbuf); - return -1; - default: - /* don't send information, see isakmp_ident_r1() */ - plog(LLV_ERROR, LOCATION, iph1->remote, - "reject the packet, " - "received unexpecting payload type %d.\n", - pap->type); - vfree(pbuf); - return 0; - } - } - - if (!protected) { - plog(LLV_ERROR, LOCATION, NULL, - "delete payload is not proteted, " - "ignored.\n"); - vfree(pbuf); - return -1; - } - - /* process a delete payload */ - for (pap = pa; pap->type; pap++) { - if (pap->type != ISAKMP_NPTYPE_D) - continue; - - d = (struct isakmp_pl_d *)pap->ptr; - - if (ntohl(d->doi) != IPSEC_DOI) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with invalid doi:%d.\n", - ntohl(d->doi)); -#ifdef ENABLE_HYBRID - /* - * At deconnexion time, Cisco VPN client does this - * with a zero DOI. Don't give up in that situation. - */ - if (((iph1->mode_cfg->flags & - ISAKMP_CFG_VENDORID_UNITY) == 0) || (d->doi != 0)) - continue; -#else - continue; -#endif - } - - num_spi = ntohs(d->num_spi); - tlen = ntohs(d->h.len) - sizeof(struct isakmp_pl_d); - - if (tlen != num_spi * d->spi_size) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "deletion payload with invalid length.\n"); - vfree(pbuf); - return -1; - } - - switch (d->proto_id) { - case IPSECDOI_PROTO_ISAKMP: - if (d->spi_size != sizeof(isakmp_index)) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with strange spi " - "size %d(proto_id:%d)\n", - d->spi_size, d->proto_id); - continue; - } - - if (iph1->scr) - SCHED_KILL(iph1->scr); - - purge_remote(iph1); - break; - - case IPSECDOI_PROTO_IPSEC_AH: - case IPSECDOI_PROTO_IPSEC_ESP: - if (d->spi_size != sizeof(u_int32_t)) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with strange spi " - "size %d(proto_id:%d)\n", - d->spi_size, d->proto_id); - continue; - } - EVT_PUSH(iph1->local, iph1->remote, - EVTT_PEER_DELETE, NULL); - purge_ipsec_spi(iph1->remote, d->proto_id, - (u_int32_t *)(d + 1), num_spi); - break; - - case IPSECDOI_PROTO_IPCOMP: - /* need to handle both 16bit/32bit SPI */ - memset(&spi, 0, sizeof(spi)); - if (d->spi_size == sizeof(spi.spi16[1])) { - memcpy(&spi.spi16[1], d + 1, - sizeof(spi.spi16[1])); - } else if (d->spi_size == sizeof(spi.spi32)) - memcpy(&spi.spi32, d + 1, sizeof(spi.spi32)); - else { - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete payload with strange spi " - "size %d(proto_id:%d)\n", - d->spi_size, d->proto_id); - continue; - } - purge_ipsec_spi(iph1->remote, d->proto_id, - &spi.spi32, num_spi); - break; - - default: - plog(LLV_ERROR, LOCATION, iph1->remote, - "deletion message received, " - "invalid proto_id: %d\n", - d->proto_id); - continue; - } - - plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); - } - - vfree(pbuf); - - return 0; -} - void isakmp_check_notify(gen, iph1) struct isakmp_gen *gen; /* points to Notify payload */ @@ -1515,16 +1797,15 @@ isakmp_check_notify(gen, iph1) switch (ntohs(notify->type)) { case ISAKMP_NTYPE_CONNECTED: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore CONNECTED notification.\n"); - break; case ISAKMP_NTYPE_RESPONDER_LIFETIME: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore RESPONDER-LIFETIME notification.\n"); - break; case ISAKMP_NTYPE_REPLAY_STATUS: + case ISAKMP_NTYPE_HEARTBEAT: +#ifdef ENABLE_HYBRID + case ISAKMP_NTYPE_UNITY_HEARTBEAT: +#endif plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore REPLAY-STATUS notification.\n"); + "ignore %s notification.\n", + s_isakmp_notify_msg(ntohs(notify->type))); break; case ISAKMP_NTYPE_INITIAL_CONTACT: plog(LLV_WARNING, LOCATION, iph1->remote, @@ -1536,20 +1817,61 @@ isakmp_check_notify(gen, iph1) "ignore LOAD-BALANCE notification, " "because it is only accepted after phase1.\n"); break; - case ISAKMP_NTYPE_HEARTBEAT: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore HEARTBEAT notification\n"); - break; default: isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); plog(LLV_ERROR, LOCATION, iph1->remote, - "received unknown notification type %u.\n", - ntohs(notify->type)); + "received unknown notification type %s.\n", + s_isakmp_notify_msg(ntohs(notify->type))); } return; } +void +isakmp_check_ph2_notify(gen, iph2) +struct isakmp_gen *gen; /* points to Notify payload */ +struct ph2handle *iph2; +{ + struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen; + + plog(LLV_DEBUG, LOCATION, iph2->dst, + "Phase2 Notify Message received\n"); + + switch (ntohs(notify->type)) { + case ISAKMP_NTYPE_RESPONDER_LIFETIME: + return((void)isakmp_ph2_responder_lifetime(iph2, + (struct isakmp_pl_resp_lifetime *)notify)); + break; + case ISAKMP_NTYPE_CONNECTED: + case ISAKMP_NTYPE_REPLAY_STATUS: + case ISAKMP_NTYPE_HEARTBEAT: +#ifdef ENABLE_HYBRID + case ISAKMP_NTYPE_UNITY_HEARTBEAT: +#endif + plog(LLV_WARNING, LOCATION, iph2->dst, + "ignore %s notification.\n", + s_isakmp_notify_msg(ntohs(notify->type))); + break; + case ISAKMP_NTYPE_INITIAL_CONTACT: + plog(LLV_WARNING, LOCATION, iph2->dst, + "ignore INITIAL-CONTACT notification, " + "because it is only accepted after phase1.\n"); + break; + case ISAKMP_NTYPE_LOAD_BALANCE: + plog(LLV_WARNING, LOCATION, iph2->dst, + "ignore LOAD-BALANCE notification, " + "because it is only accepted after phase1.\n"); + break; + default: + isakmp_info_send_n1(iph2->ph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); + plog(LLV_ERROR, LOCATION, iph2->dst, + "received unknown notification type %s.\n", + s_isakmp_notify_msg(ntohs(notify->type))); + } + + return; +} + #ifdef ENABLE_VPNCONTROL_PORT static int isakmp_info_recv_lb(iph1, n, encrypted) @@ -1586,6 +1908,17 @@ isakmp_info_recv_lb(iph1, n, encrypted) "received LOAD_BALANCE notification - redirect address=%x.\n", ntohl(n->address)); + if (((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr != ntohl(n->address)) { + plog(LLV_DEBUG, LOCATION, iph1->remote, + "deleting old phase1 because of LOAD_BALANCE notification - redirect address=%x.\n", + ntohl(n->address)); + + if (iph1->status == PHASE1ST_ESTABLISHED) { + isakmp_info_send_d1(iph1); + } + isakmp_ph1expire(iph1); + } + return 0; } #endif @@ -1610,6 +1943,10 @@ isakmp_info_recv_r_u (iph1, ru, msgid) tlen = sizeof(*ru_ack); payload = vmalloc(tlen); if (payload == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("R-U-THERE? ACK"), + CONSTSTR("Failed to transmit DPD response")); plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer to send.\n"); return errno; @@ -1630,6 +1967,17 @@ isakmp_info_recv_r_u (iph1, ru, msgid) error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, ISAKMP_FLAG_E); vfree(payload); + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("R-U-THERE? ACK"), + CONSTSTR("Failed to transmit DPD ack")); + } else { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + CONSTSTR("R-U-THERE? ACK"), + CONSTSTR(NULL)); + } plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n"); @@ -1650,10 +1998,10 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid) /* XXX Maintain window of acceptable sequence numbers ? * => ru->data <= iph2->dpd_seq && * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */ - if (ntohl(ru->data) != iph1->dpd_seq-1) { + if (ntohl(ru->data) != iph1->dpd_seq) { plog(LLV_ERROR, LOCATION, iph1->remote, "Wrong DPD sequence number (%d, %d expected).\n", - ntohl(ru->data), iph1->dpd_seq-1); + ntohl(ru->data), iph1->dpd_seq); return 0; } @@ -1666,14 +2014,26 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid) iph1->dpd_fails = 0; + iph1->dpd_seq++; + /* Useless ??? */ iph1->dpd_lastack = time(NULL); - if (iph1->dpd_r_u != NULL) - SCHED_KILL(iph1->dpd_r_u); + SCHED_KILL(iph1->dpd_r_u); isakmp_sched_r_u(iph1, 0); + if (iph1->side == INITIATOR) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RESP, + CONSTSTR("Initiator DPD Response"), + CONSTSTR(NULL)); + } else { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RESP, + CONSTSTR("Responder DPD Response"), + CONSTSTR(NULL)); + } plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n"); return 0; @@ -1683,7 +2043,7 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid) /* * send Delete payload (for ISAKMP SA) in Informational exchange. */ -static void +void isakmp_info_send_r_u(arg) void *arg; { @@ -1695,10 +2055,27 @@ isakmp_info_send_r_u(arg) int tlen; int error = 0; - plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n"); + if (iph1->status != PHASE1ST_ESTABLISHED) { + plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD r-u send aborted, invalid phase1 status %d....\n", + iph1->status); + return; + } if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) { + u_int32_t address; + + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT, + CONSTSTR("DPD maximum retransmits"), + CONSTSTR("maxed-out of DPD requests without receiving an ack")); + EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL); + if (iph1->remote->sa_family == AF_INET) + address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; + else + address = 0; + (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PEER_DEAD, FROM_LOCAL, address, 0, NULL); + purge_remote(iph1); plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD: remote seems to be dead\n"); @@ -1709,26 +2086,13 @@ isakmp_info_send_r_u(arg) return; } - /* TODO: check recent activity to avoid useless sends... */ - - /* XXX: why do we have a NULL LIST_FIRST even when a Phase2 exists ??? */ -#if 0 - if (LIST_FIRST(&iph1->ph2tree) == NULL){ - /* XXX: No Ph2 => no need to test ph1 ? - */ - /* Reschedule the r_u_there.... - XXX: reschedule when a new ph2 ? - */ - isakmp_sched_r_u(iph1, 0); - plog(LLV_DEBUG, LOCATION, iph1->remote, - "no phase2 handler, rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_interval); - return 0; - } -#endif - tlen = sizeof(*ru); payload = vmalloc(tlen); if (payload == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("R-U-THERE?"), + CONSTSTR("Failed to transmit DPD request")); plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer for payload.\n"); return; @@ -1754,16 +2118,35 @@ isakmp_info_send_r_u(arg) error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); vfree(payload); + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, + CONSTSTR("R-U-THERE?"), + CONSTSTR("Failed to transmit DPD request")); + } else { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, + CONSTSTR("R-U-THERE?"), + CONSTSTR(NULL)); + } + if (iph1->side == INITIATOR) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ, + CONSTSTR("Initiator DPD Request"), + CONSTSTR(NULL)); + } else { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ, + CONSTSTR("Responder DPD Request"), + CONSTSTR(NULL)); + } plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD R-U-There sent (%d)\n", error); /* will be decreased if ACK received... */ iph1->dpd_fails++; - /* XXX should be increased only when ACKed ? */ - iph1->dpd_seq++; - /* Reschedule the r_u_there with a short delay, * will be deleted/rescheduled if ACK received before */ isakmp_sched_r_u(iph1, 1); @@ -1772,6 +2155,97 @@ isakmp_info_send_r_u(arg) "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry); } +/* + * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange. + */ +static void +isakmp_info_monitor_r_u_algo_inbound_detect (struct ph1handle *iph1) +{ + if (iph1->status != PHASE1ST_ESTABLISHED) { + plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) aborted, invalid phase1 status %d....\n", + iph1->status); + return; + } + + plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) ....\n"); + + // check phase1 for ike packets received from peer + if (iph1->peer_sent_ike) { + // yes, reshedule check + iph1->peer_sent_ike = 0; + + /* ike packets received from peer... reschedule dpd */ + isakmp_sched_r_u(iph1, 0); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "ike packets received from peer... reschedule monitor.\n"); + + return; + } + + // after ike packets, next we check if any data was received + if (!iph1->parent_session->peer_sent_data_sc_dpd) { + isakmp_info_send_r_u(iph1); + } else { + isakmp_sched_r_u(iph1, 0); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "rescheduling DPD monitoring (for ALGORITHM_INBOUND_DETECT).\n"); + } + iph1->parent_session->peer_sent_data_sc_dpd = 0; +} + +/* + * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange. + */ +static void +isakmp_info_monitor_r_u_algo_blackhole_detect (struct ph1handle *iph1) +{ + if (iph1->status != PHASE1ST_ESTABLISHED) { + plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) aborted, invalid phase1 status %d....\n", + iph1->status); + return; + } + + plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) ....\n"); + + // check if data was sent but none was received + if (iph1->parent_session->i_sent_data_sc_dpd && + !iph1->parent_session->peer_sent_data_sc_dpd) { + isakmp_info_send_r_u(iph1); + } else { + isakmp_sched_r_u(iph1, 0); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "rescheduling DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) i = %d, peer %d.\n", + iph1->parent_session->i_sent_data_sc_dpd, + iph1->parent_session->peer_sent_data_sc_dpd); + } + iph1->parent_session->i_sent_data_sc_dpd = 0; + iph1->parent_session->peer_sent_data_sc_dpd = 0; +} + +/* + * monitor DPD Informational exchange. + */ +static void +isakmp_info_monitor_r_u(arg) +void *arg; +{ + struct ph1handle *iph1 = arg; + + if (iph1 && iph1->rmconf) { + if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT) { + isakmp_info_monitor_r_u_algo_inbound_detect(iph1); + } else if (iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) { + isakmp_info_monitor_r_u_algo_blackhole_detect(iph1); + } else { + plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring aborted, invalid algorithm %d....\n", + iph1->rmconf->dpd_algo); + } + } +} + /* Schedule a new R-U-THERE */ int isakmp_sched_r_u(iph1, retry) @@ -1787,13 +2261,49 @@ isakmp_sched_r_u(iph1, retry) iph1->rmconf->dpd_interval == 0) return 0; - if(retry) + if(retry) { iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry, - isakmp_info_send_r_u, iph1); - else - sched_new(iph1->rmconf->dpd_interval, - isakmp_info_send_r_u, iph1); + isakmp_info_send_r_u, iph1); + } else { + if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT || + iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) { + iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval, + isakmp_info_monitor_r_u, iph1); + } else { + iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval, + isakmp_info_send_r_u, iph1); + } + } return 0; } + +/* + * punts dpd for later because of some activity that: + * 1) implicitly does dpd (e.g. phase2 exchanges), or + * 2) indicates liveness (e.g. received ike packets). + */ +void +isakmp_reschedule_info_monitor_if_pending (struct ph1handle *iph1, + char *reason) +{ + if (!iph1 || + iph1->status != PHASE1ST_ESTABLISHED || + !iph1->dpd_support || + !iph1->rmconf->dpd_interval || + iph1->rmconf->dpd_algo == DPD_ALGO_DEFAULT) { + return; + } + + if (!iph1->peer_sent_ike) { + SCHED_KILL(iph1->dpd_r_u); + + isakmp_sched_r_u(iph1, 0); + + plog(LLV_DEBUG, LOCATION, iph1->remote, + "%s... rescheduling send_r_u.\n", + reason); + } + iph1->peer_sent_ike++; +} #endif diff --git a/ipsec-tools/racoon/isakmp_inf.h b/ipsec-tools/racoon/isakmp_inf.h index 4f22ece..50cd2f9 100644 --- a/ipsec-tools/racoon/isakmp_inf.h +++ b/ipsec-tools/racoon/isakmp_inf.h @@ -1,4 +1,6 @@ -/* $Id: isakmp_inf.h,v 1.4 2004/11/16 15:44:46 ludvigm Exp $ */ +/* $NetBSD: isakmp_inf.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: isakmp_inf.h,v 1.6 2005/05/07 14:15:59 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -32,6 +34,8 @@ #ifndef _ISAKMP_INF_H #define _ISAKMP_INF_H +#include "proposal.h" + struct saproto; extern int isakmp_info_recv __P((struct ph1handle *, vchar_t *)); extern int isakmp_info_send_d1 __P((struct ph1handle *)); @@ -48,8 +52,15 @@ extern vchar_t * isakmp_add_pl_n __P((vchar_t *, u_int8_t **, int, extern void isakmp_check_notify __P((struct isakmp_gen *, struct ph1handle *)); +extern void isakmp_check_ph2_notify __P((struct isakmp_gen *, struct ph2handle *)); + #ifdef ENABLE_DPD extern int isakmp_sched_r_u __P((struct ph1handle *, int)); +extern void isakmp_reschedule_info_monitor_if_pending __P((struct ph1handle *, char *)); +extern void isakmp_info_send_r_u __P((void *)); #endif +extern void purge_ipsec_spi __P((struct sockaddr *, int, u_int32_t *, size_t)); +extern int tunnel_mode_prop __P((struct saprop *)); + #endif /* _ISAKMP_INF_H */ diff --git a/ipsec-tools/racoon/isakmp_newg.c b/ipsec-tools/racoon/isakmp_newg.c index 0db0107..211e632 100644 --- a/ipsec-tools/racoon/isakmp_newg.c +++ b/ipsec-tools/racoon/isakmp_newg.c @@ -1,3 +1,5 @@ +/* $NetBSD: isakmp_newg.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + /* $KAME: isakmp_newg.c,v 1.10 2002/09/27 05:55:52 itojun Exp $ */ /* diff --git a/ipsec-tools/racoon/isakmp_quick.c b/ipsec-tools/racoon/isakmp_quick.c index a872904..005ca95 100644 --- a/ipsec-tools/racoon/isakmp_quick.c +++ b/ipsec-tools/racoon/isakmp_quick.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_quick.c,v 1.13.2.7 2005/07/20 08:02:05 vanhu Exp $ */ +/* $NetBSD: isakmp_quick.c,v 1.11.4.1 2007/08/01 11:52:21 vanhu Exp $ */ + +/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -51,6 +53,9 @@ # include # endif #endif +#ifdef ENABLE_HYBRID +#include +#endif #ifndef HAVE_NETINET6_IPSEC #include @@ -67,12 +72,14 @@ #include "localconf.h" #include "remoteconf.h" +#include "handler.h" +#include "policy.h" +#include "proposal.h" #include "isakmp_var.h" #include "isakmp.h" #include "isakmp_inf.h" #include "isakmp_quick.h" #include "oakley.h" -#include "handler.h" #include "ipsec_doi.h" #include "crypto_openssl.h" #include "pfkey.h" @@ -84,6 +91,8 @@ #include "admin.h" #include "strnames.h" #include "nattraversal.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" /* quick mode */ static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *)); @@ -111,6 +120,8 @@ quick_i1prep(iph2, msg) } iph2->msgid = isakmp_newmsgid2(iph2->ph1); + if (iph2->ivm != NULL) + oakley_delivm(iph2->ivm); iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid); if (iph2->ivm == NULL) return 0; @@ -124,8 +135,11 @@ quick_i1prep(iph2, msg) } /* send getspi message */ - if (pk_sendgetspi(iph2) < 0) + if (pk_sendgetspi(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send getspi message"); goto end; + } plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); @@ -140,7 +154,7 @@ end: /* * send to responder - * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] + * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_i1send(iph2, msg) @@ -149,8 +163,10 @@ quick_i1send(iph2, msg) { vchar_t *body = NULL; vchar_t *hash = NULL; +#ifdef ENABLE_NATT vchar_t *natoa_i = NULL; vchar_t *natoa_r = NULL; +#endif /* ENABLE_NATT */ int natoa_type = 0; struct isakmp_gen *gen; char *p; @@ -173,13 +189,19 @@ quick_i1send(iph2, msg) } /* create SA payload for my proposal */ - if (ipsecdoi_setph2proposal(iph2) < 0) + if (ipsecdoi_setph2proposal(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set proposal"); goto end; + } /* generate NONCE value */ iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); - if (iph2->nonce == NULL) + if (iph2->nonce == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NONCE"); goto end; + } /* * DH value calculation is kicked out into cfparse.y. @@ -197,6 +219,8 @@ quick_i1send(iph2, msg) } if (oakley_dh_generate(iph2->pfsgrp, &iph2->dhpub, &iph2->dhpriv) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate DH"); goto end; } } @@ -207,9 +231,9 @@ quick_i1send(iph2, msg) "failed to get ID.\n"); goto end; } - plog(LLV_DEBUG, LOCATION, NULL, "IDci:"); + plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n"); plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); - plog(LLV_DEBUG, LOCATION, NULL, "IDcr:"); + plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n"); plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); /* @@ -239,22 +263,28 @@ quick_i1send(iph2, msg) if (idcr) tlen += sizeof(*gen) + iph2->id_p->l; -#ifdef NOT_NOW #ifdef ENABLE_NATT - /* - * create natoa payloads if needed but only - * if transport mode proposals are present + /* + * RFC3947 5.2. if we propose UDP-Encapsulated-Transport + * we should send NAT-OA */ - if (ipsecdoi_tunnelmode(iph2) != 1) { + if (ipsecdoi_any_transportmode(iph2->proposal) + && (iph2->ph1->natt_flags & NAT_DETECTED)) { natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r); - if (natoa_type == -1) + if (natoa_type == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NAT-OA payload.\n"); goto end; - else if (natoa_type != 0) { + } else if (natoa_type != 0) { tlen += sizeof(*gen) + natoa_i->l; tlen += sizeof(*gen) + natoa_r->l; + + plog(LLV_DEBUG, LOCATION, NULL, "initiator send NAT-OAi:\n"); + plogdump(LLV_DEBUG, natoa_i->v, natoa_i->l); + plog(LLV_DEBUG, LOCATION, NULL, "initiator send NAT-OAr:\n"); + plogdump(LLV_DEBUG, natoa_r->v, natoa_r->l); } } -#endif #endif body = vmalloc(tlen); @@ -275,34 +305,21 @@ quick_i1send(iph2, msg) else if (idci || idcr) np = ISAKMP_NPTYPE_ID; else -#ifdef NOT_NOW np = (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE); -#else - np = ISAKMP_NPTYPE_NONE; -#endif p = set_isakmp_payload(p, iph2->nonce, np); /* add KE payload if need. */ -#ifdef NOT_NOW np = (idci || idcr) ? ISAKMP_NPTYPE_ID : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE); -#else - np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; -#endif if (pfsgroup) p = set_isakmp_payload(p, iph2->dhpub, np); /* IDci */ -#ifdef NOT_NOW np = (idcr) ? ISAKMP_NPTYPE_ID : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE); -#else - np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; -#endif if (idci) p = set_isakmp_payload(p, iph2->id, np); /* IDcr */ if (idcr) -#ifdef NOT_NOW p = set_isakmp_payload(p, iph2->id_p, natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE); /* natoa */ @@ -310,48 +327,65 @@ quick_i1send(iph2, msg) p = set_isakmp_payload(p, natoa_i, natoa_type); p = set_isakmp_payload(p, natoa_r, ISAKMP_NPTYPE_NONE); } -#else - p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE); -#endif /* generate HASH(1) */ hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body); - if (hash == NULL) + if (hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; + } /* send isakmp payload */ iph2->sendbuf = quick_ir1mx(iph2, body, hash); - if (iph2->sendbuf == NULL) + if (iph2->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get send buffer"); goto end; + } /* send the packet, add to the schedule to resend */ iph2->retry_counter = iph2->ph1->rmconf->retry_counter; - if (isakmp_ph2resend(iph2) == -1) + if (isakmp_ph2resend(iph2) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* change status of isakmp status entry */ iph2->status = PHASE2ST_MSG1SENT; error = 0; + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Quick-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Quick-Mode Message 1"), + CONSTSTR("Failed to transmit Quick-Mode Message 1")); + } if (body != NULL) vfree(body); if (hash != NULL) vfree(hash); -#ifdef NOT_NOW +#ifdef ENABLE_NATT if (natoa_i) vfree(natoa_i); if (natoa_r) vfree(natoa_r); -#endif +#endif /* ENABLE_NATT */ return error; } /* * receive from responder - * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] + * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_i2recv(iph2, msg0) @@ -368,6 +402,8 @@ quick_i2recv(iph2, msg0) char *p; int tlen; int error = ISAKMP_INTERNAL_ERROR; + struct sockaddr *natoa_i = NULL; + struct sockaddr *natoa_r = NULL; /* validity check */ if (iph2->status != PHASE2ST_MSG1SENT) { @@ -383,8 +419,11 @@ quick_i2recv(iph2, msg0) goto end; } msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt"); goto end; + } /* create buffer for validating HASH(2) */ /* @@ -394,8 +433,11 @@ quick_i2recv(iph2, msg0) * 3. two IDs must be considered as IDci, then IDcr */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } pa = (struct isakmp_parse_t *)pbuf->v; /* HASH payload is fixed postion */ @@ -454,18 +496,27 @@ quick_i2recv(iph2, msg0) "isn't supported.\n"); break; } - if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SA payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_ID: @@ -523,14 +574,38 @@ quick_i2recv(iph2, msg0) break; case ISAKMP_NPTYPE_N: - isakmp_check_notify(pa->ptr, iph2->ph1); + isakmp_check_ph2_notify(pa->ptr, iph2); break; #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATOA_DRAFT: case ISAKMP_NPTYPE_NATOA_BADDRAFT: case ISAKMP_NPTYPE_NATOA_RFC: - /* Ignore original source/destination messages */ + { + vchar_t *vp = NULL; + struct sockaddr *daddr; + + isakmp_p2ph(&vp, pa->ptr); + + if (vp) { + daddr = process_natoa_payload(vp); + if (daddr) { + if (natoa_i == NULL) { + natoa_i = daddr; + plog(LLV_DEBUG, LOCATION, NULL, "initiaor rcvd NAT-OA i: %s\n", + saddr2str(natoa_i)); + } else if (natoa_r == NULL) { + natoa_r = daddr; + plog(LLV_DEBUG, LOCATION, NULL, "initiator rcvd NAT-OA r: %s\n", + saddr2str(natoa_r)); + } else { + racoon_free(daddr); + } + } + vfree(vp); + } + + } break; #endif @@ -576,8 +651,11 @@ quick_i2recv(iph2, msg0) plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); - if (my_hash == NULL) + if (my_hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; + } result = memcmp(my_hash->v, r_hash, my_hash->l); vfree(my_hash); @@ -592,6 +670,8 @@ quick_i2recv(iph2, msg0) /* validity check SA payload sent from responder */ if (ipsecdoi_checkph2proposal(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to validate SA proposal"); error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; goto end; } @@ -601,7 +681,18 @@ quick_i2recv(iph2, msg0) error = 0; + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Quick-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Quick-Mode Message 2"), + CONSTSTR("Failed to process Quick-Mode Message 2 ")); + } if (hbuf) vfree(hbuf); if (pbuf) @@ -609,6 +700,15 @@ end: if (msg) vfree(msg); +#ifdef ENABLE_NATT + if (natoa_i) { + racoon_free(natoa_i); + } + if (natoa_r) { + racoon_free(natoa_r); + } +#endif + if (error) { VPTRINIT(iph2->sa_ret); VPTRINIT(iph2->nonce_p); @@ -635,6 +735,7 @@ quick_i2send(iph2, msg0) char *p = NULL; int tlen; int error = ISAKMP_INTERNAL_ERROR; + int packet_error = -1; /* validity check */ if (iph2->status != PHASE2ST_STATUS6) { @@ -661,8 +762,11 @@ quick_i2send(iph2, msg0) hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); vfree(tmp); - if (hash == NULL) + if (hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; + } } /* create buffer for isakmp payload */ @@ -677,8 +781,11 @@ quick_i2send(iph2, msg0) /* create isakmp header */ p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); - if (p == NULL) + if (p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to create ISAKMP header"); goto end; + } /* add HASH(3) payload */ p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE); @@ -689,32 +796,51 @@ quick_i2send(iph2, msg0) /* encoding */ iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); - if (iph2->sendbuf == NULL) + if (iph2->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to encrypt packet"); goto end; + } /* if there is commit bit, need resending */ if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { /* send the packet, add to the schedule to resend */ iph2->retry_counter = iph2->ph1->rmconf->retry_counter; - if (isakmp_ph2resend(iph2) == -1) + if (isakmp_ph2resend(iph2) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet, commit-bit"); goto end; + } } else { /* send the packet */ - if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } } /* the sending message is added to the received-list. */ if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, - iph2->sendbuf, msg0) == -1) { + iph2->sendbuf, msg0, + PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; } + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Quick-Mode message 3"), + CONSTSTR(NULL)); + packet_error = 0; + /* compute both of KEYMATs */ - if (oakley_compute_keymat(iph2, INITIATOR) < 0) + if (oakley_compute_keymat(iph2, INITIATOR) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute KEYMAT"); goto end; + } iph2->status = PHASE2ST_ADDSA; @@ -749,6 +875,12 @@ quick_i2send(iph2, msg0) error = 0; end: + if (packet_error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Quick-Mode Message 3"), + CONSTSTR("Failed to transmit Quick-Mode Message 3")); + } if (buf != NULL) vfree(buf); if (msg != NULL) @@ -774,6 +906,7 @@ quick_i3recv(iph2, msg0) struct isakmp_pl_hash *hash = NULL; vchar_t *notify = NULL; int error = ISAKMP_INTERNAL_ERROR; + int packet_error = -1; /* validity check */ if (iph2->status != PHASE2ST_COMMIT) { @@ -789,13 +922,19 @@ quick_i3recv(iph2, msg0) goto end; } msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt packet"); goto end; + } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; @@ -806,7 +945,12 @@ quick_i3recv(iph2, msg0) hash = (struct isakmp_pl_hash *)pa->ptr; break; case ISAKMP_NPTYPE_N: - isakmp_check_notify(pa->ptr, iph2->ph1); + if (notify != NULL) { + plog(LLV_WARNING, LOCATION, NULL, + "Ignoring multiple notifications\n"); + break; + } + isakmp_check_ph2_notify(pa->ptr, iph2); notify = vmalloc(pa->len); if (notify == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -846,8 +990,11 @@ quick_i3recv(iph2, msg0) my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); vfree(tmp); - if (my_hash == NULL) + if (my_hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; + } result = memcmp(my_hash->v, r_hash, my_hash->l); vfree(my_hash); @@ -860,6 +1007,12 @@ quick_i3recv(iph2, msg0) } } + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Quick-Mode message 4"), + CONSTSTR(NULL)); + packet_error = 0; + iph2->status = PHASE2ST_ADDSA; iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ @@ -887,6 +1040,12 @@ quick_i3recv(iph2, msg0) error = 0; end: + if (packet_error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Quick-Mode Message 4"), + CONSTSTR("Failed to process Quick-Mode Message 4")); + } if (msg != NULL) vfree(msg); if (pbuf != NULL) @@ -899,7 +1058,7 @@ end: /* * receive from initiator - * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] + * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_r1recv(iph2, msg0) @@ -916,6 +1075,8 @@ quick_r1recv(iph2, msg0) int tlen; int f_id_order; /* for ID payload detection */ int error = ISAKMP_INTERNAL_ERROR; + struct sockaddr *natoa_i = NULL; + struct sockaddr *natoa_r = NULL; /* validity check */ if (iph2->status != PHASE2ST_START) { @@ -933,8 +1094,11 @@ quick_r1recv(iph2, msg0) } /* decrypt packet */ msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt packet"); goto end; + } /* create buffer for using to validate HASH(1) */ /* @@ -944,8 +1108,11 @@ quick_r1recv(iph2, msg0) * 3. two IDs must be considered as IDci, then IDcr */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } pa = (struct isakmp_parse_t *)pbuf->v; /* HASH payload is fixed postion */ @@ -1018,18 +1185,27 @@ quick_r1recv(iph2, msg0) "Multi SAs isn't supported.\n"); goto end; } - if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process SA payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_ID: @@ -1037,8 +1213,11 @@ quick_r1recv(iph2, msg0) /* for IDci */ f_id_order++; - if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process IDci2 payload"); goto end; + } } else if (iph2->id == NULL) { /* for IDcr */ @@ -1050,8 +1229,11 @@ quick_r1recv(iph2, msg0) /* XXX we allowed in this case. */ } - if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) + if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to process IDcr2 payload"); goto end; + } } else { plog(LLV_ERROR, LOCATION, NULL, "received too many ID payloads.\n"); @@ -1062,14 +1244,38 @@ quick_r1recv(iph2, msg0) break; case ISAKMP_NPTYPE_N: - isakmp_check_notify(pa->ptr, iph2->ph1); + isakmp_check_ph2_notify(pa->ptr, iph2); break; #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATOA_DRAFT: case ISAKMP_NPTYPE_NATOA_BADDRAFT: case ISAKMP_NPTYPE_NATOA_RFC: - /* Ignore original source/destination messages */ + { + vchar_t *vp = NULL; + struct sockaddr *daddr; + + isakmp_p2ph(&vp, pa->ptr); + + if (vp) { + daddr = process_natoa_payload(vp); + if (daddr) { + if (natoa_i == NULL) { + natoa_i = daddr; + plog(LLV_DEBUG, LOCATION, NULL, "responder rcvd NAT-OA i: %s\n", + saddr2str(natoa_i)); + } else if (natoa_r == NULL) { + natoa_r = daddr; + plog(LLV_DEBUG, LOCATION, NULL, "responder rcvd NAT-OA r: %s\n", + saddr2str(natoa_r)); + } else { + racoon_free(daddr); + } + } + vfree(vp); + } + + } break; #endif @@ -1120,8 +1326,11 @@ quick_r1recv(iph2, msg0) plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); - if (my_hash == NULL) + if (my_hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; + } result = memcmp(my_hash->v, r_hash, my_hash->l); vfree(my_hash); @@ -1142,10 +1351,10 @@ quick_r1recv(iph2, msg0) goto end; } - /* check the existence of ID payload and create responder's proposal */ - error = get_proposal_r(iph2, 0); - if (error != -2 && error != 0 && (iph2->ph1->natt_flags & NAT_DETECTED_ME) && lcconf->ext_nat_id != NULL) - error = get_proposal_r(iph2, 1); + /* check the existence of ID payload and create responder's proposal */ + error = get_proposal_r(iph2, 0); + if (error != -2 && error != 0 && (iph2->ph1->natt_flags & NAT_DETECTED_ME) && (lcconf->ext_nat_id != NULL || ike_session_is_client_ph2_rekey(iph2))) + error = get_proposal_r(iph2, 1); switch (error) { case -2: @@ -1160,6 +1369,8 @@ quick_r1recv(iph2, msg0) case 0: /* select single proposal or reject it. */ if (ipsecdoi_selectph2proposal(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to select proposal.\n"); error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; goto end; } @@ -1184,6 +1395,8 @@ quick_r1recv(iph2, msg0) goto end; } + ike_session_update_mode(iph2); /* update the mode, now that we have a proposal */ + /* * save the packet from the initiator in order to resend the * responder's first packet against this packet. @@ -1195,7 +1408,18 @@ quick_r1recv(iph2, msg0) error = 0; + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Quick-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Quick-Mode Message 1"), + CONSTSTR("Failed to process Quick-Mode Message 1")); + } if (hbuf) vfree(hbuf); if (msg) @@ -1203,6 +1427,15 @@ end: if (pbuf) vfree(pbuf); +#ifdef ENABLE_NATT + if (natoa_i) { + racoon_free(natoa_i); + } + if (natoa_r) { + racoon_free(natoa_r); + } +#endif + if (error) { VPTRINIT(iph2->sa); VPTRINIT(iph2->nonce_p); @@ -1234,8 +1467,11 @@ quick_r1prep(iph2, msg) iph2->status = PHASE2ST_GETSPISENT; /* send getspi message */ - if (pk_sendgetspi(iph2) < 0) + if (pk_sendgetspi(iph2) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send getspi"); goto end; + } plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); @@ -1250,7 +1486,7 @@ end: /* * send to initiator - * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] + * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_r2send(iph2, msg) @@ -1262,7 +1498,6 @@ quick_r2send(iph2, msg) vchar_t *natoa_i = NULL; vchar_t *natoa_r = NULL; int natoa_type = 0; - int encmode; struct isakmp_gen *gen; char *p; int tlen; @@ -1290,8 +1525,11 @@ quick_r2send(iph2, msg) /* generate NONCE value */ iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); - if (iph2->nonce == NULL) + if (iph2->nonce == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate NONCE"); goto end; + } /* generate KE value if need */ pfsgroup = iph2->approval->pfs_group; @@ -1305,6 +1543,8 @@ quick_r2send(iph2, msg) /* generate DH public value */ if (oakley_dh_generate(iph2->pfsgrp, &iph2->dhpub, &iph2->dhpriv) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to generate DH public"); goto end; } } @@ -1318,24 +1558,30 @@ quick_r2send(iph2, msg) tlen += (sizeof(*gen) + iph2->id_p->l + sizeof(*gen) + iph2->id->l); -#ifdef NOT_NOW #ifdef ENABLE_NATT - /* create natoa payloads if needed */ - encmode = iph2->approval->head->encmode; - if (encmode == IPSECDOI_ATTR_ENC_MODE_TRNS || - encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC || - encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT) { - + /* + * RFC3947 5.2. if we chose UDP-Encapsulated-Transport + * we should send NAT-OA + */ + if (ipsecdoi_any_transportmode(iph2->approval) + && (iph2->ph1->natt_flags & NAT_DETECTED)) { natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r); - if (natoa_type == -1) + if (natoa_type == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to create NATOA payloads"); goto end; + } else if (natoa_type != 0) { tlen += sizeof(*gen) + natoa_i->l; tlen += sizeof(*gen) + natoa_r->l; + + plog(LLV_DEBUG, LOCATION, NULL, "responder send NAT-OAi:\n"); + plogdump(LLV_DEBUG, natoa_i->v, natoa_i->l); + plog(LLV_DEBUG, LOCATION, NULL, "responder send NAT-OAr:\n"); + plogdump(LLV_DEBUG, natoa_r->v, natoa_r->l); } } #endif -#endif body = vmalloc(tlen); @@ -1356,23 +1602,13 @@ quick_r2send(iph2, msg) ? ISAKMP_NPTYPE_KE : (iph2->id_p != NULL ? ISAKMP_NPTYPE_ID -#ifdef NOT_NOW : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE))); -#else - : ISAKMP_NPTYPE_ID)); -#endif /* add KE payload if need. */ if (iph2->dhpub_p != NULL && pfsgroup != 0) { np_p = &((struct isakmp_gen *)p)->np; /* XXX */ p = set_isakmp_payload(p, iph2->dhpub, - (iph2->id_p == NULL) -#ifdef NOT_NOW - ? (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE) -#else - ? ISAKMP_NPTYPE_NONE -#endif - : ISAKMP_NPTYPE_ID); + (iph2->id_p == NULL) ? (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE) : ISAKMP_NPTYPE_ID); } /* add ID payloads received. */ @@ -1381,11 +1617,7 @@ quick_r2send(iph2, msg) p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID); /* IDcr */ np_p = &((struct isakmp_gen *)p)->np; /* XXX */ -#ifdef NOT_NOW p = set_isakmp_payload(p, iph2->id, (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE)); -#else - p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE); -#endif } /* add a RESPONDER-LIFETIME notify payload if needed */ @@ -1398,23 +1630,35 @@ quick_r2send(iph2, msg) u_int32_t v = htonl((u_int32_t)pp->lifetime); data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, IPSECDOI_ATTR_SA_LD_TYPE_SEC); - if (!data) + if (!data) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to add RESPONDER-LIFETIME notify (type) payload"); goto end; + } data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, (caddr_t)&v, sizeof(v)); - if (!data) + if (!data) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to add RESPONDER-LIFETIME notify (value) payload"); goto end; + } } if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) { u_int32_t v = htonl((u_int32_t)pp->lifebyte); data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, IPSECDOI_ATTR_SA_LD_TYPE_KB); - if (!data) + if (!data) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to add RESPONDER-LIFETIME notify (type) payload"); goto end; + } data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, (caddr_t)&v, sizeof(v)); - if (!data) + if (!data) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to add RESPONDER-LIFETIME notify (value) payload"); goto end; + } } /* @@ -1426,6 +1670,8 @@ quick_r2send(iph2, msg) body = isakmp_add_pl_n(body, &np_p, ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data); if (!body) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid RESPONDER-LIFETIME payload"); vfree(data); return error; /* XXX */ } @@ -1434,13 +1680,11 @@ quick_r2send(iph2, msg) } } -#ifdef NOT_NOW /* natoa */ if (natoa_type) { p = set_isakmp_payload(p, natoa_i, natoa_type); p = set_isakmp_payload(p, natoa_r, ISAKMP_NPTYPE_NONE); } -#endif /* generate HASH(2) */ { @@ -1458,22 +1702,32 @@ quick_r2send(iph2, msg) hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp); vfree(tmp); - if (hash == NULL) + if (hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; } + } /* send isakmp payload */ iph2->sendbuf = quick_ir1mx(iph2, body, hash); - if (iph2->sendbuf == NULL) + if (iph2->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get send buffer"); goto end; + } /* send the packet, add to the schedule to resend */ iph2->retry_counter = iph2->ph1->rmconf->retry_counter; - if (isakmp_ph2resend(iph2) == -1) + if (isakmp_ph2resend(iph2) == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1) == -1) { + if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1, + PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -1484,17 +1738,26 @@ quick_r2send(iph2, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Quick-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Quick-Mode Message 2"), + CONSTSTR("Failed to transmit Quick-Mode Message 2")); + } if (body != NULL) vfree(body); if (hash != NULL) vfree(hash); -#ifdef NOT_NOW if (natoa_i) vfree(natoa_i); if (natoa_r) vfree(natoa_r); -#endif return error; } @@ -1528,13 +1791,19 @@ quick_r3recv(iph2, msg0) goto end; } msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to decrypt packet"); goto end; + } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to parse msg"); goto end; + } for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; @@ -1545,7 +1814,7 @@ quick_r3recv(iph2, msg0) hash = (struct isakmp_pl_hash *)pa->ptr; break; case ISAKMP_NPTYPE_N: - isakmp_check_notify(pa->ptr, iph2->ph1); + isakmp_check_ph2_notify(pa->ptr, iph2); break; default: /* don't send information, see ident_r1recv() */ @@ -1588,8 +1857,11 @@ quick_r3recv(iph2, msg0) my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); vfree(tmp); - if (my_hash == NULL) + if (my_hash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; + } result = memcmp(my_hash->v, r_hash, my_hash->l); vfree(my_hash); @@ -1610,7 +1882,18 @@ quick_r3recv(iph2, msg0) error = 0; + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Quick-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Quick-Mode Message 3"), + CONSTSTR("Failed to process Quick-Mode Message 3")); + } if (pbuf != NULL) vfree(pbuf); if (msg != NULL) @@ -1665,8 +1948,11 @@ quick_r3send(iph2, msg0) memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize); myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); - if (myhash == NULL) + if (myhash == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute HASH"); goto end; + } /* create buffer for isakmp payload */ tlen = sizeof(struct isakmp) @@ -1681,8 +1967,11 @@ quick_r3send(iph2, msg0) /* create isakmp header */ p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); - if (p == NULL) + if (p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ISAKMP header"); goto end; + } /* add HASH(4) payload */ p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N); @@ -1696,15 +1985,22 @@ quick_r3send(iph2, msg0) /* encoding */ iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); - if (iph2->sendbuf == NULL) + if (iph2->sendbuf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to encrypt packet"); goto end; + } /* send the packet */ - if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) + if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0) == -1) { + if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0, + PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) { plog(LLV_ERROR , LOCATION, NULL, "failed to add a response packet to the tree.\n"); goto end; @@ -1714,7 +2010,18 @@ quick_r3send(iph2, msg0) error = 0; + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Quick-Mode message 4"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Quick-Mode Message 4"), + CONSTSTR("Failed to transmit Quick-Mode Message 4")); + } if (buf != NULL) vfree(buf); if (myhash != NULL) @@ -1725,6 +2032,7 @@ end: return error; } + /* * set SA to kernel. */ @@ -1744,8 +2052,11 @@ quick_r3prep(iph2, msg0) } /* compute both of KEYMATs */ - if (oakley_compute_keymat(iph2, RESPONDER) < 0) + if (oakley_compute_keymat(iph2, RESPONDER) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to compute KEYMAT"); goto end; + } iph2->status = PHASE2ST_ADDSA; iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ @@ -1875,8 +2186,11 @@ quick_ir1mx(iph2, body, hash) /* set isakmp header */ p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); - if (p == NULL) + if (p == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to set ISAKMP header"); goto end; + } /* add HASH payload */ /* XXX is next type always SA ? */ @@ -1891,8 +2205,11 @@ quick_ir1mx(iph2, body, hash) /* encoding */ new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); - if (new == NULL) + if (new == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to encrypt packet"); goto end; + } vfree(buf); @@ -1920,8 +2237,10 @@ get_sainfo_r(iph2) vchar_t *idsrc = NULL, *iddst = NULL; int prefixlen; int error = ISAKMP_INTERNAL_ERROR; + int remoteid = 0; - if (iph2->id_p == NULL) { + if (iph2->id == NULL || + ((iph2->ph1->natt_flags & NAT_DETECTED_ME) && ike_session_is_client_ph2_rekey(iph2))) { switch (iph2->src->sa_family) { case AF_INET: prefixlen = sizeof(struct in_addr) << 3; @@ -1945,7 +2264,8 @@ get_sainfo_r(iph2) goto end; } - if (iph2->id == NULL) { + if (iph2->id_p == NULL || + ((iph2->ph1->natt_flags & NAT_DETECTED_PEER) && ike_session_is_client_ph2_rekey(iph2))) { switch (iph2->dst->sa_family) { case AF_INET: prefixlen = sizeof(struct in_addr) << 3; @@ -1978,9 +2298,27 @@ get_sainfo_r(iph2) "failed to get sainfo.\n"); goto end; } +#ifdef __APPLE__ + if (link_sainfo_to_ph2(iph2->sainfo) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to link sainfo\n"); + iph2->sainfo = NULL; + goto end; + } +#endif + +#ifdef ENABLE_HYBRID + /* xauth group inclusion check */ + if (iph2->sainfo->group != NULL) + if(group_check(iph2->ph1,&iph2->sainfo->group->v,1)) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to group check"); + goto end; + } +#endif plog(LLV_DEBUG, LOCATION, NULL, - "get sa info: %s\n", sainfo2str(iph2->sainfo)); + "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); error = 0; end: @@ -2011,6 +2349,7 @@ get_proposal_r(iph2, use_remote_addr) struct secpolicy *sp_in, *sp_out; int idi2type = 0; /* switch whether copy IDs into id[src,dst]. */ int error = ISAKMP_INTERNAL_ERROR; + int generated_policy_exit_early = 1; /* check the existence of ID payload */ if ((iph2->id_p != NULL && iph2->id == NULL) @@ -2137,7 +2476,17 @@ get_proposal_r(iph2, use_remote_addr) if (_XIDT(iph2->id_p) == idi2type && spidx.dst.ss_family == spidx.src.ss_family) { iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst); + if (iph2->src_id == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src); + if (iph2->dst_id == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } } } else { @@ -2192,38 +2541,45 @@ get_proposal_r(iph2, use_remote_addr) sp_in = getsp_r(&spidx); if (sp_in == NULL || sp_in->policy == IPSEC_POLICY_GENERATE) { if (iph2->ph1->rmconf->gen_policy) { - plog(LLV_INFO, LOCATION, NULL, - "no policy found, " - "try to generate the policy : %s\n", - spidx2str(&spidx)); + if (sp_in) + plog(LLV_INFO, LOCATION, NULL, + "Update the generated policy : %s\n", + spidx2str(&spidx)); + else + plog(LLV_INFO, LOCATION, NULL, + "no policy found, " + "try to generate the policy : %s\n", + spidx2str(&spidx)); iph2->spidx_gen = racoon_malloc(sizeof(spidx)); if (!iph2->spidx_gen) { - plog(LLV_ERROR, LOCATION, NULL, - "buffer allocation failed.\n"); + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); return ISAKMP_INTERNAL_ERROR; } memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); - return -2; /* special value */ - } - plog(LLV_ERROR, LOCATION, NULL, - "no policy found: %s\n", spidx2str(&spidx)); - return ISAKMP_INTERNAL_ERROR; - } - /* Refresh existing generated policies - */ - if (iph2->ph1->rmconf->gen_policy) { - plog(LLV_INFO, LOCATION, NULL, - "Update the generated policy : %s\n", - spidx2str(&spidx)); - iph2->spidx_gen = racoon_malloc(sizeof(spidx)); - if (!iph2->spidx_gen) { - plog(LLV_ERROR, LOCATION, NULL, - "buffer allocation failed.\n"); + generated_policy_exit_early = 1; /* special value */ + } else { + plog(LLV_ERROR, LOCATION, NULL, + "no policy found: %s\n", spidx2str(&spidx)); return ISAKMP_INTERNAL_ERROR; } - memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); + } else { + /* Refresh existing generated policies + */ + if (iph2->ph1->rmconf->gen_policy) { + plog(LLV_INFO, LOCATION, NULL, + "Update the generated policy : %s\n", + spidx2str(&spidx)); + iph2->spidx_gen = racoon_malloc(sizeof(spidx)); + if (!iph2->spidx_gen) { + plog(LLV_ERROR, LOCATION, NULL, + "buffer allocation failed.\n"); + return ISAKMP_INTERNAL_ERROR; + } + memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); + } } - + /* get outbound policy */ { struct sockaddr_storage addr; @@ -2242,12 +2598,21 @@ get_proposal_r(iph2, use_remote_addr) plog(LLV_WARNING, LOCATION, NULL, "no outbound policy found: %s\n", spidx2str(&spidx)); + } else { + + if (!iph2->spid) { + iph2->spid = sp_out->id; + } } } plog(LLV_DEBUG, LOCATION, NULL, "suitable SP found:%s\n", spidx2str(&spidx)); + if (generated_policy_exit_early) { + return -2; + } + /* * In the responder side, the inbound policy should be using IPsec. * outbound policy is not checked currently. diff --git a/ipsec-tools/racoon/isakmp_unity.c b/ipsec-tools/racoon/isakmp_unity.c index 21a1962..c7951ba 100644 --- a/ipsec-tools/racoon/isakmp_unity.c +++ b/ipsec-tools/racoon/isakmp_unity.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_unity.c,v 1.5.4.1 2005/05/10 09:45:46 manubsd Exp $ */ +/* $NetBSD: isakmp_unity.c,v 1.7 2006/10/09 06:17:20 manu Exp $ */ + +/* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -59,6 +61,7 @@ #include #endif #include +#include #include "var.h" #include "misc.h" @@ -76,6 +79,9 @@ #include "isakmp_cfg.h" #include "strnames.h" +static vchar_t *isakmp_cfg_split(struct ph1handle *, + struct isakmp_data *, struct unity_netentry*,int); + vchar_t * isakmp_unity_req(iph1, attr) struct ph1handle *iph1; @@ -98,13 +104,14 @@ isakmp_unity_req(iph1, attr) type &= ~ISAKMP_GEN_MASK; plog(LLV_DEBUG, LOCATION, NULL, - "Short attribute %d = %d\n", - type, ntohs(attr->lorv)); + "Short attribute %s = %d\n", + s_isakmp_cfg_type(type), ntohs(attr->lorv)); switch (type) { default: plog(LLV_DEBUG, LOCATION, NULL, - "Ignored short attribute %d\n", type); + "Ignored short attribute %s\n", + s_isakmp_cfg_type(type)); break; } @@ -117,7 +124,7 @@ isakmp_unity_req(iph1, attr) char buf[MAXMOTD + 1]; int fd; char *filename = &isakmp_cfg_config.motd[0]; - size_t len; + int len; if ((fd = open(filename, O_RDONLY, 0)) == -1) { plog(LLV_ERROR, LOCATION, NULL, @@ -154,14 +161,37 @@ isakmp_unity_req(iph1, attr) break; case UNITY_DEF_DOMAIN: - case UNITY_FW_TYPE: - case UNITY_SPLITDNS_NAME: + reply_attr = isakmp_cfg_string(iph1, + attr, isakmp_cfg_config.default_domain); + break; + case UNITY_SPLIT_INCLUDE: + if(isakmp_cfg_config.splitnet_type == UNITY_SPLIT_INCLUDE) + reply_attr = isakmp_cfg_split(iph1, attr, + isakmp_cfg_config.splitnet_list, + isakmp_cfg_config.splitnet_count); + else + return NULL; + break; + case UNITY_LOCAL_LAN: + if(isakmp_cfg_config.splitnet_type == UNITY_LOCAL_LAN) + reply_attr = isakmp_cfg_split(iph1, attr, + isakmp_cfg_config.splitnet_list, + isakmp_cfg_config.splitnet_count); + else + return NULL; + break; + case UNITY_SPLITDNS_NAME: + reply_attr = isakmp_cfg_varlen(iph1, attr, + isakmp_cfg_config.splitdns_list, + isakmp_cfg_config.splitdns_len); + break; + case UNITY_FW_TYPE: case UNITY_NATT_PORT: case UNITY_BACKUP_SERVERS: default: plog(LLV_DEBUG, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); return NULL; break; } @@ -169,4 +199,218 @@ isakmp_unity_req(iph1, attr) return reply_attr; } +void +isakmp_unity_reply(iph1, attr) + struct ph1handle *iph1; + struct isakmp_data *attr; +{ + int type = ntohs(attr->type); + int alen = ntohs(attr->lorv); + + type &= ~ISAKMP_GEN_MASK; + + struct unity_network *network = (struct unity_network *)(attr + 1); + int index = 0; + int count = 0; + + switch(type) { + case UNITY_SPLIT_INCLUDE: + { + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) == 0) { + if (alen) + count = alen / sizeof(struct unity_network); + + for(;index < count; index++) + splitnet_list_add( + &iph1->mode_cfg->split_include, + &network[index], + &iph1->mode_cfg->include_count); + + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_INCLUDE; + } + break; + } + case UNITY_LOCAL_LAN: + { + if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) == 0) { + if (alen) + count = alen / sizeof(struct unity_network); + + for(;index < count; index++) + splitnet_list_add( + &iph1->mode_cfg->split_local, + &network[index], + &iph1->mode_cfg->local_count); + + iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_LOCAL; + } + break; + } + case UNITY_PFS: + { + break; + } + case UNITY_SPLITDNS_NAME: + case UNITY_BANNER: + case UNITY_SAVE_PASSWD: + case UNITY_NATT_PORT: + case UNITY_FW_TYPE: + case UNITY_BACKUP_SERVERS: + case UNITY_DDNS_HOSTNAME: + default: + plog(LLV_WARNING, LOCATION, NULL, + "Ignored attribute %s\n", + s_isakmp_cfg_type(type)); + break; + } + return; +} + +static vchar_t * +isakmp_cfg_split(iph1, attr, netentry, count) + struct ph1handle *iph1; + struct isakmp_data *attr; + struct unity_netentry *netentry; + int count; +{ + vchar_t *buffer; + struct isakmp_data *new; + struct unity_network * network; + size_t len; + int index = 0; + + char tmp1[40]; + char tmp2[40]; + + len = sizeof(struct unity_network) * count; + if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); + return NULL; + } + + new = (struct isakmp_data *)buffer->v; + new->type = attr->type; + new->lorv = htons(len); + + network = (struct unity_network *)(new + 1); + for (; index < count; index++) { + + memcpy(&network[index], + &netentry->network, + sizeof(struct unity_network)); + + inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40); + inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40); + plog(LLV_DEBUG, LOCATION, NULL, "splitnet: %s/%s\n", tmp1, tmp2); + + netentry = netentry->next; + } + + return buffer; +} + +int splitnet_list_add(list, network, count) + struct unity_netentry ** list; + struct unity_network * network; + int *count; +{ + struct unity_netentry * newentry; + + /* + * allocate new netentry and copy + * new splitnet network data + */ + newentry = (struct unity_netentry *) + racoon_malloc(sizeof(struct unity_netentry)); + if (newentry == NULL) + return -1; + + memcpy(&newentry->network,network, + sizeof(struct unity_network)); + newentry->next = NULL; + + /* + * locate the last netentry in our + * splitnet list and add our entry + */ + if (*list == NULL) + *list = newentry; + else { + struct unity_netentry * tmpentry = *list; + while (tmpentry->next != NULL) + tmpentry = tmpentry->next; + tmpentry->next = newentry; + } + + (*count)++; + + return 0; +} +void splitnet_list_free(list, count) + struct unity_netentry * list; + int *count; +{ + struct unity_netentry * netentry = list; + struct unity_netentry * delentry; + + *count = 0; + + while (netentry != NULL) { + delentry = netentry; + netentry = netentry->next; + racoon_free(delentry); + } +} + +char * splitnet_list_2str(list) + struct unity_netentry * list; +{ + struct unity_netentry * netentry; + char tmp1[40]; + char tmp2[40]; + char * str; + int len; + int print_len; + int rc; + + /* determine string length */ + len = 0; + netentry = list; + while (netentry != NULL) { + + inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40); + inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40); + len += strlen(tmp1); + len += strlen(tmp2); + len += 2; + + netentry = netentry->next; + } + + /* allocate network list string */ + str = racoon_malloc(len); + if (str == NULL) + return NULL; + + /* create network list string */ + str[0] = 0; + print_len = 0; + netentry = list; + while (netentry != NULL && print_len < len) { + + inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40); + inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40); + + rc = snprintf(str+print_len, len-print_len, "%s/%s ", tmp1, tmp2); + if (rc < 0) { + // failure -> exit loop + break; + } + print_len += rc; + + netentry = netentry->next; + } + + return str; +} diff --git a/ipsec-tools/racoon/isakmp_unity.h b/ipsec-tools/racoon/isakmp_unity.h index 4f09af1..b52f02c 100644 --- a/ipsec-tools/racoon/isakmp_unity.h +++ b/ipsec-tools/racoon/isakmp_unity.h @@ -1,3 +1,5 @@ +/* $NetBSD: isakmp_unity.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + /* $KAME$ */ /* @@ -29,6 +31,10 @@ * SUCH DAMAGE. */ +/* ISAKMP notifies specific to the Unity vendor Id */ +/* Sent during xauth if the user types his password too slowly */ +#define ISAKMP_NTYPE_UNITY_HEARTBEAT 40500 + /* ISAKMP mode config attributes specific to the Unity vendor Id */ #define UNITY_BANNER 28672 #define UNITY_SAVE_PASSWD 28673 @@ -42,4 +48,25 @@ #define UNITY_BACKUP_SERVERS 28681 #define UNITY_DDNS_HOSTNAME 28682 +/* + * Unity adress/mask lists + * XXX : the padding is probably there for something ! + */ + +struct unity_network { + struct in_addr addr4; + struct in_addr mask4; + char padding[6]; +} __attribute__((__packed__)); + +struct unity_netentry { + struct unity_network network; + struct unity_netentry *next; +}; + +int splitnet_list_add(struct unity_netentry **, struct unity_network *, int *); +void splitnet_list_free(struct unity_netentry *, int *); +char * splitnet_list_2str(struct unity_netentry *); + vchar_t *isakmp_unity_req(struct ph1handle *, struct isakmp_data *); +void isakmp_unity_reply(struct ph1handle *, struct isakmp_data *); diff --git a/ipsec-tools/racoon/isakmp_var.h b/ipsec-tools/racoon/isakmp_var.h index ef32d5b..d6dc017 100644 --- a/ipsec-tools/racoon/isakmp_var.h +++ b/ipsec-tools/racoon/isakmp_var.h @@ -61,12 +61,16 @@ struct isakmp_pl_nonce; /* XXX */ extern int isakmp_handler __P((int)); extern int isakmp_ph1begin_i __P((struct remoteconf *, struct sockaddr *, - struct sockaddr *)); + struct sockaddr *, int)); extern vchar_t *isakmp_parsewoh __P((int, struct isakmp_gen *, int)); extern vchar_t *isakmp_parse __P((vchar_t *)); +#ifndef __APPLE__ extern int isakmp_init __P((void)); +#else +extern int isakmp_init __P((int)); +#endif /* __APPLE__ */ extern void isakmp_cleanup __P((void)); extern const char *isakmp_pindex __P((const isakmp_index *, const u_int32_t)); @@ -84,6 +88,9 @@ extern void isakmp_ph2resend_stub __P((void *)); extern int isakmp_ph2resend __P((struct ph2handle *)); extern void isakmp_ph1expire_stub __P((void *)); extern void isakmp_ph1expire __P((struct ph1handle *)); +extern void isakmp_ph1rekeyexpire_stub __P((void *)); +extern void isakmp_ph1rekeyexpire __P((struct ph1handle *)); +extern int isakmp_ph1rekeyretry __P((struct ph1handle *)); extern void isakmp_ph1delete_stub __P((void *)); extern void isakmp_ph1delete __P((struct ph1handle *)); extern void isakmp_ph2expire_stub __P((void *)); @@ -126,11 +133,11 @@ extern void log_ph1established __P((const struct ph1handle *)); extern void script_hook __P((struct ph1handle *, int)); extern int script_env_append __P((char ***, int *, char *, char *)); -extern int script_exec __P((int, int, char * const *)); +extern int script_exec __P((char *, int, char * const *)); void purge_remote __P((struct ph1handle *)); void delete_spd __P((struct ph2handle *)); #ifdef INET6 u_int32_t setscopeid __P((struct sockaddr *, struct sockaddr *)); -#endif +#endif #endif /* _ISAKMP_VAR_H */ diff --git a/ipsec-tools/racoon/isakmp_xauth.c b/ipsec-tools/racoon/isakmp_xauth.c index 1bf87c1..aeb5aa8 100644 --- a/ipsec-tools/racoon/isakmp_xauth.c +++ b/ipsec-tools/racoon/isakmp_xauth.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_xauth.c,v 1.17.2.5 2005/05/20 07:31:09 manubsd Exp $ */ +/* $NetBSD: isakmp_xauth.c,v 1.11.6.1 2007/08/07 04:49:24 manu Exp $ */ + +/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */ /* * Copyright (C) 2004-2005 Emmanuel Dreyfus @@ -43,9 +45,7 @@ #include #include #include -#ifdef HAVE_SHADOW_H -#include -#endif +#include #if TIME_WITH_SYS_TIME # include # include @@ -61,6 +61,11 @@ #include #endif #include +#include + +#ifdef HAVE_SHADOW_H +#include +#endif #include "var.h" #include "misc.h" @@ -87,6 +92,10 @@ #include "ipsec_doi.h" #include "remoteconf.h" #include "localconf.h" +#include "vpn_control.h" +#include "vpn_control_var.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" #ifdef HAVE_LIBRADIUS #include @@ -96,11 +105,7 @@ struct rad_handle *radius_acct_state = NULL; #endif #ifdef HAVE_LIBPAM -#ifdef __APPLE__ -#include -#else #include -#endif static char *PAM_usr = NULL; static char *PAM_pwd = NULL; @@ -109,6 +114,11 @@ static int PAM_conv(int, const struct pam_message **, static struct pam_conv PAM_chat = { &PAM_conv, NULL }; #endif +#ifdef HAVE_LIBLDAP +#include "ldap.h" +#include +struct xauth_ldap_config xauth_ldap_config; +#endif void xauth_sendreq(iph1) @@ -167,7 +177,7 @@ xauth_sendreq(iph1) pwdattr->lorv = htons(0); isakmp_cfg_send(iph1, buffer, - ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL); vfree(buffer); @@ -176,7 +186,7 @@ xauth_sendreq(iph1) return; } -void +int xauth_attr_reply(iph1, attr, id) struct ph1handle *iph1; struct isakmp_data *attr; @@ -191,13 +201,13 @@ xauth_attr_reply(iph1, attr, id) plog(LLV_ERROR, LOCATION, NULL, "Xauth reply but peer did not declare " "itself as Xauth capable\n"); - return; + return -1; } if (xst->status != XAUTHST_REQSENT) { plog(LLV_ERROR, LOCATION, NULL, "Xauth reply while Xauth state is %d\n", xst->status); - return; + return -1; } type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; @@ -211,7 +221,7 @@ xauth_attr_reply(iph1, attr, id) plog(LLV_WARNING, LOCATION, NULL, "Unexpected authentication type %d\n", ntohs(type)); - return; + return -1; } break; @@ -232,10 +242,10 @@ xauth_attr_reply(iph1, attr, id) if (outlet != NULL) { alen = ntohs(attr->lorv); - if ((*outlet = racoon_malloc(alen + 1)) == NULL) { + if ((*outlet = racoon_realloc(*outlet, alen + 1)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory for Xauth Data\n"); - return; + return -1; } memcpy(*outlet, attr + 1, alen); @@ -256,8 +266,7 @@ xauth_attr_reply(iph1, attr, id) plog(LLV_DEBUG, LOCATION, NULL, "Got username \"%s\", password \"%s\"\n", usr, pwd); #endif - strncpy(iph1->mode_cfg->login, usr, LOGINLEN); - iph1->mode_cfg->login[LOGINLEN] = '\0'; + strlcpy(iph1->mode_cfg->login, usr, sizeof(iph1->mode_cfg->login)); res = -1; if ((port = isakmp_cfg_getport(iph1)) == -1) { @@ -280,6 +289,11 @@ xauth_attr_reply(iph1, attr, id) res = privsep_xauth_login_pam(iph1->mode_cfg->port, iph1->remote, usr, pwd); break; +#endif +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_AUTH_LDAP: + res = xauth_login_ldap(iph1, usr, pwd); + break; #endif default: plog(LLV_ERROR, LOCATION, NULL, @@ -288,6 +302,14 @@ xauth_attr_reply(iph1, attr, id) break; } + /* + * Optional group authentication + */ + if (!res && (isakmp_cfg_config.groupcount)) + res = group_check(iph1, + isakmp_cfg_config.grouplist, + isakmp_cfg_config.groupcount); + /* * On failure, throttle the connexion for the remote host * in order to make password attacks more difficult. @@ -313,8 +335,7 @@ skip_auth: if ((xra = racoon_malloc(sizeof(*xra))) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "malloc failed, bypass throttling\n"); - xauth_reply(iph1, port, id, res); - return; + return xauth_reply(iph1, port, id, res); } /* @@ -328,11 +349,11 @@ skip_auth: xra->res = res; sched_new(throttle_delay, xauth_reply_stub, xra); } else { - xauth_reply(iph1, port, id, res); + return xauth_reply(iph1, port, id, res); } } - return; + return 0; } void @@ -343,7 +364,7 @@ xauth_reply_stub(args) struct ph1handle *iph1; if ((iph1 = getph1byindex(&xra->index)) != NULL) - xauth_reply(iph1, xra->port, xra->id, xra->res); + (void)xauth_reply(iph1, xra->port, xra->id, xra->res); else plog(LLV_ERROR, LOCATION, NULL, "Delayed Xauth reply: phase 1 no longer exists.\n"); @@ -352,7 +373,7 @@ xauth_reply_stub(args) return; } -void +int xauth_reply(iph1, port, id, res) struct ph1handle *iph1; int port; @@ -377,7 +398,7 @@ xauth_reply(iph1, port, id, res) remph1(iph1); delph1(iph1); - return; + return -1; } xst->status = XAUTHST_OK; @@ -386,7 +407,7 @@ xauth_reply(iph1, port, id, res) xauth_sendstatus(iph1, XAUTH_STATUS_OK, id); - return; + return 0; } void @@ -420,7 +441,7 @@ xauth_sendstatus(iph1, status, id) stattr->lorv = htons(status); isakmp_cfg_send(iph1, buffer, - ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL); vfree(buffer); @@ -452,7 +473,7 @@ xauth_radius_init(void) if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) && (radius_acct_state == NULL)) { - if ((radius_acct_state = rad_auth_open()) == NULL) { + if ((radius_acct_state = rad_acct_open()) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot init libradius\n"); return -1; @@ -513,13 +534,13 @@ xauth_login_radius(iph1, usr, pwd) case RAD_FRAMED_IP_ADDRESS: iph1->mode_cfg->addr4 = rad_cvt_addr(data); iph1->mode_cfg->flags - |= ISAKMP_CFG_ADDR4_RADIUS; + |= ISAKMP_CFG_ADDR4_EXTERN; break; case RAD_FRAMED_IP_NETMASK: iph1->mode_cfg->mask4 = rad_cvt_addr(data); iph1->mode_cfg->flags - |= ISAKMP_CFG_MASK4_RADIUS; + |= ISAKMP_CFG_MASK4_EXTERN; break; default: @@ -574,13 +595,21 @@ PAM_conv(msg_count, msg, rsp, dontcare) case PAM_PROMPT_ECHO_ON: /* Send the username, libpam frees resp */ reply[i].resp_retcode = PAM_SUCCESS; - reply[i].resp = strdup(PAM_usr); + if ((reply[i].resp = strdup(PAM_usr)) == NULL) { + plog(LLV_ERROR, LOCATION, + NULL, "strdup failed\n"); + exit(1); + } break; case PAM_PROMPT_ECHO_OFF: /* Send the password, libpam frees resp */ reply[i].resp_retcode = PAM_SUCCESS; - reply[i].resp = strdup(PAM_pwd); + if ((reply[i].resp = strdup(PAM_pwd)) == NULL) { + plog(LLV_ERROR, LOCATION, + NULL, "strdup failed\n"); + exit(1); + } break; case PAM_TEXT_INFO: @@ -615,7 +644,7 @@ xauth_login_pam(port, raddr, usr, pwd) const void *data; size_t len; int type; - char *remote; + char *remote = NULL; pam_handle_t *pam = NULL; if (isakmp_cfg_config.port_pool == NULL) { @@ -678,15 +707,528 @@ xauth_login_pam(port, raddr, usr, pwd) goto out; } + if (remote != NULL) + free(remote); + return 0; out: pam_end(pam, error); isakmp_cfg_config.port_pool[port].pam = NULL; + if (remote != NULL) + free(remote); return -1; } #endif +#ifdef HAVE_LIBLDAP +int +xauth_ldap_init(void) +{ + int tmplen; + int error = -1; + + xauth_ldap_config.pver = 3; + xauth_ldap_config.host = NULL; + xauth_ldap_config.port = LDAP_PORT; + xauth_ldap_config.base = NULL; + xauth_ldap_config.subtree = 0; + xauth_ldap_config.bind_dn = NULL; + xauth_ldap_config.bind_pw = NULL; + xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE; + xauth_ldap_config.attr_user = NULL; + xauth_ldap_config.attr_addr = NULL; + xauth_ldap_config.attr_mask = NULL; + xauth_ldap_config.attr_group = NULL; + xauth_ldap_config.attr_member = NULL; + + /* set default host */ + tmplen = strlen(LDAP_DFLT_HOST); + xauth_ldap_config.host = vmalloc(tmplen); + if (xauth_ldap_config.host == NULL) + goto out; + memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen); + + /* set default user naming attribute */ + tmplen = strlen(LDAP_DFLT_USER); + xauth_ldap_config.attr_user = vmalloc(tmplen); + if (xauth_ldap_config.attr_user == NULL) + goto out; + memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen); + + /* set default address attribute */ + tmplen = strlen(LDAP_DFLT_ADDR); + xauth_ldap_config.attr_addr = vmalloc(tmplen); + if (xauth_ldap_config.attr_addr == NULL) + goto out; + memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen); + + /* set default netmask attribute */ + tmplen = strlen(LDAP_DFLT_MASK); + xauth_ldap_config.attr_mask = vmalloc(tmplen); + if (xauth_ldap_config.attr_mask == NULL) + goto out; + memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen); + + /* set default group naming attribute */ + tmplen = strlen(LDAP_DFLT_GROUP); + xauth_ldap_config.attr_group = vmalloc(tmplen); + if (xauth_ldap_config.attr_group == NULL) + goto out; + memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen); + + /* set default member attribute */ + tmplen = strlen(LDAP_DFLT_MEMBER); + xauth_ldap_config.attr_member = vmalloc(tmplen); + if (xauth_ldap_config.attr_member == NULL) + goto out; + memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen); + + error = 0; +out: + if (error != 0) + plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n"); + + return error; +} + +void +xauth_ldap_flush(void) +{ + if (xauth_ldap_config.host) { + vfree(xauth_ldap_config.host); + xauth_ldap_config.host = NULL; + } + if (xauth_ldap_config.base) { + vfree(xauth_ldap_config.base); + xauth_ldap_config.base = NULL; + } + if (xauth_ldap_config.bind_dn) { + vfree(xauth_ldap_config.bind_dn); + xauth_ldap_config.bind_dn = NULL; + } + if (xauth_ldap_config.bind_pw) { + vfree(xauth_ldap_config.bind_pw); + xauth_ldap_config.bind_pw = NULL; + } + if (xauth_ldap_config.attr_user) { + vfree(xauth_ldap_config.attr_user); + xauth_ldap_config.attr_user = NULL; + } + if (xauth_ldap_config.attr_addr) { + vfree(xauth_ldap_config.attr_addr); + xauth_ldap_config.attr_addr = NULL; + } + if (xauth_ldap_config.attr_mask) { + vfree(xauth_ldap_config.attr_mask); + xauth_ldap_config.attr_mask = NULL; + } + if (xauth_ldap_config.attr_group) { + vfree(xauth_ldap_config.attr_group); + xauth_ldap_config.attr_group = NULL; + } + if (xauth_ldap_config.attr_member) { + vfree(xauth_ldap_config.attr_member); + xauth_ldap_config.attr_member = NULL; + } +} + +int +xauth_login_ldap(iph1, usr, pwd) + struct ph1handle *iph1; + char *usr; + char *pwd; +{ + int rtn = -1; + int res = -1; + LDAP *ld = NULL; + LDAPMessage *lr = NULL; + LDAPMessage *le = NULL; + struct berval cred; + struct berval **bv = NULL; + struct timeval timeout; + char *init = NULL; + char *filter = NULL; + char *atlist[3]; + int atlist_len[sizeof(atlist)/sizeof(__typeof__(*atlist))]; + char *basedn = NULL; + char *userdn = NULL; + int udn_len = 0; + int tmplen = 0; + int ecount = 0; + int scope = LDAP_SCOPE_ONE; + + atlist[0] = NULL; + atlist_len[0] = 0; + atlist[1] = NULL; + atlist_len[1] = 0; + atlist[2] = NULL; + atlist_len[2] = 0; + + /* build our initialization url */ + tmplen = strlen("ldap://:") + 17; + tmplen += strlen(xauth_ldap_config.host->v); + init = racoon_malloc(tmplen); + if (init == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap init url\n"); + goto ldap_end; + } + snprintf(init, tmplen, "ldap://%s:%d", + xauth_ldap_config.host->v, + xauth_ldap_config.port ); + + /* initialize the ldap handle */ + res = ldap_initialize(&ld, init); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_initialize failed: %s\n", + ldap_err2string(res)); + goto ldap_end; + } + + /* initialize the protocol version */ + ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, + &xauth_ldap_config.pver); + + /* + * attempt to bind to the ldap server. + * default to anonymous bind unless a + * user dn and password has been + * specified in our configuration + */ + if ((xauth_ldap_config.bind_dn != NULL)&& + (xauth_ldap_config.bind_pw != NULL)) + { + cred.bv_val = xauth_ldap_config.bind_pw->v; + cred.bv_len = strlen( cred.bv_val ); + res = ldap_sasl_bind_s(ld, + xauth_ldap_config.bind_dn->v, NULL, &cred, + NULL, NULL, NULL); + } + else + { + res = ldap_sasl_bind_s(ld, + NULL, NULL, NULL, + NULL, NULL, NULL); + } + + if (res!=LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_sasl_bind_s (search) failed: %s\n", + ldap_err2string(res)); + goto ldap_end; + } + + /* build an ldap user search filter */ + tmplen = strlen(xauth_ldap_config.attr_user->v); + tmplen += 1; + tmplen += strlen(usr); + tmplen += 1; + filter = racoon_malloc(tmplen); + if (filter == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap search filter buffer\n"); + goto ldap_end; + } + snprintf(filter, tmplen, "%s=%s", + xauth_ldap_config.attr_user->v, usr); + + /* build our return attribute list */ + atlist_len[0] = strlen(xauth_ldap_config.attr_addr->v) + 1; + atlist[0] = racoon_malloc(atlist_len[0]); + atlist_len[1] = strlen(xauth_ldap_config.attr_mask->v) + 1; + atlist[1] = racoon_malloc(atlist_len[1]); + if ((atlist[0] == NULL)||(atlist[1] == NULL)) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap attrib list buffer\n"); + goto ldap_end; + } + strlcpy(atlist[0],xauth_ldap_config.attr_addr->v,atlist_len[0]); + strlcpy(atlist[1],xauth_ldap_config.attr_mask->v,atlist_len[1]); + + /* attempt to locate the user dn */ + if (xauth_ldap_config.base != NULL) + basedn = xauth_ldap_config.base->v; + if (xauth_ldap_config.subtree) + scope = LDAP_SCOPE_SUBTREE; + timeout.tv_sec = 15; + timeout.tv_usec = 0; + res = ldap_search_ext_s(ld, basedn, scope, + filter, atlist, 0, NULL, NULL, + &timeout, 2, &lr); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_search_ext_s failed: %s\n", + ldap_err2string(res)); + goto ldap_end; + } + + /* check the number of ldap entries returned */ + ecount = ldap_count_entries(ld, lr); + if (ecount < 1) { + plog(LLV_WARNING, LOCATION, NULL, + "no ldap results for filter \'%s\'\n", + filter); + goto ldap_end; + } + if (ecount > 1) { + plog(LLV_WARNING, LOCATION, NULL, + "multiple (%i) ldap results for filter \'%s\'\n", + ecount, filter); + } + + /* obtain the dn from the first result */ + le = ldap_first_entry(ld, lr); + if (le == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_first_entry failed: invalid entry returned\n"); + goto ldap_end; + } + userdn = ldap_get_dn(ld, le); + if (userdn == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_get_dn failed: invalid string returned\n"); + goto ldap_end; + } + + /* cache the user dn in the xauth state */ + udn_len = strlen(userdn)+1; + iph1->mode_cfg->xauth.udn = racoon_malloc(udn_len); + strlcpy(iph1->mode_cfg->xauth.udn,userdn,udn_len); + + /* retrieve modecfg address */ + bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v); + if (bv != NULL) { + char tmpaddr[16]; + /* sanity check for address value */ + if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) { + plog(LLV_DEBUG, LOCATION, NULL, + "ldap returned invalid modecfg address\n"); + ldap_value_free_len(bv); + goto ldap_end; + } + memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len); + tmpaddr[bv[0]->bv_len]=0; + iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr); + iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN; + plog(LLV_INFO, LOCATION, NULL, + "ldap returned modecfg address %s\n", tmpaddr); + ldap_value_free_len(bv); + } + + /* retrieve modecfg netmask */ + bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v); + if (bv != NULL) { + char tmpmask[16]; + /* sanity check for netmask value */ + if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) { + plog(LLV_DEBUG, LOCATION, NULL, + "ldap returned invalid modecfg netmask\n"); + ldap_value_free_len(bv); + goto ldap_end; + } + memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len); + tmpmask[bv[0]->bv_len]=0; + iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask); + iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN; + plog(LLV_INFO, LOCATION, NULL, + "ldap returned modecfg netmask %s\n", tmpmask); + ldap_value_free_len(bv); + } + + /* + * finally, use the dn and the xauth + * password to check the users given + * credentials by attempting to bind + * to the ldap server + */ + plog(LLV_INFO, LOCATION, NULL, + "attempting ldap bind for dn \'%s\'\n", userdn); + cred.bv_val = pwd; + cred.bv_len = strlen( cred.bv_val ); + res = ldap_sasl_bind_s(ld, + userdn, NULL, &cred, + NULL, NULL, NULL); + if(res==LDAP_SUCCESS) + rtn = 0; + +ldap_end: + + /* free ldap resources */ + if (userdn != NULL) + ldap_memfree(userdn); + if (atlist[0] != NULL) + racoon_free(atlist[0]); + if (atlist[1] != NULL) + racoon_free(atlist[1]); + if (filter != NULL) + racoon_free(filter); + if (lr != NULL) + ldap_msgfree(lr); + if (init != NULL) + racoon_free(init); + + ldap_unbind_ext_s(ld, NULL, NULL); + + return rtn; +} + +int +xauth_group_ldap(udn, grp) + char * udn; + char * grp; +{ + int rtn = -1; + int res = -1; + LDAP *ld = NULL; + LDAPMessage *lr = NULL; + LDAPMessage *le = NULL; + struct berval cred; + struct timeval timeout; + char *init = NULL; + char *filter = NULL; + char *basedn = NULL; + char *groupdn = NULL; + int tmplen = 0; + int ecount = 0; + int scope = LDAP_SCOPE_ONE; + + /* build our initialization url */ + tmplen = strlen("ldap://:") + 17; + tmplen += strlen(xauth_ldap_config.host->v); + init = racoon_malloc(tmplen); + if (init == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap init url\n"); + goto ldap_group_end; + } + snprintf(init, tmplen, "ldap://%s:%d", + xauth_ldap_config.host->v, + xauth_ldap_config.port ); + + /* initialize the ldap handle */ + res = ldap_initialize(&ld, init); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_initialize failed: %s\n", + ldap_err2string(res)); + goto ldap_group_end; + } + + /* initialize the protocol version */ + ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, + &xauth_ldap_config.pver); + + /* + * attempt to bind to the ldap server. + * default to anonymous bind unless a + * user dn and password has been + * specified in our configuration + */ + if ((xauth_ldap_config.bind_dn != NULL)&& + (xauth_ldap_config.bind_pw != NULL)) + { + cred.bv_val = xauth_ldap_config.bind_pw->v; + cred.bv_len = strlen( cred.bv_val ); + res = ldap_sasl_bind_s(ld, + xauth_ldap_config.bind_dn->v, NULL, &cred, + NULL, NULL, NULL); + } + else + { + res = ldap_sasl_bind_s(ld, + NULL, NULL, NULL, + NULL, NULL, NULL); + } + + if (res!=LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_sasl_bind_s (search) failed: %s\n", + ldap_err2string(res)); + goto ldap_group_end; + } + + /* build an ldap group search filter */ + tmplen = strlen("(&(=)(=))") + 1; + tmplen += strlen(xauth_ldap_config.attr_group->v); + tmplen += strlen(grp); + tmplen += strlen(xauth_ldap_config.attr_member->v); + tmplen += strlen(udn); + filter = racoon_malloc(tmplen); + if (filter == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to alloc ldap search filter buffer\n"); + goto ldap_group_end; + } + snprintf(filter, tmplen, "(&(%s=%s)(%s=%s))", + xauth_ldap_config.attr_group->v, grp, + xauth_ldap_config.attr_member->v, udn); + + /* attempt to locate the group dn */ + if (xauth_ldap_config.base != NULL) + basedn = xauth_ldap_config.base->v; + if (xauth_ldap_config.subtree) + scope = LDAP_SCOPE_SUBTREE; + timeout.tv_sec = 15; + timeout.tv_usec = 0; + res = ldap_search_ext_s(ld, basedn, scope, + filter, NULL, 0, NULL, NULL, + &timeout, 2, &lr); + if (res != LDAP_SUCCESS) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_search_ext_s failed: %s\n", + ldap_err2string(res)); + goto ldap_group_end; + } + + /* check the number of ldap entries returned */ + ecount = ldap_count_entries(ld, lr); + if (ecount < 1) { + plog(LLV_WARNING, LOCATION, NULL, + "no ldap results for filter \'%s\'\n", + filter); + goto ldap_group_end; + } + + /* success */ + rtn = 0; + + /* obtain the dn from the first result */ + le = ldap_first_entry(ld, lr); + if (le == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_first_entry failed: invalid entry returned\n"); + goto ldap_group_end; + } + groupdn = ldap_get_dn(ld, le); + if (groupdn == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "ldap_get_dn failed: invalid string returned\n"); + goto ldap_group_end; + } + + plog(LLV_INFO, LOCATION, NULL, + "ldap membership group returned \'%s\'\n", groupdn); +ldap_group_end: + + /* free ldap resources */ + if (groupdn != NULL) + ldap_memfree(groupdn); + if (filter != NULL) + racoon_free(filter); + if (lr != NULL) + ldap_msgfree(lr); + if (init != NULL) + racoon_free(init); + + ldap_unbind_ext_s(ld, NULL, NULL); + + return rtn; +} + +#endif + int xauth_login_system(usr, pwd) char *usr; @@ -724,22 +1266,54 @@ xauth_login_system(usr, pwd) return -1; } +int +xauth_group_system(usr, grp) + char * usr; + char * grp; +{ + struct group * gr; + char * member; + int index = 0; + + gr = getgrnam(grp); + if (gr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "the system group name \'%s\' is unknown\n", + grp); + return -1; + } + + while ((member = gr->gr_mem[index++])!=NULL) { + if (!strcmp(member,usr)) { + plog(LLV_INFO, LOCATION, NULL, + "membership validated\n"); + return 0; + } + } + + return -1; +} + int xauth_check(iph1) struct ph1handle *iph1; { struct xauth_state *xst = &iph1->mode_cfg->xauth; - /* If we don't use Xauth, then we pass */ - switch (iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + /* + * Only the server side (edge device) really check for Xauth + * status. It does it if the chose authmethod is using Xauth. + * On the client side (roadwarrior), we don't check anything. + */ + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: /* The following are not yet implemented */ - case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: - case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: - case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: - case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: - case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { plog(LLV_ERROR, LOCATION, NULL, "Hybrid auth negotiated but peer did not " @@ -764,6 +1338,80 @@ xauth_check(iph1) return 0; } +int +group_check(iph1, grp_list, grp_count) + struct ph1handle *iph1; + char **grp_list; + int grp_count; +{ + int res = -1; + int grp_index = 0; + char * usr = NULL; + + /* check for presence of modecfg data */ + + if(iph1->mode_cfg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth group specified but modecfg not found\n"); + return res; + } + + /* loop through our group list */ + + for(; grp_index < grp_count; grp_index++) { + + /* check for presence of xauth data */ + + usr = iph1->mode_cfg->xauth.authdata.generic.usr; + + if(usr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth group specified but xauth not found\n"); + return res; + } + + /* call appropriate group validation funtion */ + + switch (isakmp_cfg_config.groupsource) { + + case ISAKMP_CFG_GROUP_SYSTEM: + res = xauth_group_system( + usr, + grp_list[grp_index]); + break; + +#ifdef HAVE_LIBLDAP + case ISAKMP_CFG_GROUP_LDAP: + res = xauth_group_ldap( + iph1->mode_cfg->xauth.udn, + grp_list[grp_index]); + break; +#endif + + default: + /* we should never get here */ + plog(LLV_ERROR, LOCATION, NULL, + "Unknown group auth source\n"); + break; + } + + if( !res ) { + plog(LLV_INFO, LOCATION, NULL, + "user \"%s\" is a member of group \"%s\"\n", + usr, + grp_list[grp_index]); + break; + } else { + plog(LLV_INFO, LOCATION, NULL, + "user \"%s\" is not a member of group \"%s\"\n", + usr, + grp_list[grp_index]); + } + } + + return res; +} + vchar_t * isakmp_xauth_req(iph1, attr) struct ph1handle *iph1; @@ -774,6 +1422,8 @@ isakmp_xauth_req(iph1, attr) int ashort = 0; int value = 0; vchar_t *buffer = NULL; + char* mraw = NULL; + vchar_t *mdata = NULL; char *data; vchar_t *usr = NULL; vchar_t *pwd = NULL; @@ -809,48 +1459,41 @@ isakmp_xauth_req(iph1, attr) break; case XAUTH_USER_NAME: - if (iph1->rmconf->idvtype != IDTYPE_LOGIN) { - plog(LLV_ERROR, LOCATION, NULL, "Xauth performed " - "while identifier is not a login\n"); - return NULL; - } - - if (iph1->rmconf->idv == NULL) { + if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) { plog(LLV_ERROR, LOCATION, NULL, "Xauth performed " "with no login supplied\n"); return NULL; } - dlen = iph1->rmconf->idv->l; + dlen = iph1->rmconf->xauth->login->l - 1; + iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME; break; case XAUTH_USER_PASSWORD: - if (iph1->rmconf->idvtype != IDTYPE_LOGIN) - return NULL; - - if (iph1->rmconf->idv == NULL) + case XAUTH_PASSCODE: + if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) return NULL; skip = sizeof(struct ipsecdoi_id_b); - if ((usr = vmalloc(iph1->rmconf->idv->l + skip)) == NULL) { + usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip); + if (usr == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); return NULL; } - memset(usr->v, 0, skip); memcpy(usr->v + skip, - iph1->rmconf->idv->v, - iph1->rmconf->idv->l); + iph1->rmconf->xauth->login->v, + iph1->rmconf->xauth->login->l - 1); - if (iph1->rmconf->key) { + if (iph1->rmconf->xauth->pass) { /* A key given through racoonctl */ - pwd = iph1->rmconf->key; + pwd = iph1->rmconf->xauth->pass; } else { if ((pwd = getpskbyname(usr)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "No password was found for login %s\n", - iph1->rmconf->idv->v); + iph1->rmconf->xauth->login->v); vfree(usr); return NULL; } @@ -859,13 +1502,32 @@ isakmp_xauth_req(iph1, attr) } vfree(usr); - dlen = pwd->l; + iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD; + dlen = pwd->l - 1; break; - + + case XAUTH_MESSAGE: + if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) { + dlen = ntohs(attr->lorv); + if (dlen > 0) { + mraw = (char*)(attr + 1); + if ((mdata = vmalloc(dlen)) == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cannot allocate memory\n"); + return NULL; + } + memcpy(mdata->v, mraw, mdata->l); + plog(LLV_NOTIFY,LOCATION, iph1->remote, + "XAUTH Message: '%s'.\n", + binsanitize(mdata->v, mdata->l)); + vfree(mdata); + } + } + return NULL; default: plog(LLV_WARNING, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); return NULL; break; } @@ -889,9 +1551,14 @@ isakmp_xauth_req(iph1, attr) switch(type) { case XAUTH_USER_NAME: - memcpy(data, iph1->rmconf->idv->v, dlen); + /* + * iph1->rmconf->xauth->login->v is valid, + * we just checked it in the previous switch case + */ + memcpy(data, iph1->rmconf->xauth->login->v, dlen); break; case XAUTH_USER_PASSWORD: + case XAUTH_PASSCODE: memcpy(data, pwd->v, dlen); break; default: @@ -913,8 +1580,16 @@ isakmp_xauth_set(iph1, attr) int type; vchar_t *buffer = NULL; char *data; + struct xauth_state *xst; + size_t dlen = 0; + char* mraw = NULL; + vchar_t *mdata = NULL; if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP, + CONSTSTR("XAUTH is not supported by peer"), + CONSTSTR("XAUTH dropped (not supported by peer)")); plog(LLV_ERROR, LOCATION, NULL, "Xauth mode config set but peer " "did not declare itself as Xauth capable\n"); @@ -925,31 +1600,107 @@ isakmp_xauth_set(iph1, attr) switch(type) { case XAUTH_STATUS: + /* + * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS + * when running as a client (initiator). + */ + xst = &iph1->mode_cfg->xauth; + switch(AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + if (!iph1->is_rekey) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP, + CONSTSTR("Unexpected XAUTH Status"), + CONSTSTR("Xauth dropped (unexpected Xauth status)... not a phase1 rekey")); + plog(LLV_ERROR, LOCATION, NULL, + "Unexpected XAUTH_STATUS_OK... not a phase1 rekey\n"); + return NULL; + } + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + /* Not implemented ... */ + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + break; + default: + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP, + CONSTSTR("Unexpected XAUTH Status"), + CONSTSTR("Xauth dropped (unexpected Xauth status)")); + plog(LLV_ERROR, LOCATION, NULL, + "Unexpected XAUTH_STATUS_OK\n"); + return NULL; + break; + } + /* If we got a failure, delete iph1 */ if (ntohs(attr->lorv) != XAUTH_STATUS_OK) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL, + CONSTSTR("XAUTH Status is not OK"), + CONSTSTR("Xauth Failed (status not ok)")); plog(LLV_ERROR, LOCATION, NULL, "Xauth authentication failed\n"); EVT_PUSH(iph1->local, iph1->remote, EVTT_XAUTH_FAILED, NULL); + + vpncontrol_notify_ike_failed(VPNCTL_NTYPE_AUTHENTICATION_FAILED, FROM_LOCAL, + ((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr, 0, NULL); iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1; } else { - EVT_PUSH(iph1->local, - iph1->remote, EVTT_XAUTH_SUCCESS, NULL); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC, + CONSTSTR("XAUTH Status is OK"), + CONSTSTR(NULL)); + EVT_PUSH(iph1->local, iph1->remote, + EVTT_XAUTH_SUCCESS, NULL); + if (iph1->is_rekey) { + xst->status = XAUTHST_OK; + } } /* We acknowledge it */ break; + case XAUTH_MESSAGE: + if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) { + dlen = ntohs(attr->lorv); + if (dlen > 0) { + mraw = (char*)(attr + 1); + if ((mdata = vmalloc(dlen)) == NULL) { + plog(LLV_ERROR, LOCATION, iph1->remote, + "Cannot allocate memory\n"); + return NULL; + } + memcpy(mdata->v, mraw, mdata->l); + plog(LLV_NOTIFY,LOCATION, iph1->remote, + "XAUTH Message: '%s'.\n", + binsanitize(mdata->v, mdata->l)); + vfree(mdata); + } + } + default: + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP, + CONSTSTR("ignored attribute"), + CONSTSTR("Xauth dropped (ignored attribute)")); plog(LLV_WARNING, LOCATION, NULL, - "Ignored attribute %d\n", type); + "Ignored attribute %s\n", s_isakmp_cfg_type(type)); return NULL; break; } if ((buffer = vmalloc(sizeof(*attr))) == NULL) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP, + CONSTSTR("Failed to allocate attribute"), + CONSTSTR("Xauth dropped (failed to allocate attribute)")); plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); return NULL; @@ -990,6 +1741,56 @@ xauth_rmstate(xst) break; } +#ifdef HAVE_LIBLDAP + if (xst->udn != NULL) + racoon_free(xst->udn); +#endif return; } +int +xauth_rmconf_used(xauth_rmconf) + struct xauth_rmconf **xauth_rmconf; +{ + if (*xauth_rmconf == NULL) { + *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf)); + if (*xauth_rmconf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "xauth_rmconf_used: malloc failed\n"); + return -1; + } + + (*xauth_rmconf)->login = NULL; + (*xauth_rmconf)->pass = NULL; + (*xauth_rmconf)->state = 0; + } else { + if ((*xauth_rmconf)->login) { + vfree((*xauth_rmconf)->login); + (*xauth_rmconf)->login = NULL; + } + if ((*xauth_rmconf)->pass != NULL) { + vfree((*xauth_rmconf)->pass); + (*xauth_rmconf)->pass = NULL; + } + (*xauth_rmconf)->state = 0; + } + + return 0; +} + +void +xauth_rmconf_delete(xauth_rmconf) + struct xauth_rmconf **xauth_rmconf; +{ + if (*xauth_rmconf != NULL) { + if ((*xauth_rmconf)->login != NULL) + vfree((*xauth_rmconf)->login); + if ((*xauth_rmconf)->pass != NULL) + vfree((*xauth_rmconf)->pass); + + racoon_free(*xauth_rmconf); + *xauth_rmconf = NULL; + } + + return; +} diff --git a/ipsec-tools/racoon/isakmp_xauth.h b/ipsec-tools/racoon/isakmp_xauth.h index 5d4bdbb..5898062 100644 --- a/ipsec-tools/racoon/isakmp_xauth.h +++ b/ipsec-tools/racoon/isakmp_xauth.h @@ -1,3 +1,5 @@ +/* $NetBSD: isakmp_xauth.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + /* $KAME$ */ /* @@ -29,6 +31,9 @@ * SUCH DAMAGE. */ +#ifndef _ISAKMP_XAUTH_H +#define _ISAKMP_XAUTH_H + /* ISAKMP mode config attribute types specific to the Xauth vendor ID */ #define XAUTH_TYPE 16520 #define XAUTH_USER_NAME 16521 @@ -51,8 +56,9 @@ #define XAUTH_STATUS_FAIL 0 #define XAUTH_STATUS_OK 1 +/* For phase 1 Xauth status */ struct xauth_state { - int status; + int status; /* authentication status, used only on server side */ int vendorid; int authtype; union { @@ -61,6 +67,21 @@ struct xauth_state { char *pwd; } generic; } authdata; +#ifdef HAVE_LIBLDAP + char *udn; /* ldap user dn */ +#endif +}; + +/* What's been sent */ +#define XAUTH_SENT_USERNAME 1 +#define XAUTH_SENT_PASSWORD 2 +#define XAUTH_SENT_EVERYTHING (XAUTH_SENT_USERNAME | XAUTH_SENT_PASSWORD) + +/* For rmconf Xauth data */ +struct xauth_rmconf { + vchar_t *login; /* xauth login */ + vchar_t *pass; /* xauth password */ + int state; /* what's been sent */ }; /* status */ @@ -76,21 +97,60 @@ struct xauth_reply_arg { }; struct ph1handle; +struct isakmp_data; void xauth_sendreq(struct ph1handle *); -void xauth_attr_reply(struct ph1handle *, struct isakmp_data *, int); +int xauth_attr_reply(struct ph1handle *, struct isakmp_data *, int); int xauth_login_system(char *, char *); void xauth_sendstatus(struct ph1handle *, int, int); int xauth_check(struct ph1handle *); +int group_check(struct ph1handle *, char **, int); vchar_t *isakmp_xauth_req(struct ph1handle *, struct isakmp_data *); vchar_t *isakmp_xauth_set(struct ph1handle *, struct isakmp_data *); void xauth_rmstate(struct xauth_state *); void xauth_reply_stub(void *); -void xauth_reply(struct ph1handle *, int, int, int); +int xauth_reply(struct ph1handle *, int, int, int); +int xauth_rmconf_used(struct xauth_rmconf **); +void xauth_rmconf_delete(struct xauth_rmconf **); #ifdef HAVE_LIBRADIUS int xauth_login_radius(struct ph1handle *, char *, char *); int xauth_radius_init(void); #endif + #ifdef HAVE_LIBPAM int xauth_login_pam(int, struct sockaddr *, char *, char *); #endif + +#ifdef HAVE_LIBLDAP + +#define LDAP_DFLT_HOST "localhost" +#define LDAP_DFLT_USER "cn" +#define LDAP_DFLT_ADDR "racoon-address" +#define LDAP_DFLT_MASK "racoon-netmask" +#define LDAP_DFLT_GROUP "cn" +#define LDAP_DFLT_MEMBER "member" + +struct xauth_ldap_config { + int pver; + vchar_t *host; + int port; + vchar_t *base; + int subtree; + vchar_t *bind_dn; + vchar_t *bind_pw; + int auth_type; + vchar_t *attr_user; + vchar_t *attr_addr; + vchar_t *attr_mask; + vchar_t *attr_group; + vchar_t *attr_member; +}; + +extern struct xauth_ldap_config xauth_ldap_config; + +int xauth_ldap_init(void); +void xauth_ldap_flush(void); +int xauth_login_ldap(struct ph1handle *, char *, char *); +#endif + +#endif /* _ISAKMP_XAUTH_H */ diff --git a/ipsec-tools/racoon/kmpstat.c b/ipsec-tools/racoon/kmpstat.c index b9eec1a..f4629ac 100644 --- a/ipsec-tools/racoon/kmpstat.c +++ b/ipsec-tools/racoon/kmpstat.c @@ -65,6 +65,7 @@ #endif #include #include +#include #include "libpfkey.h" @@ -106,7 +107,7 @@ com_init() memset(&name, 0, sizeof(name)); name.sun_family = AF_UNIX; snprintf(name.sun_path, sizeof(name.sun_path), - "%s", ADMINSOCK_PATH); + "%s", adminsock_path); so = socket(AF_UNIX, SOCK_STREAM, 0); if (so < 0) diff --git a/ipsec-tools/racoon/localconf.c b/ipsec-tools/racoon/localconf.c index 6725987..7b2c5ba 100644 --- a/ipsec-tools/racoon/localconf.c +++ b/ipsec-tools/racoon/localconf.c @@ -64,7 +64,11 @@ #ifdef __APPLE__ #include +#if HAVE_SECURITY_FRAMEWORK #include +#else +typedef void * SecKeychainRef; +#endif #endif struct localconf *lcconf; @@ -135,6 +139,7 @@ setdefault() lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL; lcconf->auto_exit_delay = 0; lcconf->auto_exit_state &= ~LC_AUTOEXITSTATE_SET; + lcconf->auto_exit_state |= LC_AUTOEXITSTATE_CLIENT; /* always auto exit as default */ } /* @@ -165,7 +170,7 @@ end: return key; } -#ifdef __APPLE__ +#if defined(__APPLE__) && HAVE_KEYCHAIN /* * get PSK from keyChain. */ @@ -210,7 +215,7 @@ getpskfromkeychain(const char *name, u_int8_t etype, int secrettype, vchar_t *id case IPSECDOI_ID_IPV6_ADDR_RANGE: case IPSECDOI_ID_DER_ASN1_DN: case IPSECDOI_ID_DER_ASN1_GN: - goto end; + goto no_id; break; case IPSECDOI_ID_FQDN: @@ -239,11 +244,23 @@ getpskfromkeychain(const char *name, u_int8_t etype, int secrettype, vchar_t *id &cur_password, NULL); + /* try find it using using only the peer id. */ + if (status == errSecItemNotFound) + status = SecKeychainFindGenericPassword(keychain, + idlen, + peer_id, + 0, + 0, + &cur_password_len, + &cur_password, + NULL); + if (status == noErr) goto end; /* otherwise fall through to use the default value */ } +no_id: /* use the value in remote config sharedsecret field this is either the value specified for lookup or the default when lookup by id fails. @@ -482,3 +499,5 @@ doitype2doi(doitype) return -1; } + + diff --git a/ipsec-tools/racoon/localconf.h b/ipsec-tools/racoon/localconf.h index 95fda09..f2671be 100644 --- a/ipsec-tools/racoon/localconf.h +++ b/ipsec-tools/racoon/localconf.h @@ -32,6 +32,10 @@ #ifndef _LOCALCONF_H #define _LOCALCONF_H +#if !TARGET_OS_EMBEDDED +#include +#endif + /* local configuration */ #define LC_DEFAULT_CF SYSCONFDIR "/racoon.conf" @@ -79,6 +83,9 @@ struct vpnctl_socket_elem { struct bound_addr { LIST_ENTRY(bound_addr) chain; u_int32_t address; + vchar_t *user_id; + vchar_t *user_pw; + vchar_t *version; /* our version string - if present */ }; struct redirect { @@ -93,6 +100,7 @@ struct saved_msg_elem { void* msg; }; + struct localconf { char *racoon_conf; /* configuration filename */ @@ -108,6 +116,7 @@ struct localconf { int sock_vpncontrol; int sock_pfkey; int rtsock; /* routing socket */ + LIST_HEAD(_vpnctl_socket_elem_, vpnctl_socket_elem) vpnctl_comm_socks; LIST_HEAD(_redirect_, redirect) redirect_addresses; int auto_exit_state; /* auto exit state */ @@ -118,7 +127,7 @@ struct localconf { int autograbaddr; struct myaddrs *myaddrs; - char *logfile_param; /* from command line */ + char *logfile_param; /* from command line */ char *pathinfo[LC_PATHTYPE_MAX]; vchar_t *ident[LC_IDENTTYPE_MAX]; /* base of Identifier payload. */ @@ -154,6 +163,9 @@ struct localconf { */ int gss_id_enc; /* GSS ID encoding to use */ +#if !TARGET_OS_EMBEDDED + vproc_transaction_t vt; /* returned by vproc_transaction_begin */ +#endif }; extern struct localconf *lcconf; @@ -162,7 +174,7 @@ extern void initlcconf __P((void)); extern void flushlcconf __P((void)); extern vchar_t *getpskbyname __P((vchar_t *)); extern vchar_t *getpskbyaddr __P((struct sockaddr *)); -#ifdef __APPLE__ +#if defined(__APPLE__) && HAVE_KEYCHAIN extern vchar_t *getpskfromkeychain __P((const char *, u_int8_t, int, vchar_t *)); #endif extern void getpathname __P((char *, int, int, const char *)); @@ -170,4 +182,5 @@ extern int sittype2doi __P((int)); extern int doitype2doi __P((int)); extern vchar_t *getpsk __P((const char *, const int)); + #endif /* _LOCALCONF_H */ diff --git a/ipsec-tools/racoon/logger.c b/ipsec-tools/racoon/logger.c index 03a3ac6..b9ac558 100644 --- a/ipsec-tools/racoon/logger.c +++ b/ipsec-tools/racoon/logger.c @@ -87,7 +87,7 @@ log_open(siz, fname) p->siz = siz; if (fname) - p->fname = strdup(fname); + p->fname = racoon_strdup(fname); return p; } @@ -105,7 +105,7 @@ log_add(p, str) /* syslog if p->fname == NULL? */ if (p->buf[p->head]) racoon_free(p->buf[p->head]); - p->buf[p->head] = strdup(str); + p->buf[p->head] = racoon_strdup(str); p->tbuf[p->head] = time(NULL); p->head++; p->head %= p->siz; diff --git a/ipsec-tools/racoon/main.c b/ipsec-tools/racoon/main.c index f325c90..82057e7 100644 --- a/ipsec-tools/racoon/main.c +++ b/ipsec-tools/racoon/main.c @@ -49,6 +49,7 @@ #endif #include #include +#include /* * If we're using a debugging malloc library, this may define our @@ -65,19 +66,27 @@ #include "cfparse_proto.h" #include "isakmp_var.h" -#ifdef HAVE_LIBRADIUS +#ifdef ENABLE_HYBRID +#include #include "isakmp.h" #include "isakmp_xauth.h" +#include "isakmp_cfg.h" #endif #include "remoteconf.h" #include "localconf.h" #include "session.h" #include "oakley.h" #include "pfkey.h" +#include "policy.h" #include "crypto_openssl.h" #include "backupsa.h" #include "vendorid.h" +#ifdef __APPLE__ +#include +#include +#endif + //#include "package_version.h" int f_local = 0; /* local test mode. behave like a wall. */ @@ -99,6 +108,7 @@ static void restore_params __P((void)); static void save_params __P((void)); static void saverestore_params __P((int)); static void cleanup_pidfile __P((void)); +static int launchedbylaunchd(void); pid_t racoon_pid = 0; int print_pid = 1; /* for racoon only */ @@ -106,7 +116,7 @@ int print_pid = 1; /* for racoon only */ void usage() { - printf("usage: racoon [-BdFve%s] %s[-f (file)] [-l (file)] [-p (port)]\n", + printf("usage: racoon [-BdFvs%s] %s[-f (file)] [-l (file)] [-p (port)]\n", #ifdef INET6 "46", #else @@ -125,7 +135,7 @@ usage() printf(" -L: include location in debug messages\n"); printf(" -F: run in foreground, do not become daemon.\n"); printf(" -v: be more verbose\n"); - printf(" -e: enable auto exit\n"); + printf(" -s: override enable auto exit\n"); #ifdef INET6 printf(" -4: IPv4 mode.\n"); printf(" -6: IPv6 mode.\n"); @@ -146,6 +156,7 @@ main(ac, av) char **av; { int error; + char logFileStr[MAXPATHLEN+1]; if (geteuid() != 0) { errx(1, "must be root to invoke this program."); @@ -168,6 +179,8 @@ main(ac, av) DRM_init(); #endif + logFileStr[0] = 0; + eay_init(); initlcconf(); initrmconf(); @@ -175,8 +188,63 @@ main(ac, av) compute_vendorids(); parse(ac, av); - if (lcconf->logfile_param) - plogset(lcconf->logfile_param); + + #ifdef __APPLE__ + /* + * Check IPSec plist + */ + { + SCPreferencesRef prefs = NULL; + CFPropertyListRef globals; + CFStringRef logFileRef; + CFNumberRef debugLevelRef; + + int level = 0; + + logFileStr[0] = 0; + + if ((prefs = SCPreferencesCreate(0, CFSTR("racoon"), CFSTR("com.apple.ipsec.plist"))) == NULL) + goto skip; + globals = SCPreferencesGetValue(prefs, CFSTR("Global")); + if (!globals || (CFGetTypeID(globals) != CFDictionaryGetTypeID())) + goto skip; + debugLevelRef = CFDictionaryGetValue(globals, CFSTR("DebugLevel")); + if (!debugLevelRef || (CFGetTypeID(debugLevelRef) != CFNumberGetTypeID())) + goto skip; + CFNumberGetValue(debugLevelRef, kCFNumberSInt32Type, &level); + switch (level) + { + case 0: + loglevel = 5; + goto skip; + break; + case 1: + loglevel = 6; + break; + case 2: + loglevel = 7; + break; + default: + break; /* invalid - ignore */ + } + + logFileRef = CFDictionaryGetValue(globals, CFSTR("DebugLogfile")); + if (!logFileRef || (CFGetTypeID(logFileRef) != CFStringGetTypeID())) { + goto skip; + } + CFStringGetCString(logFileRef, logFileStr, MAXPATHLEN, kCFStringEncodingMacRoman); +skip: + if (prefs) + CFRelease(prefs); + } + + if (logFileStr[0]) + plogset(logFileStr); + else +#endif /* __APPLE__ */ + if (lcconf->logfile_param) + plogset(lcconf->logfile_param); + ploginit(); plog(LLV_INFO, LOCATION, NULL, "***** racoon started: pid=%d started by: %d\n", getpid(), getppid()); @@ -184,6 +252,8 @@ main(ac, av) plog(LLV_INFO, LOCATION, NULL, "@(#)" "This product linked %s (http://www.openssl.org/)" "\n", eay_version()); + plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n", + lcconf->racoon_conf); if (pfkey_init() < 0) { errx(1, "something error happened " @@ -191,6 +261,16 @@ main(ac, av) /* NOTREACHED*/ } +#ifdef ENABLE_HYBRID + if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD)) + errx(1, "could not initialize ISAKMP mode config structures"); +#endif + +#ifdef HAVE_LIBLDAP + if (xauth_ldap_init() != 0) + errx(1, "could not initialize libldap"); +#endif + /* * in order to prefer the parameters by command line, * saving some parameters before parsing configuration file. @@ -200,7 +280,8 @@ main(ac, av) if (error != 0) errx(1, "failed to parse configuration file."); restore_params(); - if (lcconf->logfile_param == NULL) + + if (lcconf->logfile_param == NULL && logFileStr[0] == 0) plogreset(lcconf->pathinfo[LC_PATHTYPE_LOGFILE]); #ifdef ENABLE_NATT @@ -235,54 +316,67 @@ main(ac, av) if (f_foreground) close(0); - else if (exec_done) { - if (atexit(cleanup_pidfile) < 0) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot register pidfile cleanup"); - } - } else { - #define MAX_EXEC_ARGS 32 - - char *args[MAX_EXEC_ARGS + 1]; - char *env[1] = {0}; - int i; - - if (ac > MAX_EXEC_ARGS) { - plog(LLV_ERROR, LOCATION, NULL, - "too many arguments.\n"); - exit(1); - } - - if (daemon(0, 0) < 0) { - errx(1, "failed to be daemon. (%s)", - strerror(errno)); - } + else { + if ( !exec_done && launchedbylaunchd() ){ + plog(LLV_INFO, LOCATION, NULL, + "racoon launched by launchd.\n"); + exec_done = 1; + if (atexit(cleanup_pidfile) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot register pidfile cleanup"); + } + }else { - /* Radar 5129006 - Prevent non-root user from killing racoon - * when launched by setuid process - */ - if (setuid(0)) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot set uid.\n"); - exit(1); - } - if (setgid(0)) { - plog(LLV_ERROR, LOCATION, NULL, - "cannot set gid.\n"); - exit(1); + if (exec_done) { + if (atexit(cleanup_pidfile) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot register pidfile cleanup"); + } + } else { + #define MAX_EXEC_ARGS 32 + + char *args[MAX_EXEC_ARGS + 2]; /* 2 extra, for '-x' and NULL */ + char *env[1] = {0}; + int i; + + if (ac > MAX_EXEC_ARGS) { + plog(LLV_ERROR, LOCATION, NULL, + "too many arguments.\n"); + exit(1); + } + + if (daemon(0, 0) < 0) { + errx(1, "failed to be daemon. (%s)", + strerror(errno)); + } + + /* Radar 5129006 - Prevent non-root user from killing racoon + * when launched by setuid process + */ + if (setuid(0)) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot set uid.\n"); + exit(1); + } + if (setgid(0)) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot set gid.\n"); + exit(1); + } + + /* setup args to re-exec - for CoreFoundation issues */ + args[0] = PATHRACOON; + for (i = 1; i < ac; i++) + args[i] = *(av + i); + args[ac] = "-x"; /* tells racoon its been exec'd */ + args[ac+1] = 0; + + execve(PATHRACOON, args, env); + plog(LLV_ERROR, LOCATION, NULL, + "failed to exec racoon. (%s)", strerror(errno)); + exit(1); + } } - - /* setup args to re-exec - for CoreFoundation issues */ - args[0] = PATHRACOON; - for (i = 1; i < ac; i++) - args[i] = *(av + i); - args[ac] = "-x"; /* tells racoon its been exec'd */ - args[ac+1] = 0; - - execve(PATHRACOON, args, env); - plog(LLV_ERROR, LOCATION, NULL, - "failed to exec racoon. (%s)", strerror(errno)); - exit(1); } session(); @@ -291,6 +385,41 @@ main(ac, av) } +static int +launchedbylaunchd(){ + int launchdlaunched = 1; + launch_data_t checkin_response = NULL; + launch_data_t checkin_request = NULL; + + /* check in with launchd */ + if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "launch_data_new_string fails.\n"); + launchdlaunched = 0; + goto done; + } + if ((checkin_response = launch_msg(checkin_request)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "launch_msg fails.\n"); + launchdlaunched = 0; + goto done; + } + if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { + plog(LLV_ERROR, LOCATION, NULL, + "launch_data_get_type fails errno %d.\n", launch_data_get_errno(checkin_response)); + launchdlaunched = 0; + goto done; + } + +done: + /* clean up before we leave */ + if ( checkin_request ) + launch_data_free(checkin_request); + if ( checkin_response ) + launch_data_free(checkin_response); + return launchdlaunched; +} + static void cleanup_pidfile() { @@ -300,12 +429,12 @@ cleanup_pidfile() /* if it's not child process, clean everything */ if (racoon_pid == p) { if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) - strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN); + strlcpy(pid_file, _PATH_VARRUN "racoon.pid", sizeof(pid_file)); else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') - strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); + strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file)); else { - strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN); - strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); + strlcat(pid_file, _PATH_VARRUN, sizeof(pid_file)); + strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file)); } (void) unlink(pid_file); } @@ -335,7 +464,7 @@ parse(ac, av) plogset("/tmp/racoon.log"); #endif - while ((c = getopt(ac, av, "dLFp:P:a:f:l:veZBCx" + while ((c = getopt(ac, av, "dLFp:P:a:f:l:vsZBCx" #ifdef YYDEBUG "y" #endif @@ -378,8 +507,8 @@ parse(ac, av) case 'v': vflag++; break; - case 'e': - lcconf->auto_exit_state |= LC_AUTOEXITSTATE_CLIENT; + case 's': + lcconf->auto_exit_state &= ~LC_AUTOEXITSTATE_CLIENT; /* override default auto exit state */ break; case 'x': exec_done = 1; diff --git a/ipsec-tools/racoon/misc.h b/ipsec-tools/racoon/misc.h index 8f90cc9..cb33533 100644 --- a/ipsec-tools/racoon/misc.h +++ b/ipsec-tools/racoon/misc.h @@ -1,4 +1,6 @@ -/* $Id: misc.h,v 1.6.10.1 2005/11/06 17:18:26 monas Exp $ */ +/* $NetBSD: misc.h,v 1.4 2006/09/09 16:22:09 manu Exp $ */ + +/* Id: misc.h,v 1.9 2006/04/06 14:00:06 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -47,15 +49,26 @@ extern const char *debug_location __P((const char *, int, const char *)); extern int getfsize __P((char *)); struct timeval; extern double timedelta __P((struct timeval *, struct timeval *)); +char *strdup __P((const char *)); -#ifndef HAVE_STRLCPY -#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0') +#if defined(__APPLE__) +#define RACOON_TAILQ_FOREACH_REVERSE(var, head, headname ,field) \ + TAILQ_FOREACH_REVERSE(var, head, field, headname) +#else +#define RACOON_TAILQ_FOREACH_REVERSE(var, head, headname ,field) \ + TAILQ_FOREACH_REVERSE(var, head, headname, field) #endif -#ifndef HAVE_STRLCAT -#define strlcat(d,s,l) strncat(d,s,(l)-strlen(d)-1) -#endif +#define STRDUP_FATAL(x) if (x == NULL) { \ + plog(LLV_ERROR, LOCATION, NULL, "strdup failed\n"); \ + exit(1); \ +} #include "libpfkey.h" +#define remainingsize(string_buffer_sizeof, filled_str) (string_buffer_sizeof - strlen(filled_str) - 1) +#define remainingsize_opt(string_buffer_sizeof, filled_strlen) (string_buffer_sizeof - filled_strlen - 1) +#define remainingsizeof(string_buffer) (sizeof(string_buffer) - strlen(string_buffer) - 1) +#define remainingsizeof_opt(string_buffer, filled_strlen) (sizeof(string_buffer) - filled_strlen - 1) + #endif /* _MISC_H */ diff --git a/ipsec-tools/racoon/nattraversal.c b/ipsec-tools/racoon/nattraversal.c index a9c02b1..4bd1f1f 100644 --- a/ipsec-tools/racoon/nattraversal.c +++ b/ipsec-tools/racoon/nattraversal.c @@ -65,6 +65,7 @@ #include "schedule.h" #include "nattraversal.h" #include "grabmyaddr.h" +#include "ike_session.h" struct natt_ka_addrs { struct sockaddr *src; @@ -220,6 +221,9 @@ natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received, verified = 1; } + if (iph1->parent_session) + iph1->parent_session->natt_flags = iph1->natt_flags; + vfree (natd_computed); return verified; @@ -300,98 +304,110 @@ natt_fill_options (struct ph1natt_options *opts, int version) return 0; } -#ifdef NOT_NOW -static int +int create_natoa_payloads(struct ph2handle *iph2, vchar_t **natoa_i, vchar_t **natoa_r) { int natoa_type = 0; - int natt_type; vchar_t *i; vchar_t *r; u_int8_t *p; - size_t src_size; - size_t dst_size; + struct sockaddr *i_addr; + struct sockaddr *r_addr; + size_t i_size; + size_t r_size; *natoa_i = *natoa_r = NULL; /* create natoa payloads if natt being used */ /* don't send if type == apple */ - if ((natt_type = natd_hasnat(iph2->ph1)) != 0) - if (natt_type == natt_type_rfc) - natoa_type = ISAKMP_NPTYPE_NATOA_RFC; - else if (natt_type == natt_type_02 || natt_type == natt_type_02N) - natoa_type = ISAKMP_NPTYPE_NATOA_DRAFT; - + if (!iph2->ph1->natt_options) + return 0; + + natoa_type = iph2->ph1->natt_options->payload_nat_oa; if (natoa_type == 0) return 0; - - switch (iph2->src->sa_family) { + + if (iph2->side == INITIATOR) { + i_addr = iph2->src; + r_addr = iph2->dst; + } else { + i_addr = iph2->dst; + r_addr = iph2->src; + } + + switch (i_addr->sa_family) { case AF_INET: - src_size = sizeof(in_addr_t); + i_size = sizeof(in_addr_t); break; #ifdef INET6 case AF_INET6: - src_size = sizeof(struct in6_addr); + i_size = sizeof(struct in6_addr); break; #endif default: plog(LLV_ERROR, LOCATION, NULL, - "invalid address family: %d\n", iph2->src->sa_family); + "invalid address family: %d\n", i_addr->sa_family); return -1; } - - switch (iph2->dst->sa_family) { + + switch (r_addr->sa_family) { case AF_INET: - dst_size = sizeof(in_addr_t); + r_size = sizeof(in_addr_t); break; #ifdef INET6 case AF_INET6: - dst_size = sizeof(struct in6_addr); + r_size = sizeof(struct in6_addr); break; #endif default: plog(LLV_ERROR, LOCATION, NULL, - "invalid address family: %d\n", iph2->dst->sa_family); + "invalid address family: %d\n", r_addr->sa_family); return -1; } - i = vmalloc(sizeof(struct isakmp_pl_natoa) + src_size - sizeof(struct isakmp_gen)); - r = vmalloc(sizeof(struct isakmp_pl_natoa) + dst_size - sizeof(struct isakmp_gen)); - if (i == NULL || r == NULL) { + i = vmalloc(sizeof(struct isakmp_pl_natoa) + i_size - sizeof(struct isakmp_gen)); + if (i == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get buffer for natoa payload.\n"); + return -1; + } + r = vmalloc(sizeof(struct isakmp_pl_natoa) + r_size - sizeof(struct isakmp_gen)); + if (r == NULL) { + vfree(i); plog(LLV_ERROR, LOCATION, NULL, "failed to get buffer for natoa payload.\n"); return -1; } /* copy src address */ - p = i->v; + p = (__typeof__(p))i->v; - switch (iph2->src->sa_family) { + switch (i_addr->sa_family) { case AF_INET: *p = IPSECDOI_ID_IPV4_ADDR; - bcopy(&(((struct sockaddr_in *)iph2->src)->sin_addr.s_addr), p + sizeof(u_int32_t), src_size); + bcopy(&(((struct sockaddr_in *)i_addr)->sin_addr.s_addr), p + sizeof(u_int32_t), i_size); break; #ifdef INET6 case AF_INET6: *p = IPSECDOI_ID_IPV6_ADDR; - bcopy(&(((struct sockaddr_in6 *)iph2->src)->sin6_addr), p + sizeof(u_int32_t), src_size); + bcopy(&(((struct sockaddr_in6 *)i_addr)->sin6_addr), p + sizeof(u_int32_t), i_size); break; #endif } /* copy dst address */ - p = r->v; + p = (__typeof__(p))r->v; - switch (iph2->dst->sa_family) { + switch (r_addr->sa_family) { case AF_INET: *p = IPSECDOI_ID_IPV4_ADDR; - bcopy(&(((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr), p + sizeof(u_int32_t), dst_size); + bcopy(&(((struct sockaddr_in *)r_addr)->sin_addr.s_addr), p + sizeof(u_int32_t), r_size); break; #ifdef INET6 case AF_INET6: *p = IPSECDOI_ID_IPV6_ADDR; - bcopy(&(((struct sockaddr_in6 *)iph2->dst)->sin6_addr), p + sizeof(u_int32_t), dst_size); + bcopy(&(((struct sockaddr_in6 *)r_addr)->sin6_addr), p + sizeof(u_int32_t), r_size); break; #endif } @@ -400,8 +416,49 @@ create_natoa_payloads(struct ph2handle *iph2, vchar_t **natoa_i, vchar_t **natoa *natoa_r = r; return natoa_type; } -#endif - + +struct sockaddr * +process_natoa_payload(vchar_t *buf) +{ + struct sockaddr *saddr = NULL; + struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)buf->v; + + switch (id_b->type) { + case IPSECDOI_ID_IPV4_ADDR: + saddr = racoon_malloc(sizeof(struct sockaddr_in)); + if (!saddr) { + plog(LLV_ERROR, LOCATION, NULL, + "error allocating addr for NAT-OA payload\n"); + return NULL; + } + saddr->sa_len = sizeof(struct sockaddr_in); + saddr->sa_family = AF_INET; + ((struct sockaddr_in *)saddr)->sin_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in *)saddr)->sin_addr, + buf->v + sizeof(*id_b), sizeof(struct in_addr)); + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + saddr = racoon_malloc(sizeof(struct sockaddr_in6)); + if (!saddr) { + plog(LLV_ERROR, LOCATION, NULL, + "error allocating addr for NAT-OA payload\n"); + return NULL; + } + saddr->sa_len = sizeof(struct sockaddr_in6); + saddr->sa_family = AF_INET6; + ((struct sockaddr_in6 *)saddr)->sin6_port = IPSEC_PORT_ANY; + memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr, + buf->v + sizeof(*id_b), sizeof(struct in6_addr)); + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid NAT-OA payload %d\n", id_b->type); + return NULL; + } + return saddr; +} void natt_float_ports (struct ph1handle *iph1) @@ -429,7 +486,8 @@ natt_float_ports (struct ph1handle *iph1) set_port (iph1->remote, iph1->natt_options->float_port); iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER; - + ike_session_ikev1_float_ports(iph1); + #ifndef __APPLE__ natt_keepalive_add_ph1 (iph1); #endif @@ -516,8 +574,16 @@ natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst) return -1; } - new_addr->src = dupsaddr(src); - new_addr->dst = dupsaddr(dst); + if ((new_addr->src = dupsaddr(src)) == NULL) { + racoon_free(new_addr); + plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); + return -1; + } + if ((new_addr->dst = dupsaddr(dst)) == NULL) { + racoon_free(new_addr); + plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); + return -1; + } new_addr->in_use = 1; TAILQ_INSERT_TAIL(&ka_tree, new_addr, chain); diff --git a/ipsec-tools/racoon/nattraversal.h b/ipsec-tools/racoon/nattraversal.h index f03c76c..693fc40 100644 --- a/ipsec-tools/racoon/nattraversal.h +++ b/ipsec-tools/racoon/nattraversal.h @@ -51,6 +51,19 @@ #define NON_ESP_MARKER_LEN sizeof(u_int32_t) #define NON_ESP_MARKER_USE(iph1) ((iph1)->natt_flags & NAT_ADD_NON_ESP_MARKER) +#ifdef ENABLE_NATT +#ifdef ENABLE_FRAG +#define PH1_NON_ESP_EXTRA_LEN(iph1) ((iph1->frag && iph1->sendbuf->l > ISAKMP_FRAG_MAXLEN) ? 0: (NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0)) +#define PH2_NON_ESP_EXTRA_LEN(iph2) ((iph2->ph1->frag && iph2->sendbuf->l > ISAKMP_FRAG_MAXLEN) ? 0: (NON_ESP_MARKER_USE(iph2->ph1) ? NON_ESP_MARKER_LEN : 0)) +#else +#define PH1_NON_ESP_EXTRA_LEN(iph1) (NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0) +#define PH2_NON_ESP_EXTRA_LEN(iph2) (NON_ESP_MARKER_USE(iph2->ph1) ? NON_ESP_MARKER_LEN : 0) +#endif +#else +#define PH1_NON_ESP_EXTRA_LEN(iph1) 0 +#define PH2_NON_ESP_EXTRA_LEN(iph2) 0 +#endif + /* These are the values from parsing "remote {}" block of the config file. */ #define NATT_OFF FALSE /* = 0 */ @@ -83,9 +96,8 @@ int natt_udp_encap (int encmode); int natt_fill_options (struct ph1natt_options *opts, int version); void natt_float_ports (struct ph1handle *iph1); void natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric); -#ifdef NOT_NOW int create_natoa_payloads(struct ph2handle *iph2, vchar_t **, vchar_t **); -#endif +struct sockaddr * process_natoa_payload(vchar_t *buf); struct payload_list * isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]); diff --git a/ipsec-tools/racoon/oakley.c b/ipsec-tools/racoon/oakley.c index 1d52885..9ab26f9 100644 --- a/ipsec-tools/racoon/oakley.c +++ b/ipsec-tools/racoon/oakley.c @@ -1,4 +1,6 @@ -/* $Id: oakley.c,v 1.17.2.5 2005/10/04 09:54:27 manubsd Exp $ */ +/* $NetBSD: oakley.c,v 1.9.6.2 2007/04/04 13:08:28 vanhu Exp $ */ + +/* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -36,13 +38,15 @@ #include /* XXX for subjectaltname */ #include /* XXX for subjectaltname */ -#include #include +#include #include #include #include #include +#include +#include #if TIME_WITH_SYS_TIME # include @@ -54,6 +58,9 @@ # include # endif #endif +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -72,7 +79,6 @@ #include "admin.h" #include "privsep.h" #include "localconf.h" -#include "remoteconf.h" #include "policy.h" #include "handler.h" #include "ipsec_doi.h" @@ -83,17 +89,19 @@ #include "crypto_openssl.h" #ifdef __APPLE__ #include "crypto_cssm.h" +#if HAVE_OPENDIR #include "open_dir.h" #endif +#endif #include "dnssec.h" #include "sockmisc.h" #include "strnames.h" #include "gcmalloc.h" #include "rsalist.h" #ifdef __APPLE__ -#include +#include #endif - +#include "remoteconf.h" #ifdef HAVE_GSSAPI #include "gssapi.h" @@ -610,6 +618,7 @@ oakley_compute_keymat_x(iph2, side, sa_dir) while (dupkeymat--) { vchar_t *this = NULL; /* Kn */ + int update_prev; memcpy(seed->v, prev->v, prev->l); memcpy(seed->v + prev->l, buf->v, buf->l); @@ -625,8 +634,14 @@ oakley_compute_keymat_x(iph2, side, sa_dir) goto end; } + update_prev = (prev && prev == res) ? 1 : 0; + l = res->l; res = vrealloc(res, l + this->l); + + if (update_prev) + prev = res; + if (res == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to get keymat buffer.\n"); @@ -868,7 +883,7 @@ oakley_ph1hash_common(iph1, sw) + (sw == GENERATE ? iph1->id->l : iph1->id_p->l); #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { if (iph1->gi_i != NULL && iph1->gi_r != NULL) { bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r); len += bp->l; @@ -929,7 +944,7 @@ oakley_ph1hash_common(iph1, sw) p += bp->l; #ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { + if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { if (iph1->gi_i != NULL && iph1->gi_r != NULL) { bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r); memcpy(p, bp->v, bp->l); @@ -950,7 +965,8 @@ oakley_ph1hash_common(iph1, sw) error = 0; - plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH (%s) computed:\n", + iph1->side == INITIATOR ? "init" : "resp"); plogdump(LLV_DEBUG, res->v, res->l); end: @@ -989,10 +1005,18 @@ oakley_ph1hash_base_i(iph1, sw) return NULL; } - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif if (iph1->skeyid == NULL) { plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n"); return NULL; @@ -1002,12 +1026,18 @@ oakley_ph1hash_base_i(iph1, sw) case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef HAVE_GSSAPI case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: +#endif #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: #endif /* make hash for seed */ len = iph1->nonce->l + iph1->nonce_p->l; @@ -1115,16 +1145,28 @@ oakley_ph1hash_base_r(iph1, sw) "invalid etype for this hash function\n"); return NULL; } - if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG + + switch(AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: #endif - && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG) { + break; + default: plog(LLV_ERROR, LOCATION, NULL, "not supported authentication method %d\n", iph1->approval->authmethod); return NULL; + break; } /* make hash for seed */ @@ -1186,7 +1228,7 @@ oakley_ph1hash_base_r(iph1, sw) memcpy(p, bp->v, bp->l); p += bp->l; - plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH_R with:\n"); plogdump(LLV_DEBUG, buf->v, buf->l); /* compute HASH */ @@ -1196,7 +1238,7 @@ oakley_ph1hash_base_r(iph1, sw) error = 0; - plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH_R computed:\n"); plogdump(LLV_DEBUG, res->v, res->l); end: @@ -1231,8 +1273,13 @@ oakley_validate_auth(iph1) #ifdef ENABLE_STATS gettimeofday(&start, NULL); #endif - switch (iph1->approval->authmethod) { + + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif /* validate HASH */ { char *r_hash; @@ -1242,10 +1289,20 @@ oakley_validate_auth(iph1) "few isakmp message received.\n"); return ISAKMP_NTYPE_PAYLOAD_MALFORMED; } - +#ifdef ENABLE_HYBRID + if (AUTHMETHOD(iph1) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I && + ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0)) + { + plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, " + "hybrid auth is enabled, " + "but peer is no Xauth compliant\n"); + return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED; + break; + } +#endif r_hash = (caddr_t)(iph1->pl_hash + 1); - plog(LLV_DEBUG, LOCATION, NULL, "HASH received:"); + plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n"); plogdump(LLV_DEBUG, r_hash, ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash)); @@ -1282,8 +1339,12 @@ oakley_validate_auth(iph1) case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: #endif { int error = 0; @@ -1380,10 +1441,13 @@ oakley_validate_auth(iph1) /* check configured peers identifier against cert IDs */ /* allows checking of specified ID against multiple ids in the cert */ /* such as multiple domain names */ +#if !TARGET_OS_EMBEDDED if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER && (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_RMCONFIG)) != 0) return error; +#endif +#if HAVE_OPENDIR /* check cert common name against Open Directory authentication group */ if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_OPEN_DIR) { @@ -1405,16 +1469,17 @@ oakley_validate_auth(iph1) return ISAKMP_NTYPE_AUTHENTICATION_FAILED; } } -#endif +#endif /* HAVE_OPENDIR */ +#endif /* __APPLE__ */ /* verify certificate */ if (iph1->rmconf->verify_cert && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) { certtype = iph1->rmconf->certtype; #ifdef ENABLE_HYBRID - switch (iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: certtype = iph1->cert_p->type; break; default: @@ -1423,11 +1488,49 @@ oakley_validate_auth(iph1) #endif switch (certtype) { case ISAKMP_CERT_X509SIGN: + +#if TARGET_OS_EMBEDDED + { + /* use ID from remote configuration */ + /* check each ID in list */ + struct idspec *id_spec; + CFStringRef hostname = NULL; + char *peers_id; + struct genlist_entry *gpb = NULL; + + if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER) { + id_spec = genlist_next(iph1->rmconf->idvl_p, &gpb); /* expect only one id */ + if (id_spec->idtype == IDTYPE_ADDRESS) { + switch (((struct sockaddr *)(id_spec->id->v))->sa_family) { + case AF_INET: + peers_id = inet_ntoa(((struct sockaddr_in *)(id_spec->id->v))->sin_addr); + hostname = CFStringCreateWithCString(NULL, peers_id, kCFStringEncodingUTF8); + break; +#ifdef INET6 + case AF_INET6: + return ISAKMP_NTYPE_INVALID_ID_INFORMATION; /* not currently supported for embedded */ + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "unknown address type for peers identifier.\n"); + return ISAKMP_NTYPE_AUTHENTICATION_FAILED; + break; + } + } else + hostname = CFStringCreateWithBytes(NULL, (u_int8_t *)id_spec->id->v, id_spec->id->l, kCFStringEncodingUTF8, FALSE); + } + error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, hostname); + if (hostname) + CFRelease(hostname); + } + +#else /* TARGET_OS_EMBEDDED */ #ifdef __APPLE__ if (iph1->rmconf->cert_verification == VERIFICATION_MODULE_SEC_FRAMEWORK) - error = crypto_cssm_check_x509cert(&iph1->cert_p->cert); + error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, NULL); else -#endif +#endif /* __APPLE__ */ { char path[MAXPATHLEN]; char *ca; @@ -1445,6 +1548,7 @@ oakley_validate_auth(iph1) lcconf->pathinfo[LC_PATHTYPE_CERT], ca, 0); } +#endif /* TARGET_OS_EMBEDDED */ break; default: @@ -1459,7 +1563,6 @@ oakley_validate_auth(iph1) } } - plog(LLV_DEBUG, LOCATION, NULL, "CERT validated\n"); /* compute hash */ @@ -1485,9 +1588,9 @@ oakley_validate_auth(iph1) certtype = iph1->rmconf->certtype; #ifdef ENABLE_HYBRID - switch (iph1->approval->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + switch (AUTHMETHOD(iph1)) { + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: certtype = iph1->cert_p->type; break; default: @@ -1526,8 +1629,8 @@ oakley_validate_auth(iph1) } break; #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: { if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, " @@ -1545,6 +1648,11 @@ oakley_validate_auth(iph1) #endif #ifdef HAVE_GSSAPI case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: + /* check if we're not into XAUTH_PSKEY_I instead */ +#ifdef ENABLE_HYBRID + if (iph1->rmconf->xauth) + break; +#endif switch (iph1->etype) { case ISAKMP_ETYPE_IDENT: case ISAKMP_ETYPE_AGG: @@ -1582,6 +1690,12 @@ oakley_validate_auth(iph1) #endif case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif if (iph1->id_p == NULL || iph1->pl_hash == NULL) { plog(LLV_ERROR, LOCATION, iph1->remote, "few isakmp message received.\n"); @@ -1670,11 +1784,11 @@ get_cert_fromlocal(iph1, my) switch (iph1->rmconf->certtype) { case ISAKMP_CERT_X509SIGN: -#ifdef __APPLE__ +#if defined(__APPLE__) if (iph1->rmconf->identity_in_keychain) { CFDataRef dataRef; - if (base64toCFData(iph1->rmconf->keychainCertRef, &dataRef)) + if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef)) goto end; cert = crypto_cssm_get_x509cert(dataRef); CFRelease(dataRef); @@ -1750,28 +1864,39 @@ get_plainrsa_fromlocal(iph1, my) int error = -1; iph1->rsa_candidates = rsa_lookup_keys(iph1, my); - if (!iph1->rsa_candidates || rsa_list_count(iph1->rsa_candidates) == 0) { + if (!iph1->rsa_candidates || + rsa_list_count(iph1->rsa_candidates) == 0) { plog(LLV_ERROR, LOCATION, NULL, "%s RSA key not found for %s\n", my ? "Private" : "Public", - saddr2str_fromto("%s <-> %s", iph1->local, iph1->remote)); + saddr2str_fromto("%s <-> %s", + iph1->local, iph1->remote)); goto end; } if (my && rsa_list_count(iph1->rsa_candidates) > 1) { plog(LLV_WARNING, LOCATION, NULL, - "More than one (=%lu) private PlainRSA key found for %s\n", + "More than one (=%lu) private " + "PlainRSA key found for %s\n", rsa_list_count(iph1->rsa_candidates), - saddr2str_fromto("%s <-> %s", iph1->local, iph1->remote)); + saddr2str_fromto("%s <-> %s", + iph1->local, iph1->remote)); plog(LLV_WARNING, LOCATION, NULL, - "This may have unpredictable results, i.e. wrong key could be used!\n"); + "This may have unpredictable results, " + "i.e. wrong key could be used!\n"); plog(LLV_WARNING, LOCATION, NULL, - "Consider using only one single private key for all peers...\n"); + "Consider using only one single private " + "key for all peers...\n"); } if (my) { - iph1->rsa = ((struct rsa_key *)genlist_next(iph1->rsa_candidates, NULL))->rsa; + iph1->rsa = ((struct rsa_key *) + genlist_next(iph1->rsa_candidates, NULL))->rsa; + genlist_free(iph1->rsa_candidates, NULL); iph1->rsa_candidates = NULL; + + if (iph1->rsa == NULL) + goto end; } error = 0; @@ -1791,12 +1916,12 @@ oakley_getsign(iph1) switch (iph1->rmconf->certtype) { case ISAKMP_CERT_X509SIGN: -#ifdef __APPLE__ +#if defined(__APPLE__) // cert in keychain - use cssm to sign if (iph1->rmconf->identity_in_keychain) { CFDataRef dataRef; - if (base64toCFData(iph1->rmconf->keychainCertRef, &dataRef)) + if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef)) goto end; iph1->sig = crypto_cssm_getsign(dataRef, iph1->hash); CFRelease(dataRef); @@ -2121,7 +2246,9 @@ oakley_check_certid(iph1) vfree(name); if (error != 0) { plog(LLV_ERROR, LOCATION, NULL, - "ID mismatched with subjectAltName.\n"); + "ID mismatched with ASN1 SubjectName.\n"); + plogdump(LLV_DEBUG, id_b + 1, idlen); + plogdump(LLV_DEBUG, name->v, idlen); return ISAKMP_NTYPE_INVALID_ID_INFORMATION; } return 0; @@ -2192,6 +2319,8 @@ oakley_check_certid(iph1) if (error != 0) { plog(LLV_ERROR, LOCATION, NULL, "ID mismatched with subjectAltName.\n"); + plogdump(LLV_DEBUG, id_b + 1, idlen); + plogdump(LLV_DEBUG, a, idlen); return ISAKMP_NTYPE_INVALID_ID_INFORMATION; } return 0; @@ -2240,6 +2369,8 @@ oakley_check_certid(iph1) error = memcmp(id_b + 1, altname, idlen); if (error) { plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n"); + plogdump(LLV_DEBUG, id_b + 1, idlen); + plogdump(LLV_DEBUG, altname, idlen); racoon_free(altname); return ISAKMP_NTYPE_INVALID_ID_INFORMATION; } @@ -2538,6 +2669,12 @@ save_certbuf(gen) { cert_t *new; + if(ntohs(gen->len) <= sizeof(*gen)){ + plog(LLV_ERROR, LOCATION, NULL, + "Len is too small !!.\n"); + return NULL; + } + new = oakley_newcert(); if (!new) { plog(LLV_ERROR, LOCATION, NULL, @@ -2613,10 +2750,15 @@ oakley_getcr(iph1) "failed to get cr buffer\n"); return NULL; } - buf->v[0] = iph1->rmconf->certtype; - - plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n", + if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) { + buf->v[0] = iph1->rmconf->cacerttype; + plog(LLV_DEBUG, LOCATION, NULL, "create my CR: NONE, using %s instead\n", + s_isakmp_certtype(iph1->rmconf->cacerttype)); + } else { + buf->v[0] = iph1->rmconf->certtype; + plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n", s_isakmp_certtype(iph1->rmconf->certtype)); + } if (buf->l > 1) plogdump(LLV_DEBUG, buf->v, buf->l); @@ -2660,6 +2802,10 @@ oakley_needcr(type) #ifdef ENABLE_HYBRID case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: #endif return 1; default: @@ -2685,8 +2831,12 @@ oakley_skeyid(iph1) int error = -1; /* SKEYID */ - switch(iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif #ifdef __APPLE__ if (iph1->rmconf->shared_secret) { @@ -2695,6 +2845,7 @@ oakley_skeyid(iph1) /* in psk file - use KEY from remote configuration to locate it */ iph1->authstr = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1); break; +#if HAVE_KEYCHAIN case SECRETTYPE_KEYCHAIN: /* in the system keychain */ iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, NULL); @@ -2703,6 +2854,7 @@ oakley_skeyid(iph1) /* in the system keychain - use peer id */ iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, iph1->id_p); break; +#endif HAVE_KEYCHAIN case SECRETTYPE_USE: /* in the remote configuration */ default: @@ -2778,6 +2930,10 @@ oakley_skeyid(iph1) case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: #endif #ifdef HAVE_GSSAPI case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: @@ -2809,6 +2965,12 @@ oakley_skeyid(iph1) break; case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif plog(LLV_WARNING, LOCATION, NULL, "not supported authentication method %s\n", s_oakley_attr_method(iph1->approval->authmethod)); @@ -2878,7 +3040,7 @@ oakley_skeyid_dae(iph1) buf = NULL; plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n"); - plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid->l); + plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l); /* SKEYID A */ /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */ @@ -3191,6 +3353,9 @@ oakley_newiv(iph1) plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n"); plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l); + if (iph1->ivm != NULL) + oakley_delivm(iph1->ivm); + iph1->ivm = newivm; return 0; @@ -3290,6 +3455,7 @@ oakley_delivm(ivm) if (ivm->ive != NULL) vfree(ivm->ive); racoon_free(ivm); + plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n"); return; } diff --git a/ipsec-tools/racoon/oakley.h b/ipsec-tools/racoon/oakley.h index 66edfef..5916b16 100644 --- a/ipsec-tools/racoon/oakley.h +++ b/ipsec-tools/racoon/oakley.h @@ -1,4 +1,6 @@ -/* $Id: oakley.h,v 1.9 2004/10/24 17:37:00 manubsd Exp $ */ +/* $NetBSD: oakley.h,v 1.5 2006/10/06 12:02:27 manu Exp $ */ + +/* Id: oakley.h,v 1.13 2005/05/30 20:12:43 fredsen Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -73,7 +75,7 @@ /* 65001 - 65535 Private Use */ - /* Plain Xauth, Not implemented */ + /* Plain Xauth */ #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I 65001 #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R 65002 #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I 65003 @@ -86,6 +88,12 @@ #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R 65010 #endif + /* 65500 -> still private + * to avoid clash with GSSAPI_KRB below + */ +#define FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I 65500 + + /* * The following are valid when the Vendor ID is one of * the following: @@ -215,4 +223,20 @@ extern vchar_t *oakley_do_decrypt __P((struct ph1handle *, extern vchar_t *oakley_do_encrypt __P((struct ph1handle *, vchar_t *, vchar_t *, vchar_t *)); +#ifdef ENABLE_HYBRID +#define AUTHMETHOD(iph1) \ + (((iph1)->rmconf->xauth && \ + (iph1)->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ? \ + FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I : (iph1)->approval->authmethod) +#define RMAUTHMETHOD(iph1) \ + (((iph1)->rmconf->xauth && \ + (iph1)->rmconf->proposal->authmethod == \ + OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ? \ + FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I : \ + (iph1)->rmconf->proposal->authmethod) +#else +#define AUTHMETHOD(iph1) (iph1)->approval->authmethod +#define RMAUTHMETHOD(iph1) (iph1)->rmconf->proposal->authmethod +#endif /* ENABLE_HYBRID */ + #endif /* _OAKLEY_H */ diff --git a/ipsec-tools/racoon/pfkey.h b/ipsec-tools/racoon/pfkey.h index 63d7498..f434b80 100644 --- a/ipsec-tools/racoon/pfkey.h +++ b/ipsec-tools/racoon/pfkey.h @@ -32,6 +32,8 @@ #ifndef _PFKEY_H #define _PFKEY_H +#include "ike_session.h" + struct pfkey_satype { u_int8_t ps_satype; const char *ps_name; @@ -58,6 +60,8 @@ extern int pk_sendeacquire __P((struct ph2handle *)); extern int pk_sendspdupdate2 __P((struct ph2handle *)); extern int pk_sendspdadd2 __P((struct ph2handle *)); extern int pk_sendspddelete __P((struct ph2handle *)); +extern int pk_sendget_inbound_sastats __P((ike_session_t *)); +extern int pk_sendget_outbound_sastats __P((ike_session_t *)); extern void pfkey_timeover_stub __P((void *)); extern void pfkey_timeover __P((struct ph2handle *)); diff --git a/ipsec-tools/racoon/pfkey_racoon.c b/ipsec-tools/racoon/pfkey_racoon.c index 03e70b4..390cb19 100644 --- a/ipsec-tools/racoon/pfkey_racoon.c +++ b/ipsec-tools/racoon/pfkey_racoon.c @@ -105,6 +105,9 @@ #include "grabmyaddr.h" #include "vpn_control.h" #include "vpn_control_var.h" +#include "ike_session.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC) #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC @@ -133,6 +136,7 @@ static int pk_recvspdexpire __P((caddr_t *)); static int pk_recvspdget __P((caddr_t *)); static int pk_recvspddump __P((caddr_t *)); static int pk_recvspdflush __P((caddr_t *)); +static int pk_recvgetsastat __P((caddr_t *)); static struct sadb_msg *pk_recv __P((int, int *)); static int (*pkrecvf[]) __P((caddr_t *)) = { @@ -159,9 +163,10 @@ pk_recvspdflush, NULL, /* SADB_X_SPDSETIDX */ pk_recvspdexpire, NULL, /* SADB_X_SPDDELETE2 */ +pk_recvgetsastat, /* SADB_GETSASTAT */ NULL, /* SADB_X_NAT_T_NEW_MAPPING */ NULL, /* SADB_X_MIGRATE */ -#if (SADB_MAX > 24) +#if (SADB_MAX > 25) #error "SADB extra message?" #endif }; @@ -191,7 +196,6 @@ static int addnewsp __P((caddr_t *)); #endif #endif - int pfkey_process(msg) struct sadb_msg *msg; @@ -1001,6 +1005,19 @@ pk_recvgetspi(mhp) return -1; } + // check the underlying iph2->ph1 + if (!iph2->ph1) { + if (!ike_session_update_ph2_ph1bind(iph2)) { + plog(LLV_ERROR, LOCATION, NULL, + "can't proceed with getspi for %s. no suitable ISAKMP-SA found \n", + saddrwop2str(iph2->dst)); + unbindph12(iph2); + remph2(iph2); + delph2(iph2); + return -1; + } + } + /* set SPI, and check to get all spi whether or not */ allspiok = 1; notfound = 1; @@ -1026,6 +1043,9 @@ pk_recvgetspi(mhp) plog(LLV_ERROR, LOCATION, NULL, "get spi for unknown address %s\n", saddrwop2str(iph2->dst)); + unbindph12(iph2); + remph2(iph2); + delph2(iph2); return -1; } @@ -1129,8 +1149,10 @@ pk_sendupdate(iph2) memset (&natt, 0, sizeof (natt)); natt.sport = extract_port (iph2->ph1->remote); flags |= SADB_X_EXT_NATT; - if (iph2->ph1->natt_flags & NAT_DETECTED_ME) - flags |= SADB_X_EXT_NATT_KEEPALIVE; + if (iph2->ph1->natt_flags & NAT_DETECTED_ME) { + if (iph2->ph1->rmconf->natt_keepalive == TRUE) + flags |= SADB_X_EXT_NATT_KEEPALIVE; + } else if (iph2->ph1->rmconf->natt_multiple_user == TRUE && mode == IPSEC_MODE_TRANSPORT && src->sa_family == AF_INET) @@ -1370,6 +1392,20 @@ pk_recvupdate(mhp) /* update status */ iph2->status = PHASE2ST_ESTABLISHED; + if (iph2->side == INITIATOR) { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC, + CONSTSTR("Initiator, Quick-Mode"), + CONSTSTR(NULL)); + } else { + IPSECSESSIONTRACEREVENT(iph2->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC, + CONSTSTR("Responder, Quick-Mode"), + CONSTSTR(NULL)); + } + + ike_session_ph2_established(iph2); + #ifdef ENABLE_STATS gettimeofday(&iph2->end, NULL); syslog(LOG_NOTICE, "%s(%s): %8.6f", @@ -1480,8 +1516,10 @@ pk_sendadd(iph2) memset (&natt, 0, sizeof (natt)); natt.dport = extract_port (iph2->ph1->remote); flags |= SADB_X_EXT_NATT; - if (iph2->ph1->natt_flags & NAT_DETECTED_ME) - flags |= SADB_X_EXT_NATT_KEEPALIVE; + if (iph2->ph1->natt_flags & NAT_DETECTED_ME) { + if (iph2->ph1->rmconf->natt_keepalive == TRUE) + flags |= SADB_X_EXT_NATT_KEEPALIVE; + } else if (iph2->ph1->rmconf->natt_multiple_user == TRUE && mode == IPSEC_MODE_TRANSPORT && dst->sa_family == AF_INET) @@ -1696,6 +1734,8 @@ pk_recvadd(mhp) sadbsecas2str(iph2->src, iph2->dst, msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode)); + ike_session_cleanup_other_established_ph2s(iph2->parent_session, iph2); + #ifdef ENABLE_VPNCONTROL_PORT { u_int32_t address; @@ -1788,9 +1828,10 @@ pk_recvexpire(mhp) iph2->status = PHASE2ST_EXPIRED; - /* INITIATOR, begin phase 2 exchange. */ + /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */ /* allocate buffer for status management of pfkey message */ - if (iph2->side == INITIATOR) { + if (iph2->side == INITIATOR && + !ike_session_has_other_established_ph2(iph2->parent_session, iph2)) { initph2(iph2); @@ -1801,7 +1842,7 @@ pk_recvexpire(mhp) if (isakmp_post_acquire(iph2) < 0) { plog(LLV_ERROR, LOCATION, iph2->dst, "failed to begin ipsec sa " - "re-negotication.\n"); + "re-negotiation.\n"); unbindph12(iph2); remph2(iph2); delph2(iph2); @@ -1912,8 +1953,8 @@ pk_recvacquire(mhp) * should ignore such a acquire message because the phase 2 * is just negotiating. * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon - * has to prcesss such a acquire message because racoon may - * lost the expire message. + * has to process such a acquire message because racoon may + * have lost the expire message. */ iph2[0] = getph2byid(src, dst, xpl->sadb_x_policy_id); if (iph2[0] != NULL) { @@ -2025,6 +2066,15 @@ pk_recvacquire(mhp) return -1; /* XXX should use the algorithm list from register message */ } +#ifdef __APPLE__ + if (link_sainfo_to_ph2(iph2[n]->sainfo) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to link sainfo\n"); + iph2[n]->sainfo = NULL; + delph2(iph2[n]); + return -1; + } +#endif } if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) { @@ -2039,10 +2089,19 @@ pk_recvacquire(mhp) /* XXX should be looped if there are multiple phase 2 handler. */ if (isakmp_post_acquire(iph2[n]) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "failed to begin ipsec sa negotication.\n"); + "failed to begin ipsec sa negotiation.\n"); goto err; } + +#if !TARGET_OS_EMBEDDED + if ( lcconf->vt == NULL){ + if (!(lcconf->vt = vproc_transaction_begin(NULL))) + plog(LLV_ERROR, LOCATION, NULL, + "vproc_transaction_begin returns NULL.\n"); + } +#endif + return 0; err: @@ -2072,7 +2131,6 @@ pk_recvdelete(mhp) /* sanity check */ if (mhp[0] == NULL - || mhp[SADB_EXT_SA] == NULL || mhp[SADB_EXT_ADDRESS_SRC] == NULL || mhp[SADB_EXT_ADDRESS_DST] == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -2100,6 +2158,16 @@ pk_recvdelete(mhp) return -1; } + plog(LLV_DEBUG2, LOCATION, NULL, "SADB delete message: proto-id %d\n", proto_id); + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst)); + + if (!sa) { + deleteallph2(src, dst, proto_id); + deleteallph1(src, dst); + return 0; + } + iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); if (iph2 == NULL) { /* ignore */ @@ -2119,6 +2187,7 @@ pk_recvdelete(mhp) if (iph2->status == PHASE2ST_ESTABLISHED) isakmp_info_send_d2(iph2); + ike_session_cleanup_ph1s_by_ph2(iph2); unbindph12(iph2); remph2(iph2); delph2(iph2); @@ -2141,7 +2210,8 @@ pk_recvflush(mhp) return -1; } - flushph2(); + flushph2(false); + flushph1(false); return 0; } @@ -2543,6 +2613,8 @@ pk_recvspddelete(mhp) return -1; } + purgephXbyspid(xpl->sadb_x_policy_id, true); + remsp(sp); delsp(sp); @@ -2598,6 +2670,8 @@ pk_recvspdexpire(mhp) return -1; } + purgephXbyspid(xpl->sadb_x_policy_id, false); + remsp(sp); delsp(sp); @@ -2692,6 +2766,8 @@ pk_recvspdflush(mhp) return -1; } + flushph2(false); + flushph1(false); flushsp(); return 0; @@ -2733,6 +2809,145 @@ pk_sendeacquire(iph2) return 0; } +int +pk_sendget_inbound_sastats(ike_session_t *session) +{ + u_int32_t max_stats; + u_int32_t seq; + + if (!session) { + plog(LLV_DEBUG, LOCATION, NULL, "invalid args in %s \n", __FUNCTION__); + return -1; + } + + session->traffic_monitor.num_in_curr_req = 0; + bzero(session->traffic_monitor.in_curr_req, sizeof(session->traffic_monitor.in_curr_req)); + max_stats = (sizeof(session->traffic_monitor.in_curr_req) / sizeof(session->traffic_monitor.in_curr_req[0])); + + // get list of SAs + if ((session->traffic_monitor.num_in_curr_req = ike_session_get_sas_for_stats(session, + IPSEC_DIR_INBOUND, + &seq, + session->traffic_monitor.in_curr_req, + max_stats))) { + u_int64_t session_ids[] = {(u_int64_t)session, 0}; + + plog(LLV_DEBUG, LOCATION, NULL, "about to call %s\n", __FUNCTION__); + + if (pfkey_send_getsastats(lcconf->sock_pfkey, + seq, + session_ids, + 1, + IPSEC_DIR_INBOUND, + session->traffic_monitor.in_curr_req, + session->traffic_monitor.num_in_curr_req) < 0) { + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, "%s successful\n", __FUNCTION__); + + return session->traffic_monitor.num_in_curr_req; + } + return 0; +} + +int +pk_sendget_outbound_sastats(ike_session_t *session) +{ + u_int32_t max_stats; + u_int32_t seq; + + if (!session) { + plog(LLV_DEBUG, LOCATION, NULL, "invalid args in %s \n", __FUNCTION__); + return -1; + } + + session->traffic_monitor.num_out_curr_req = 0; + bzero(session->traffic_monitor.out_curr_req, sizeof(session->traffic_monitor.out_curr_req)); + max_stats = (sizeof(session->traffic_monitor.out_curr_req) / sizeof(session->traffic_monitor.out_curr_req[0])); + + // get list of SAs + if ((session->traffic_monitor.num_out_curr_req = ike_session_get_sas_for_stats(session, + IPSEC_DIR_OUTBOUND, + &seq, + session->traffic_monitor.out_curr_req, + max_stats))) { + u_int64_t session_ids[] = {(u_int64_t)session, 0}; + + plog(LLV_DEBUG, LOCATION, NULL, "about to call %s\n", __FUNCTION__); + + if (pfkey_send_getsastats(lcconf->sock_pfkey, + seq, + session_ids, + 1, + IPSEC_DIR_OUTBOUND, + session->traffic_monitor.out_curr_req, + session->traffic_monitor.num_out_curr_req) < 0) { + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, "%s successful\n", __FUNCTION__); + + return session->traffic_monitor.num_out_curr_req; + } + return 0; +} + +/* + * receive GETSPDSTAT from kernel. + */ +static int +pk_recvgetsastat(mhp) +caddr_t *mhp; +{ + struct sadb_msg *msg; + struct sadb_session_id *session_id; + struct sadb_sastat *stat_resp; + ike_session_t *session; + + /* validity check */ + if (mhp[0] == NULL || + mhp[SADB_EXT_SESSION_ID] == NULL || + mhp[SADB_EXT_SASTAT] == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "inappropriate sadb getsastat response.\n"); + return -1; + } + msg = (struct sadb_msg *)mhp[0]; + session_id = (ike_session_t *)mhp[SADB_EXT_SESSION_ID]; + stat_resp = (struct sadb_sastat *)mhp[SADB_EXT_SASTAT]; + + /* the message has to be processed or not ? */ + if (msg->sadb_msg_pid != getpid()) { + plog(LLV_DEBUG, LOCATION, NULL, + "%s message is not interesting " + "because pid %d is not mine.\n", + s_pfkey_type(msg->sadb_msg_type), + msg->sadb_msg_pid); + return -1; + } + if (!session_id->sadb_session_id_v[0]) { + plog(LLV_DEBUG, LOCATION, NULL, + "%s message is bad " + "because session-id[0] is invalid.\n", + s_pfkey_type(msg->sadb_msg_type)); + return -1; + } + session = (__typeof__(session))session_id->sadb_session_id_v[0]; + + if (!stat_resp->sadb_sastat_list_len) { + plog(LLV_DEBUG, LOCATION, NULL, + "%s message is bad " + "because it has no sastats.\n", + s_pfkey_type(msg->sadb_msg_type)); + return -1; + } + + ike_session_update_traffic_idle_status(session, + stat_resp->sadb_sastat_dir, + (struct sastat *)(stat_resp + 1), + stat_resp->sadb_sastat_list_len); + return 0; +} + /* * check if the algorithm is supported or not. * OUT 0: ok @@ -2793,8 +3008,8 @@ pk_checkalg(class, calg, keylen) */ static struct sadb_msg * pk_recv(so, lenp) -int so; -int *lenp; + int so; + int *lenp; { struct sadb_msg *newmsg; int reallen = 0; @@ -2805,10 +3020,10 @@ int *lenp; if (reallen == 0) return NULL; - + if ((newmsg = racoon_calloc(1, reallen)) == NULL) return NULL; - + *lenp = recv(so, (caddr_t)newmsg, reallen, 0); if (*lenp < 0) { racoon_free(newmsg); @@ -2817,12 +3032,10 @@ int *lenp; racoon_free(newmsg); return NULL; } - + return newmsg; } - - /* see handler.h */ u_int32_t pk_getseq() diff --git a/ipsec-tools/racoon/plainrsa-gen.c b/ipsec-tools/racoon/plainrsa-gen.c index 974f3cb..92bfdfb 100644 --- a/ipsec-tools/racoon/plainrsa-gen.c +++ b/ipsec-tools/racoon/plainrsa-gen.c @@ -1,4 +1,6 @@ -/* $Id: plainrsa-gen.c,v 1.4.8.2 2005/04/21 09:07:20 monas Exp $ */ +/* $NetBSD: plainrsa-gen.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: plainrsa-gen.c,v 1.6 2005/04/21 09:08:40 monas Exp */ /* * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. * Contributed by: Michal Ludvig , SUSE Labs @@ -64,8 +66,7 @@ int print_pid = 0; void usage (char *argv0) { - //%%% fprintf(stderr, "Plain RSA key generator, part of %s\n", TOP_PACKAGE_STRING); - fprintf(stderr, "Plain RSA key generator\n"); +// fprintf(stderr, "Plain RSA key generator, part of %s\n", TOP_PACKAGE_STRING); fprintf(stderr, "By Michal Ludvig (http://www.logix.cz/michal)\n"); fprintf(stderr, "\n"); fprintf(stderr, "Usage: %s [options]\n", argv0); diff --git a/ipsec-tools/racoon/plog.c b/ipsec-tools/racoon/plog.c index 6b00980..0bfae4c 100644 --- a/ipsec-tools/racoon/plog.c +++ b/ipsec-tools/racoon/plog.c @@ -64,7 +64,7 @@ #include "gcmalloc.h" #ifndef VA_COPY -# define VA_COPY(dst,src) memcpy(&(dst), &(src), sizeof(va_list)) +# define VA_COPY(dst,src) memcpy(&(dst), (src), sizeof(va_list)) #endif extern int print_pid; @@ -147,13 +147,13 @@ plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...) va_list ap; va_start(ap, fmt); - plogv(pri, func, sa, fmt, ap); + plogv(pri, func, sa, fmt, &ap); va_end(ap); } void plogv(int pri, const char *func, struct sockaddr *sa, - const char *fmt, va_list ap) + const char *fmt, va_list *ap) { char *newfmt; va_list ap_bak; @@ -166,7 +166,7 @@ plogv(int pri, const char *func, struct sockaddr *sa, VA_COPY(ap_bak, ap); if (f_foreground) - vprintf(newfmt, ap); + vprintf(newfmt, *ap); if (logfile) log_vaprint(logp, newfmt, ap_bak); @@ -239,7 +239,8 @@ plogset(file) { if (logfile != NULL) racoon_free(logfile); - logfile = strdup(file); + logfile = racoon_strdup(file); + STRDUP_FATAL(logfile); } void @@ -266,5 +267,29 @@ plogreset(file) if (file) plogset(file); ploginit(); -} - +} + +/* + Returns a printable string from (possibly) binary data ; + concatenates all unprintable chars to one space. + XXX Maybe the printable chars range is too large... + */ +char* +binsanitize(binstr, n) + char *binstr; + size_t n; +{ + int p,q; + char* d; + for (p = 0, q = 0; p < n; p++) { + if (isgraph((int)binstr[p])) { + binstr[q++] = binstr[p]; + } else { + if (q && binstr[q - 1] != ' ') + binstr[q++] = ' '; + } + } + binstr[q++] = '\0'; + return binstr; +} + diff --git a/ipsec-tools/racoon/plog.h b/ipsec-tools/racoon/plog.h index d1448df..8b5a354 100644 --- a/ipsec-tools/racoon/plog.h +++ b/ipsec-tools/racoon/plog.h @@ -69,10 +69,11 @@ struct sockaddr; extern void plog __P((int, const char *, struct sockaddr *, const char *, ...)) __attribute__ ((__format__ (__printf__, 4, 5))); extern void plogv __P((int, const char *, struct sockaddr *, - const char *, va_list)); + const char *, va_list *)); extern void plogdump __P((int, void *, size_t)); extern void ploginit __P((void)); extern void plogset __P((char *)); -extern void plogreset __P((char *)); + +extern char* binsanitize __P((char*, size_t)); #endif /* _PLOG_H */ diff --git a/ipsec-tools/racoon/policy.c b/ipsec-tools/racoon/policy.c index d553d26..82d6981 100644 --- a/ipsec-tools/racoon/policy.c +++ b/ipsec-tools/racoon/policy.c @@ -383,7 +383,7 @@ inssp(new) } if (p == NULL) #endif - TAILQ_INSERT_TAIL(&sptree, new, chain); + TAILQ_INSERT_HEAD(&sptree, new, chain); check_auto_exit(); return; diff --git a/ipsec-tools/racoon/privsep.c b/ipsec-tools/racoon/privsep.c index 8dc4fd1..d343bbf 100644 --- a/ipsec-tools/racoon/privsep.c +++ b/ipsec-tools/racoon/privsep.c @@ -1,4 +1,6 @@ -/* $Id: privsep.c,v 1.6.2.7 2005/08/08 11:25:01 vanhu Exp $ */ +/* $NetBSD: privsep.c,v 1.6 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: privsep.c,v 1.15 2005/08/08 11:23:44 vanhu Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -54,12 +56,14 @@ #include "isakmp_var.h" #include "isakmp.h" #ifdef ENABLE_HYBRID +#include "resolv.h" #include "isakmp_xauth.h" #include "isakmp_cfg.h" #endif #include "localconf.h" #include "remoteconf.h" #include "admin.h" +#include "sockmisc.h" #include "privsep.h" static int privsep_sock[2] = { -1, -1 }; @@ -67,14 +71,10 @@ static int privsep_sock[2] = { -1, -1 }; static int privsep_recv(int, struct privsep_com_msg **, size_t *); static int privsep_send(int, struct privsep_com_msg *, size_t); static int safety_check(struct privsep_com_msg *, int i); -#ifdef HAVE_LIBPAM static int port_check(int); -#endif static int unsafe_env(char *const *); static int unknown_name(int); -static int unknown_script(int); static int unsafe_path(char *, int); -static char *script_name2path(int); static int privsep_send(sock, buf, len) @@ -179,7 +179,7 @@ privsep_init(void) if ((lcconf->pathinfo[LC_PATHTYPE_CERT] == NULL) || (lcconf->pathinfo[LC_PATHTYPE_SCRIPT] == NULL)) { plog(LLV_ERROR, LOCATION, NULL, "privilege separation " - "require path cert and path script in the config file\n"); + "require path cert and path script in the config file\n"); return -1; } @@ -333,7 +333,7 @@ privsep_init(void) * stuff eay_get_pkcs1privkey and eay_get_x509sign * together and sign the hash in the privilegied * instance? - * pro: the key remains inaccessibleato + * pro: the key remains inaccessible to unpriv * con: a compromised unpriv racoon can still sign anything */ case PRIVSEP_EAY_GET_PKCS1PRIVKEY: { @@ -345,11 +345,14 @@ privsep_init(void) bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; if (unsafe_path(bufs[0], LC_PATHTYPE_CERT) != 0) { - plog(LLV_ERROR, LOCATION, NULL, + plog(LLV_ERROR, LOCATION, NULL, "privsep_eay_get_pkcs1privkey: " - "unsafe key \"%s\"\n", bufs[0]); + "unsafe cert \"%s\"\n", bufs[0]); } + plog(LLV_DEBUG, LOCATION, NULL, + "eay_get_pkcs1privkey(\"%s\")\n", bufs[0]); + if ((privkey = eay_get_pkcs1privkey(bufs[0])) == NULL){ reply->hdr.ac_errno = errno; break; @@ -371,7 +374,7 @@ privsep_init(void) } case PRIVSEP_SCRIPT_EXEC: { - int script; + char *script; int name; char **envp = NULL; int envc = 0; @@ -384,6 +387,9 @@ privsep_init(void) * * We expect: script, name, envp[], void */ + if (safety_check(combuf, 0) != 0) + break; + bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; count++; /* script */ count++; /* name */ @@ -421,13 +427,7 @@ privsep_init(void) * Populate script, name and envp */ count = 0; - - if (combuf->bufs.buflen[count] != sizeof(script)) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: corrupted message\n"); - goto out; - } - memcpy((char *)&script, bufs[count++], sizeof(script)); + script = bufs[count++]; if (combuf->bufs.buflen[count] != sizeof(name)) { plog(LLV_ERROR, LOCATION, NULL, @@ -441,6 +441,10 @@ privsep_init(void) count++; /* void */ + plog(LLV_DEBUG, LOCATION, NULL, + "script_exec(\"%s\", %d, %p)\n", + script, name, envp); + /* * Check env for dangerous variables * Check script path and name @@ -448,15 +452,12 @@ privsep_init(void) */ if ((unsafe_env(envp) == 0) && (unknown_name(name) == 0) && - (unknown_script(script) == 0) && - (unsafe_path(script_name2path(script), - LC_PATHTYPE_SCRIPT) == 0)) + (unsafe_path(script, LC_PATHTYPE_SCRIPT) == 0)) (void)script_exec(script, name, envp); else - plog(LLV_ERROR, LOCATION, NULL, + plog(LLV_ERROR, LOCATION, NULL, "privsep_script_exec: " - "unsafe script \"%s\"\n", - script_name2path(script)); + "unsafe script \"%s\"\n", script); racoon_free(envp); break; @@ -477,6 +478,10 @@ privsep_init(void) goto out; } memcpy(&keylen, bufs[1], sizeof(keylen)); + + plog(LLV_DEBUG, LOCATION, NULL, + "getpsk(\"%s\", %d)\n", bufs[0], keylen); + if ((psk = getpsk(bufs[0], keylen)) == NULL) { reply->hdr.ac_errno = errno; break; @@ -498,6 +503,44 @@ privsep_init(void) } #ifdef ENABLE_HYBRID + case PRIVSEP_ACCOUNTING_SYSTEM: { + int pool_size; + int port; + int inout; + struct sockaddr *raddr; + + if (safety_check(combuf, 0) != 0) + break; + if (safety_check(combuf, 1) != 0) + break; + if (safety_check(combuf, 2) != 0) + break; + if (safety_check(combuf, 3) != 0) + break; + + memcpy(&port, bufs[0], sizeof(port)); + raddr = (struct sockaddr *)bufs[1]; + + bufs[2][combuf->bufs.buflen[2] - 1] = '\0'; + memcpy(&inout, bufs[3], sizeof(port)); + + if (port_check(port) != 0) + break; + + plog(LLV_DEBUG, LOCATION, NULL, + "accounting_system(%d, %s, %s)\n", + port, saddr2str(raddr), bufs[2]); + + errno = 0; + if (isakmp_cfg_accounting_system(port, + raddr, bufs[2], inout) != 0) { + if (errno == 0) + reply->hdr.ac_errno = EINVAL; + else + reply->hdr.ac_errno = errno; + } + break; + } case PRIVSEP_XAUTH_LOGIN_SYSTEM: { if (safety_check(combuf, 0) != 0) break; @@ -507,6 +550,10 @@ privsep_init(void) break; bufs[1][combuf->bufs.buflen[1] - 1] = '\0'; + plog(LLV_DEBUG, LOCATION, NULL, + "xauth_login_system(\"%s\", )\n", + bufs[0]); + errno = 0; if (xauth_login_system(bufs[0], bufs[1]) != 0) { if (errno == 0) @@ -520,18 +567,30 @@ privsep_init(void) case PRIVSEP_ACCOUNTING_PAM: { int port; int inout; + int pool_size; if (safety_check(combuf, 0) != 0) break; if (safety_check(combuf, 1) != 0) break; + if (safety_check(combuf, 2) != 0) + break; memcpy(&port, bufs[0], sizeof(port)); memcpy(&inout, bufs[1], sizeof(inout)); + memcpy(&pool_size, bufs[2], sizeof(pool_size)); + + if (pool_size != isakmp_cfg_config.pool_size) + if (isakmp_cfg_resize_pool(pool_size) != 0) + break; if (port_check(port) != 0) break; + plog(LLV_DEBUG, LOCATION, NULL, + "isakmp_cfg_accounting_pam(%d, %d)\n", + port, inout); + errno = 0; if (isakmp_cfg_accounting_pam(port, inout) != 0) { if (errno == 0) @@ -544,6 +603,7 @@ privsep_init(void) case PRIVSEP_XAUTH_LOGIN_PAM: { int port; + int pool_size; struct sockaddr *raddr; if (safety_check(combuf, 0) != 0) @@ -554,19 +614,30 @@ privsep_init(void) break; if (safety_check(combuf, 3) != 0) break; + if (safety_check(combuf, 4) != 0) + break; memcpy(&port, bufs[0], sizeof(port)); - raddr = (struct sockaddr *)bufs[1]; + memcpy(&pool_size, bufs[1], sizeof(pool_size)); + raddr = (struct sockaddr *)bufs[2]; - bufs[2][combuf->bufs.buflen[2] - 1] = '\0'; bufs[3][combuf->bufs.buflen[3] - 1] = '\0'; + bufs[4][combuf->bufs.buflen[4] - 1] = '\0'; + + if (pool_size != isakmp_cfg_config.pool_size) + if (isakmp_cfg_resize_pool(pool_size) != 0) + break; if (port_check(port) != 0) break; + plog(LLV_DEBUG, LOCATION, NULL, + "xauth_login_pam(%d, %s, \"%s\", )\n", + port, saddr2str(raddr), bufs[3]); + errno = 0; if (xauth_login_pam(port, - raddr, bufs[2], bufs[3]) != 0) { + raddr, bufs[3], bufs[4]) != 0) { if (errno == 0) reply->hdr.ac_errno = EINVAL; else @@ -577,15 +648,26 @@ privsep_init(void) case PRIVSEP_CLEANUP_PAM: { int port; + int pool_size; if (safety_check(combuf, 0) != 0) break; + if (safety_check(combuf, 1) != 0) + break; memcpy(&port, bufs[0], sizeof(port)); + memcpy(&pool_size, bufs[1], sizeof(pool_size)); + + if (pool_size != isakmp_cfg_config.pool_size) + if (isakmp_cfg_resize_pool(pool_size) != 0) + break; if (port_check(port) != 0) break; + plog(LLV_DEBUG, LOCATION, NULL, + "cleanup_pam(%d)\n", port); + cleanup_pam(port); reply->hdr.ac_errno = 0; @@ -695,7 +777,7 @@ privsep_pfkey_close(ps) int privsep_script_exec(script, name, envp) - int script; + char *script; int name; char *const envp[]; { @@ -745,7 +827,7 @@ privsep_script_exec(script, name, envp) * Compute the length */ count = 0; - msg->bufs.buflen[count] = sizeof(script); /* script */ + msg->bufs.buflen[count] = strlen(script) + 1; /* script */ msg->hdr.ac_len += msg->bufs.buflen[count++]; msg->bufs.buflen[count] = sizeof(name); /* name */ @@ -771,7 +853,7 @@ privsep_script_exec(script, name, envp) data = (char *)(msg + 1); count = 0; - memcpy(data, (char *)&script, msg->bufs.buflen[count]); /* script */ + memcpy(data, (char *)script, msg->bufs.buflen[count]); /* script */ data += msg->bufs.buflen[count++]; memcpy(data, (char *)&name, msg->bufs.buflen[count]); /* name */ @@ -903,9 +985,73 @@ privsep_xauth_login_system(usr, pwd) racoon_free(msg); return 0; } -#endif /* ENABLE_HYBRID */ -#ifdef HAVE_LIBPAM +int +privsep_accounting_system(port, raddr, usr, inout) + int port; + struct sockaddr *raddr; + char *usr; + int inout; +{ + struct privsep_com_msg *msg; + size_t len; + char *data; + int result; + + if (geteuid() == 0) + return isakmp_cfg_accounting_system(port, raddr, + usr, inout); + + len = sizeof(*msg) + + sizeof(port) + + sysdep_sa_len(raddr) + + strlen(usr) + 1 + + sizeof(inout); + + if ((msg = racoon_malloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + bzero(msg, len); + msg->hdr.ac_cmd = PRIVSEP_ACCOUNTING_SYSTEM; + msg->hdr.ac_len = len; + msg->bufs.buflen[0] = sizeof(port); + msg->bufs.buflen[1] = sysdep_sa_len(raddr); + msg->bufs.buflen[2] = strlen(usr) + 1; + msg->bufs.buflen[3] = sizeof(inout); + + data = (char *)(msg + 1); + memcpy(data, &port, msg->bufs.buflen[0]); + + data += msg->bufs.buflen[0]; + memcpy(data, raddr, msg->bufs.buflen[1]); + + data += msg->bufs.buflen[1]; + memcpy(data, usr, msg->bufs.buflen[2]); + + data += msg->bufs.buflen[2]; + memcpy(data, &inout, msg->bufs.buflen[3]); + + if (privsep_send(privsep_sock[1], msg, len) != 0) + return -1; + + if (privsep_recv(privsep_sock[1], &msg, &len) != 0) + return -1; + + if (msg->hdr.ac_errno != 0) { + errno = msg->hdr.ac_errno; + goto out; + } + + racoon_free(msg); + return 0; + +out: + racoon_free(msg); + return -1; +} + static int port_check(port) int port; @@ -967,10 +1113,10 @@ found: return -1; } -/* - * Check path safety - */ -static int +/* + * Check path safety + */ +static int unsafe_path(script, pathtype) char *script; int pathtype; @@ -979,8 +1125,8 @@ unsafe_path(script, pathtype) char rpath[MAXPATHLEN + 1]; size_t len; - if (script == NULL) - return -1; + if (script == NULL) + return -1; path = lcconf->pathinfo[pathtype]; @@ -1001,45 +1147,6 @@ unsafe_path(script, pathtype) return 0; } -static char * -script_name2path(name) - int name; -{ - vchar_t **sp; - - if (script_paths == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "script_name2path: script_paths was not initialized\n"); - return NULL; - } - - sp = (vchar_t **)(script_paths->v); - - return sp[name]->v; -} - -/* - * Check the script path index is correct - */ -static int -unknown_script(script) - int script; -{ - if (script_paths == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: script_paths was not initialized\n"); - return -1; - } - - if ((script < 0) || (script > (script_paths->l / sizeof(vchar_t *)))) { - plog(LLV_ERROR, LOCATION, NULL, - "privsep_script_exec: unsafe script index\n"); - return -1; - } - - return 0; -} - static int unknown_name(name) int name; @@ -1063,12 +1170,17 @@ privsep_accounting_pam(port, inout) size_t len; int *port_data; int *inout_data; + int *pool_size_data; int result; if (geteuid() == 0) return isakmp_cfg_accounting_pam(port, inout); - len = sizeof(*msg) + sizeof(port) + sizeof(inout); + len = sizeof(*msg) + + sizeof(port) + + sizeof(inout) + + sizeof(isakmp_cfg_config.pool_size); + if ((msg = racoon_malloc(len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); @@ -1079,12 +1191,15 @@ privsep_accounting_pam(port, inout) msg->hdr.ac_len = len; msg->bufs.buflen[0] = sizeof(port); msg->bufs.buflen[1] = sizeof(inout); + msg->bufs.buflen[2] = sizeof(isakmp_cfg_config.pool_size); port_data = (int *)(msg + 1); inout_data = (int *)(port_data + 1); + pool_size_data = (int *)(inout_data + 1); *port_data = port; *inout_data = inout; + *pool_size_data = isakmp_cfg_config.pool_size; if (privsep_send(privsep_sock[1], msg, len) != 0) return -1; @@ -1122,9 +1237,11 @@ privsep_xauth_login_pam(port, raddr, usr, pwd) len = sizeof(*msg) + sizeof(port) + + sizeof(isakmp_cfg_config.pool_size) + sysdep_sa_len(raddr) + strlen(usr) + 1 + strlen(pwd) + 1; + if ((msg = racoon_malloc(len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); @@ -1134,21 +1251,25 @@ privsep_xauth_login_pam(port, raddr, usr, pwd) msg->hdr.ac_cmd = PRIVSEP_XAUTH_LOGIN_PAM; msg->hdr.ac_len = len; msg->bufs.buflen[0] = sizeof(port); - msg->bufs.buflen[1] = sysdep_sa_len(raddr); - msg->bufs.buflen[2] = strlen(usr) + 1; - msg->bufs.buflen[3] = strlen(pwd) + 1; + msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size); + msg->bufs.buflen[2] = sysdep_sa_len(raddr); + msg->bufs.buflen[3] = strlen(usr) + 1; + msg->bufs.buflen[4] = strlen(pwd) + 1; data = (char *)(msg + 1); memcpy(data, &port, msg->bufs.buflen[0]); - data += sizeof(msg->bufs.buflen[0]); - memcpy(data, raddr, msg->bufs.buflen[1]); + data += msg->bufs.buflen[0]; + memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]); data += msg->bufs.buflen[1]; - memcpy(data, usr, msg->bufs.buflen[2]); + memcpy(data, raddr, msg->bufs.buflen[2]); data += msg->bufs.buflen[2]; - memcpy(data, pwd, msg->bufs.buflen[3]); + memcpy(data, usr, msg->bufs.buflen[3]); + + data += msg->bufs.buflen[3]; + memcpy(data, pwd, msg->bufs.buflen[4]); if (privsep_send(privsep_sock[1], msg, len) != 0) return -1; @@ -1181,7 +1302,10 @@ privsep_cleanup_pam(port) if (geteuid() == 0) return cleanup_pam(port); - len = sizeof(*msg) + sizeof(port); + len = sizeof(*msg) + + sizeof(port) + + sizeof(isakmp_cfg_config.pool_size); + if ((msg = racoon_malloc(len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); @@ -1191,10 +1315,14 @@ privsep_cleanup_pam(port) msg->hdr.ac_cmd = PRIVSEP_CLEANUP_PAM; msg->hdr.ac_len = len; msg->bufs.buflen[0] = sizeof(port); + msg->bufs.buflen[1] = sizeof(isakmp_cfg_config.pool_size); data = (char *)(msg + 1); memcpy(data, &port, msg->bufs.buflen[0]); + data += msg->bufs.buflen[0]; + memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]); + if (privsep_send(privsep_sock[1], msg, len) != 0) return; diff --git a/ipsec-tools/racoon/privsep.h b/ipsec-tools/racoon/privsep.h index 10e3aa2..0fa4363 100644 --- a/ipsec-tools/racoon/privsep.h +++ b/ipsec-tools/racoon/privsep.h @@ -1,4 +1,6 @@ -/* $Id: privsep.h,v 1.3 2005/02/10 02:02:56 manubsd Exp $ */ +/* $NetBSD: privsep.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: privsep.h,v 1.5 2005/06/07 12:22:11 fredsen Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -39,8 +41,9 @@ #define PRIVSEP_ACCOUNTING_PAM 0x0806 /* admin_com_bufs follows */ #define PRIVSEP_XAUTH_LOGIN_PAM 0x0807 /* admin_com_bufs follows */ #define PRIVSEP_CLEANUP_PAM 0x0808 /* admin_com_bufs follows */ +#define PRIVSEP_ACCOUNTING_SYSTEM 0x0809 /* admin_com_bufs follows */ -#define PRIVSEP_NBUF_MAX 16 +#define PRIVSEP_NBUF_MAX 24 #define PRIVSEP_BUFLEN_MAX 4096 struct admin_com_bufs { size_t buflen[PRIVSEP_NBUF_MAX]; @@ -57,7 +60,7 @@ int privsep_init __P((void)); vchar_t *privsep_eay_get_pkcs1privkey __P((char *)); int privsep_pfkey_open __P((void)); void privsep_pfkey_close __P((int)); -int privsep_script_exec __P((int, int, char * const *)); +int privsep_script_exec __P((char *, int, char * const *)); vchar_t *privsep_getpsk __P((const char *, const int)); int privsep_xauth_login_system __P((char *, char *)); #ifdef HAVE_LIBPAM @@ -65,5 +68,5 @@ int privsep_accounting_pam __P((int, int)); int privsep_xauth_login_pam __P((int, struct sockaddr *, char *, char *)); void privsep_cleanup_pam __P((int)); #endif - +int privsep_accounting_system __P((int, struct sockaddr *, char *, int)); #endif /* _PRIVSEP_H */ diff --git a/ipsec-tools/racoon/proposal.c b/ipsec-tools/racoon/proposal.c index a2f053a..7ade887 100644 --- a/ipsec-tools/racoon/proposal.c +++ b/ipsec-tools/racoon/proposal.c @@ -452,6 +452,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side) if (newtr == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to allocate satrns.\n"); + racoon_free(newpr); goto err; } newtr->trns_no = tr1->trns_no; @@ -706,6 +707,7 @@ aproppair2saprop(p0) if (sizeof(newpr->spi) < p->prop->spi_size) { plog(LLV_ERROR, LOCATION, NULL, "invalid spi size %d.\n", p->prop->spi_size); + racoon_free(newpr); goto err; } @@ -740,11 +742,15 @@ aproppair2saprop(p0) if (newtr == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to allocate satrns.\n"); + racoon_free(newpr); goto err; } - if (ipsecdoi_t2satrns(t->trns, newpp, newpr, newtr) < 0) { + if (ipsecdoi_t2satrns(t->trns, + newpp, newpr, newtr) < 0) { flushsaprop(newpp); + racoon_free(newtr); + racoon_free(newpr); return NULL; } @@ -1047,6 +1053,7 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) { plog(LLV_ERROR, LOCATION, NULL, "failed to get algorithms.\n"); + racoon_free(newpr); goto err; } @@ -1077,10 +1084,14 @@ set_proposal_from_policy(iph2, sp_main, sp_sub) iph2->proposal = newpp; + ike_session_update_mode(iph2); + printsaprop0(LLV_DEBUG, newpp); return 0; err: + if (newpp) + flushsaprop(newpp); return -1; } @@ -1111,6 +1122,10 @@ set_proposal_from_proposal(iph2) for (i = 0; i < MAXPROPPAIRLEN; i++) { if (pair[i] == NULL) continue; + + if (pp_peer != NULL) + flushsaprop(pp_peer); + pp_peer = aproppair2saprop(pair[i]); if (pp_peer == NULL) goto end; @@ -1138,6 +1153,7 @@ set_proposal_from_proposal(iph2) if (newpr == NULL) { plog(LLV_ERROR, LOCATION, NULL, "failed to allocate saproto.\n"); + racoon_free(pp0); goto end; } newpr->proto_id = pr->proto_id; @@ -1147,15 +1163,17 @@ set_proposal_from_proposal(iph2) newpr->spi_p = pr->spi; /* copy peer's SPI */ newpr->reqid_in = 0; newpr->reqid_out = 0; - } - if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to get algorithms.\n"); - goto end; + if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get algorithms.\n"); + racoon_free(newpr); + racoon_free(pp0); + goto end; + } + inssaproto(pp0, newpr); } - inssaproto(pp0, newpr); inssaprop(&newpp, pp0); } @@ -1164,6 +1182,8 @@ set_proposal_from_proposal(iph2) iph2->proposal = newpp; + ike_session_update_mode(iph2); + error = 0; end: @@ -1172,7 +1192,8 @@ end: if (pp_peer) flushsaprop(pp_peer); - free_proppair(pair); + if (pair) + free_proppair(pair); return error; } diff --git a/ipsec-tools/racoon/proposal.h b/ipsec-tools/racoon/proposal.h index e95752b..72df73a 100644 --- a/ipsec-tools/racoon/proposal.h +++ b/ipsec-tools/racoon/proposal.h @@ -206,6 +206,6 @@ extern void print_proppair __P((int, struct prop_pair *)); extern int set_proposal_from_policy __P((struct ph2handle *, struct secpolicy *, struct secpolicy *)); extern int set_proposal_from_proposal __P((struct ph2handle *)); -extern int tunnel_mode_prop __P((struct saprop *p)); +extern int tunnel_mode_prop __P((struct saprop *)); #endif /* _PROPOSAL_H */ diff --git a/ipsec-tools/racoon/prsa_par.y b/ipsec-tools/racoon/prsa_par.y index b44eafc..b8d3c20 100644 --- a/ipsec-tools/racoon/prsa_par.y +++ b/ipsec-tools/racoon/prsa_par.y @@ -1,4 +1,6 @@ -/* $Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp $ */ +/* $NetBSD: prsa_par.y,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp */ %{ /* @@ -98,7 +100,7 @@ prsaerror(const char *s, ...) #endif snprintf(fmt, sizeof(fmt), "%s:%d: %s", prsa_cur_fname, prsa_cur_lineno, s); - plogv(LLV_ERROR, LOCATION, NULL, fmt, ap); + plogv(LLV_ERROR, LOCATION, NULL, fmt, &ap); va_end(ap); } @@ -115,7 +117,7 @@ prsawarning(const char *s, ...) #endif snprintf(fmt, sizeof(fmt), "%s:%d: %s", prsa_cur_fname, prsa_cur_lineno, s); - plogv(LLV_WARNING, LOCATION, NULL, fmt, ap); + plogv(LLV_WARNING, LOCATION, NULL, fmt, &ap); va_end(ap); } diff --git a/ipsec-tools/racoon/prsa_tok.l b/ipsec-tools/racoon/prsa_tok.l index be0d26c..1c9288b 100644 --- a/ipsec-tools/racoon/prsa_tok.l +++ b/ipsec-tools/racoon/prsa_tok.l @@ -1,4 +1,6 @@ -/* $Id: prsa_tok.l,v 1.2 2004/07/12 20:43:51 ludvigm Exp $ */ +/* $NetBSD: prsa_tok.l,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: prsa_tok.l,v 1.2 2004/07/12 20:43:51 ludvigm Exp */ %{ /* diff --git a/ipsec-tools/racoon/racoon.8 b/ipsec-tools/racoon/racoon.8 index 8e02322..b47f8f4 100644 --- a/ipsec-tools/racoon/racoon.8 +++ b/ipsec-tools/racoon/racoon.8 @@ -131,8 +131,6 @@ The command exits with 0 on success, and non-zero on errors. .Bl -tag -width /private/etc/racoon/remote/anonymous -compact .It Pa /private/etc/racoon/racoon.conf default configuration file. -.It Pa /private/etc/racoon/remote/anonymous -default anonymous configuration file. .It Pa /private/etc/racoon/psk.txt default pre-shared key file. .El diff --git a/ipsec-tools/racoon/racoon.conf.5 b/ipsec-tools/racoon/racoon.conf.5 index 1183e61..3b3ff5b 100644 --- a/ipsec-tools/racoon/racoon.conf.5 +++ b/ipsec-tools/racoon/racoon.conf.5 @@ -1,4 +1,6 @@ -.\" $Id: racoon.conf.5,v 1.27.2.12 2005/11/25 16:06:32 manubsd Exp $ +.\" $NetBSD: racoon.conf.5,v 1.34.4.2 2007/07/18 22:53:03 mgrooms Exp $ +.\" +.\" Id: racoon.conf.5,v 1.54 2006/08/22 18:17:17 manubsd Exp .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -27,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 23, 2004 +.Dd September 19, 2006 .Dt RACOON.CONF 5 .Os .\" @@ -127,13 +129,21 @@ is one of following: .Ss Privilege separation .Bl -tag -width Ds -compact .It Ic privsep { Ar statements Ic } -specifies privilege separation parameters. +Specifies privilege separation parameters. When enabled, these enable .Xr racoon 8 to operate with an unprivileged instance doing most of the work, while a privileged instance takes care of performing the following operations as root: reading PSK and private keys, launching hook scripts, and validating passwords against system databases or against PAM. +Please note that using privilege separation makes changes to the +.Ar listen +and +.Ar paths +sections ignored upon configuration reloads. +A +.Xr racoon 8 +restart is required if you want such changes to be taken into account. .Pp .Bl -tag -width Ds -compact .It Ic user Ar user ; @@ -142,7 +152,7 @@ The user to which the unprivileged instance of should switch. This can be a quoted user name or a numeric UID. .It Ic group Ar group ; -The group to which the unprivileged instance of +The group the unprivilegied instance of .Xr racoon 8 , should switch. This can be a quoted group name or a numeric GID. @@ -156,8 +166,8 @@ reachable: .Bl -tag -width Ds -compact .It Pa /dev/random .It Pa /dev/urandom -.It the certificates -.It the file containing the Xauth banner +.It The certificates +.It The file containing the Xauth banner .El .Pp The PSK file, the private keys, and the hook scripts are accessed through the @@ -169,19 +179,21 @@ tree. .El .El .Ss Path Specification -This section specify various paths used by racoon. +This section specifies various paths used by racoon. When running in privilege separation mode, .Ic certificate and .Ic script -paths are mandatory. +paths are mandatory. A +.Xr racoon 8 +restart is required if you want path changes to be taken into account. .Bl -tag -width Ds -compact .It Ic path include Ar path ; -specifies a path to include a file. +Specifies a path to include a file. See .Sx File Inclusion . .It Ic path pre_shared_key Ar file ; -specifies a file containing pre-shared key(s) for various ID(s). +Specifies a file containing pre-shared key(s) for various ID(s). See .Sx Pre-shared key File . .It Ic path certificate Ar path ; @@ -191,7 +203,7 @@ If you run with privilege separation, .Xr racoon 8 will refuse to use a certificate stored outside of this directory. .It Ic path backupsa Ar file ; -specifies a file to which SA information which is negotiated by +Specifies a file to which SA information negotiated by racoon should be stored. .Xr racoon 8 will install SA(s) from the file when started with the @@ -208,22 +220,19 @@ If you run with privilege separation, .Xr racoon 8 will refuse to execute a script stored outside of this directory. .It Ic path pidfile Ar file ; -specifies file where to store PID of process. +Specifies file where to store PID of process. If path starts with .Pa / -it is treated as -an absolute path, otherwise relative to VARRUN directory specified at -compilation time. +it is treated as an absolute path. Otherwise, it is treated as a relative +path to the VARRUN directory specified at compilation time. Default is .Pa racoon.pid . -.It Ic path logfile Ar file ; -specifies log file path. .El .\" .Ss File Inclusion .Bl -tag -width Ds -compact .It Ic include Ar file -other configuration files can be included. +Specifies other configuration files to be included. .El .\" .Ss Identifier Specification @@ -235,26 +244,26 @@ directive. .Ss Timer Specification .Bl -tag -width Ds -compact .It Ic timer { Ar statements Ic } -specifies various timer values. +This section specifies various timer values used by racoon. .Pp .Bl -tag -width Ds -compact .It Ic counter Ar number ; -the maximum number of retries to send. +The maximum number of retries to send. The default is 5. .It Ic interval Ar number Ar timeunit ; -the interval to resend, in seconds. +The interval to resend, in seconds. The default time is 10 seconds. .It Ic persend Ar number ; -the number of packets per send. +The number of packets per send. The default is 1. .It Ic phase1 Ar number Ar timeunit ; -the maximum time it should take to complete phase 1. +The maximum time it should take to complete phase 1. The default time is 15 seconds. .It Ic phase2 Ar number Ar timeunit ; -the maximum time it should take to complete phase 2. +The maximum time it should take to complete phase 2. The default time is 10 seconds. .It Ic natt_keepalive Ar number Ar timeunit ; -interval between sending NAT-Traversal keep-alive packets. +The interval between sending NAT-Traversal keep-alive packets. The default time is 20 seconds. Set to 0s to disable keep-alive packets. .El @@ -277,7 +286,7 @@ The following is the list of valid statements: .It Ic isakmp Ar address Bq Bq Ar port ; If this is specified, .Xr racoon 8 -will only listen on +will only listen on the defined .Ar address . The default port is 500, which is specified by IANA. You can provide more than one address definition. @@ -290,25 +299,32 @@ If you plan to use NAT-T, you should provide at least one address with port 4500, which is specified by IANA. There is no default. .It Ic strict_address ; -require that all addresses for ISAKMP must be bound. -This statement will be ignored if you do not specify any address. +Requires that all addresses for ISAKMP be bound. +This statement will be ignored if you do not specify address definitions. .El +When running in privilege separation mode, you need to restart +.Xr racoon 8 +to have changes to the +.Ar listen +section taken into account. +.Pp The .Ar listen -section can also be used to specify the admin socket mode and ownership, +section can also be used to specify the admin socket mode and ownership if racoon was built with support for admin port. .Bl -tag -width Ds -compact .It Ic adminsock Ar path Op Ar owner\ group\ mode ; +The .Ar path , .Ar owner , and .Ar group -are the socket path, owner, and group; they must be quoted. -Defaults are +values specify the socket path, owner, and group. They must be quoted. +The defaults are .Pa /var/racoon/racoon.sock , UID 0, and GID 0. .Ar mode -is the access mode in octal, default is 0600. +is the access mode in octal. The default is 0600. .It Ic adminsock disabled ; This directive tells racoon to not listen on the admin socket. .El @@ -352,12 +368,12 @@ This is the encoding used by older versions of .Bq Ic inherit Ar parent .Ic { Ar statements Ic } .Xc -specifies the parameters for IKE phase 1 for each remote node. +Specifies the IKE phase 1 parameters for each remote node. The default port is 500. If .Ic anonymous -is specified, the statements apply to all peers which do not match -any other +is specified, the statements will apply to any peer that does not match a +more specific .Ic remote directive. .Pp @@ -369,7 +385,7 @@ is either .Ar address or a keyword .Ic anonymous ) -have all values predefined to those of a given +that have all values predefined to those of a given .Ar parent . In these sections it is enough to redefine only the changed parameters. .Pp @@ -378,46 +394,61 @@ The following are valid statements. .Bl -tag -width Ds -compact .\" .It Ic exchange_mode ( main | aggressive | base ) ; -defines the exchange mode for phase 1 when racoon is the initiator. -It also means the acceptable exchange mode when racoon is responder. +Defines the exchange mode for phase 1 when racoon is the initiator. +It also means the acceptable exchange mode when racoon is the responder. More than one mode can be specified by separating them with a comma. All of the modes are acceptable. The first exchange mode is what racoon uses when it is the initiator. .\" .It Ic doi Ic ipsec_doi ; -means to use IPsec DOI as specified in RFC 2407. +Means to use IPsec DOI as specified in RFC 2407. You can omit this statement. .\" .It Ic situation Ic identity_only ; -means to use SIT_IDENTITY_ONLY as specified in RFC 2407. +Means to use SIT_IDENTITY_ONLY as specified in RFC 2407. You can omit this statement. .\" .It Ic identifier Ar idtype ; -is obsolete. -Instead, use +This statment is obsolete. Instead, use .Ic my_identifier . .\" -.It Ic my_identifier Ar idtype ... ; -specifies the identifier sent to the remote host +.It Xo +.Ic my_identifier Bq Ar qualifier +.Ar idtype ... ; +.Xc +Specifies the identifier sent to the remote host and the type to use in the phase 1 negotiation. .Ic address, fqdn , user_fqdn , keyid , and .Ic asn1dn can be used as an .Ar idtype . -Use them in the following way: +The +.Ar qualifier +is currently only used for +.Ic keyid , +and can be either +.Ic file +or +.Ic tag . +The possible values are : .Bl -tag -width Ds -compact .It Ic my_identifier Ic address Bq Ar address ; -the type is the IP address. +The type is the IP address. This is the default type if you do not specify an identifier to use. .It Ic my_identifier Ic user_fqdn Ar string ; -the type is a USER_FQDN (user fully-qualified domain name). +The type is a USER_FQDN (user fully-qualified domain name). .It Ic my_identifier Ic fqdn Ar string ; -the type is a FQDN (fully-qualified domain name). -.It Ic my_identifier Ic keyid Ar file ; -the type is a KEY_ID. +The type is a FQDN (fully-qualified domain name). +.It Xo +.Ic my_identifier Ic keyid Bq Ic file +.Ar file ; +.Xc +The type is a KEY_ID, read from the file. +.It Ic my_identifier Ic keyid Ic tag Ar string ; +The type is a KEY_ID, specified in the quoted string. .It Ic my_identifier Ic asn1dn Bq Ar string ; -the type is an ASN.1 distinguished name. +The type is an ASN.1 distinguished name. If .Ar string is omitted, @@ -426,7 +457,7 @@ will get the DN from the Subject field in the certificate. .El .\" .It Ic xauth_login Bq Ar string ; -specifies the login to use in client-side Hybrid authentication. +Specifies the login to use in client-side Hybrid authentication. It is available only if .Xr racoon 8 has been built with this option. @@ -436,7 +467,7 @@ using the login as the key id. .\" .It Ic peers_identifier Ar idtype ... ; -specifies the peer's identifier to be received. +Specifies the peer's identifier to be received. If it is not defined then .Xr racoon 8 will not verify the peer's identifier in ID payload transmitted from the peer. @@ -455,17 +486,17 @@ Alternative acceptable peer identifiers may be specified by repeating the .Ic peers_identifier statement. .\" -.It Ic verify_identifier (on \(ba off) ; +.It Ic verify_identifier (on | off) ; If you want to verify the peer's identifier, set this to on. In this case, if the value defined by .Ic peers_identifier is not the same as the peer's identifier in the ID payload, -the negotiation will failed. +the negotiation will fail. The default is off. .\" .It Ic certificate_type Ar certspec ; -specifies a certificate specification. +Specifies a certificate specification. .Ar certspec is one of followings: .Bl -tag -width Ds -compact @@ -475,8 +506,14 @@ means a file name of a certificate. .Ar privkeyfile means a file name of a secret key. .El +.Bl -tag -width Ds -compact +.It Ic plain_rsa Ar privkeyfile ; +.Ar privkeyfile +means a file name of a private key generated by plainrsa-gen(8). Required +for RSA authentication. +.El .It Ic ca_type Ar cacertspec ; -specifies a root certificate authority specification. +Specifies a root certificate authority specification. .Ar cacertspec is one of followings: .Bl -tag -width Ds -compact @@ -487,11 +524,17 @@ Default is .Pa /etc/openssl/cert.pem .El .\" -.It Ic mode_cfg (on \(ba off) ; +.It Ic mode_cfg (on | off) ; Gather network information through ISAKMP mode configuration. Default is off. .\" -.It Ic peers_certfile ( dnssec | Ar certfile ) ; +.It Ic weak_phase1_check (on | off) ; +Tells racoon to act on unencrypted deletion messages during phase 1. +This is a small security risk, so the default is off, meaning that +racoon will keep on trying to establish a connection even if the +user credentials are wrong, for instance. +.\" +.It Ic peers_certfile ( dnssec | Ar certfile | Ic plain_rsa Ar pubkeyfile ) ; If .Ic dnssec is defined, @@ -504,6 +547,14 @@ is defined, .Xr racoon 8 will ignore the CERT payload from the peer, and will use this certificate as the peer's certificate. +If +.Ic plain_rsa +is defined, +.Xr racoon 8 +will expect +.Ar pubkeyfile +to be the peer's public key that was generated +by plainrsa-gen(8). .\" .It Ic script Ar script Ic phase1_up .It Ic script Ar script Ic phase1_down @@ -532,41 +583,76 @@ was enabled: An IPv4 internal address obtained by ISAKMP mode config. .It INTERNAL_NETMASK4 An IPv4 internal netmask obtained by ISAKMP mode config. +.It INTERNAL_CIDR4 +An IPv4 internal netmask obtained by ISAKMP mode config, in CIDR notation. .It INTERNAL_DNS4 -Internal DNS server IPv4 address obtained by ISAKMP mode config. -.It INTERNAL_NBNS4 -Internal WINS server IPv4 address obtained by ISAKMP mode config. +The first internal DNS server IPv4 address obtained by ISAKMP mode config. +.It INTERNAL_DNS4_LIST +A list of internal DNS servers IPv4 address obtained by ISAKMP mode config, +separated by spaces. +.It INTERNAL_WINS4 +The first internal WINS server IPv4 address obtained by ISAKMP mode config. +.It INTERNAL_WINS4_LIST +A list of internal WINS servers IPv4 address obtained by ISAKMP mode config, +separated by spaces. +.It SPLIT_INCLUDE +The space separated list of IPv4 addresses and masks (address slash mask) +that define the networks to be encrypted (as opposed to the default where +all the traffic should be encrypted) ; obtained by ISAKMP mode config ; +SPLIT_INCLUDE and SPLIT_LOCAL are mutually exclusive. +.It SPLIT_LOCAL +The space separated list of IPv4 addresses and masks (address slash mask) +that define the networks to be considered local, and thus excluded from the +tunnels ; obtained by ISAKMP mode config. +.It DEFAULT_DOMAIN +The DNS default domain name obtained by ISAKMP mode config. .El .\" .\" -.It Ic send_cert (on \(ba off) ; -If you do not want to send a certificate for some reason, set this to off. +.It Ic send_cert (on | off) ; +If you do not want to send a certificate, set this to off. The default is on. .\" -.It Ic send_cr (on \(ba off) ; -If you do not want to send a certificate request for some reason, set this to off. +.It Ic send_cr (on | off) ; +If you do not want to send a certificate request, set this to off. The default is on. .\" -.It Ic verify_cert (on \(ba off) ; -If you do not want to verify the peer's certificate for some reason, +.It Ic verify_cert (on | off) ; +By default, the identifier sent by the remote host (as specified in its +.Ic my_identifier +statement) is compared with the credentials in the certificate +used to authenticate the remote host as follows: +.Bl -tag -width Ds -compact +.It Type Ic asn1dn: +The entire certificate subject name is compared with the identifier, +e.g. "C=XX, O=YY, ...". +.It Type Ic address, fqdn, or user_fqdn: +The certificate's subjectAltName is compared with the identifier. +.El +If the two do not match the negotiation will fail. +If you do not want to verify the identifier using the peer's certificate, set this to off. -The default is on. .\" .It Ic lifetime time Ar number Ar timeunit ; Define a lifetime of a certain time which will be proposed in the phase 1 negotiations. -Any proposal will be accepted, and the attribute(s) will be not proposed to +Any proposal will be accepted, and the attribute(s) will not be proposed to the peer if you do not specify it (them). They can be individually specified in each proposal. .\" -.It Ic ike_frag (on \(ba off) ; -Enable receiver-side IKE fragmentation, if +.It Ic ike_frag (on | off | force) ; +Enable receiver-side IKE fragmentation if .Xr racoon 8 has been built with this feature. -This extension is there to work around -broken firewalls that do not work with fragmented UDP packets. -IKE fragmentation is always enabled on the sender-side, and -it is used if the peer advertises itself as IKE fragmentation capable. +If set to on, racoon will advertise +itself as being capable of receiving packets split by IKE fragmentation. +This extension is there to work around broken firewalls that do not +work with fragmented UDP packets. +IKE fragmentation is always enabled on the sender-side, and it is +used if the peer advertises itself as IKE fragmentation capable. +By selecting force, IKE Fragmentation will +be used when racoon is acting as the initiator even before the remote +peer has advertised itself as IKE fragmentation capable. .\" .It Ic esp_frag Ar fraglen ; This option is only relevant if you use NAT traversal in tunnel mode. @@ -580,32 +666,33 @@ is the maximum size of the fragments. 552 should work anywhere, but the higher .Ar fraglen -is, the better is the performance. +is, the better the performance. .Pp Note that because PMTU discovery is broken on many sites, you will have to use MSS clamping if you want TCP to work correctly. .\" -.It Ic initial_contact (on \(ba off) ; -enable this to send an INITIAL-CONTACT message. +.It Ic initial_contact (on | off) ; +Enable this to send an INITIAL-CONTACT message. The default value is .Ic on . -This message is useful only when -the implementation of the responder chooses an old SA when there are multiple -SAs with different established time, and the initiator reboots. +This message is useful only when the responder implementation chooses an +old SA when there are multiple SAs with different established time and the +initiator reboots. If racoon did not send the message, the responder would use an old SA even when a new SA was established. -The KAME stack has the switch in the system wide value -net.key.preferred_oldsa. -when the value is zero, the stack always uses a new SA. +For systems that use a KAME derived IPSEC stack, the +.Xr sysctl 8 +variable net.key.preferred_oldsa can be used to control this preference. +When the value is zero, the stack always uses a new SA. .\" -.It Ic passive (on \(ba off) ; +.It Ic passive (on | off) ; If you do not want to initiate the negotiation, set this to on. The default value is .Ic off . It is useful for a server. .\" .It Ic proposal_check Ar level ; -specifies the action of lifetime length and PFS of the phase 2 +Specifies the action of lifetime length, key length and PFS of the phase 2 selection on the responder side, and the action of lifetime check in phase 1. The default level is @@ -615,37 +702,38 @@ If the is: .Bl -tag -width Ds -compact .It Ic obey -the responder will obey the initiator anytime. +The responder will obey the initiator anytime. .It Ic strict -If the responder's length is longer than the initiator's one, the -responder uses the initiator's one. -Otherwise it rejects the proposal. +If the responder's lifetime length is longer than the initiator's or +the responder's key length is shorter than the initiator's, +the responder will use the initiator's value. +Otherwise, the proposal will be rejected. If PFS is not required by the responder, the responder will obey the proposal. -If PFS is required by both sides and if the responder's group is not equal to -the initiator's one, then the responder will reject the proposal. +If PFS is required by both sides and the responder's group is not equal to +the initiator's, then the responder will reject the proposal. .It Ic claim -If the responder's length is longer than the initiator's one, the -responder will use the initiator's one. -If the responder's length is -shorter than the initiator's one, the responder uses its own length -AND sends a RESPONDER-LIFETIME notify message to an initiator in the -case of lifetime (phase 2 only). +If the responder's lifetime length is longer than the initiator's or +the responder's key length is shorter than the initiator's, +the responder will use the initiator's value. +If the responder's lifetime length is shorter than the initiator's, +the responder uses its own length AND sends a RESPONDER-LIFETIME notify +message to an initiator in the case of lifetime (phase 2 only). For PFS, this directive behaves the same as .Ic strict . .It Ic exact -If the initiator's length is not equal to the responder's one, the -responder will reject the proposal. -If PFS is required by both sides and if the responder's group is not equal to -the initiator's one, then the responder will reject the proposal. +If the initiator's lifetime or key length is not equal to the responder's, +the responder will reject the proposal. +If PFS is required by both sides and the responder's group is not equal to +the initiator's, then the responder will reject the proposal. .El .\" -.It Ic support_proxy (on \(ba off) ; +.It Ic support_proxy (on | off) ; If this value is set to on, then both values of ID payloads in the phase 2 exchange are always used as the addresses of end-point of IPsec-SAs. The default is off. .\" -.It Ic generate_policy (on \(ba off) ; +.It Ic generate_policy (on | off | require | unique) ; This directive is for the responder. Therefore you should set .Ic passive @@ -663,20 +751,27 @@ Note that an inappropriate policy might be installed into the responder's SPD by the initiator, so other communications might fail if such policies are installed due to a policy mismatch between the initiator and the responder. +.Ic on +and +.Ic require +values mean the same thing (generate a require policy). +.Ic unique +tells racoon to set up unique policies, with a monotoning increasing +reqid number (between 1 and IPSEC_MANUAL_REQID_MAX). This directive is ignored in the initiator case. The default value is .Ic off . .\" .\" -.It Ic nat_traversal (on \(ba off \(ba force) ; +.It Ic nat_traversal (on | off | force) ; This directive enables use of the NAT-Traversal IPsec extension (NAT-T). NAT-T allows one or both peers to reside behind a NAT gateway (i.e., doing address- or port-translation). -Presence of NAT gateways along the path -is discovered during phase 1 handshake and if found, NAT-T is negotiated. -When NAT-T is in charge, all ESP and AH packets of a given connection -are encapsulated into UDP datagrams (port 4500, by default). +If a NAT gateway is detected during the phase 1 handshake, racoon will +attempt to negotiate the use of NAT-T with the remote peer. +If the negotiation succeeds, all ESP and AH packets for the given connection +will be encapsulated into UDP datagrams (port 4500, by default). Possible values are: .Bl -tag -width Ds -compact .It Ic on @@ -685,7 +780,8 @@ NAT-T is used when a NAT gateway is detected between the peers. NAT-T is not proposed/accepted. This is the default. .It Ic force -NAT-T is used regardless if a NAT is detected between the peers or not. +NAT-T is used regardless of whether a NAT gateway is detected between the +peers or not. .El Please note that NAT-T support is a compile-time option. Although it is enabled in the source distribution by default, it @@ -695,7 +791,7 @@ warning when using any NAT-T related config options. .\" .It Ic dpd_delay Ar delay ; This option activates the DPD and sets the time (in seconds) allowed -between 2 proof of liveness requests. +between 2 proof of liveliness requests. The default value is .Ic 0 , which disables DPD monitoring, but still negotiates DPD support. @@ -704,14 +800,14 @@ which disables DPD monitoring, but still negotiates DPD support. If .Ic dpd_delay is set, this sets the delay (in seconds) to wait for a proof of -liveness before considering it as failed and send another request. +liveliness before considering it as failed and send another request. The default value is .Ic 5 . .\" .It Ic dpd_maxfail Ar number ; If .Ic dpd_delay -is set, this sets the maximum number of proof of liveness to request +is set, this sets the maximum number of liveliness proofs to request (without reply) before considering the peer is dead. The default value is .Ic 5 . @@ -722,23 +818,28 @@ Racoon can send any value although RFC2409 specifies that the value MUST be between 8 and 256 bytes. The default size is 16 bytes. .\" +.It Ic ph1id Ar number ; +An optionnal number to identify the remote proposal and to link it +only with sainfos who have the same number. +Defaults to 0. +.\" .It Xo .Ic proposal { Ar sub-substatements Ic } .Xc .Bl -tag -width Ds -compact .\" .It Ic encryption_algorithm Ar algorithm ; -specify the encryption algorithm used for the phase 1 negotiation. +Specifies the encryption algorithm used for the phase 1 negotiation. This directive must be defined. .Ar algorithm is one of following: -.Ic des , 3des , blowfish , cast128 , aes +.Ic des, 3des, blowfish, cast128, aes, camellia .\".Ic rc5 , idea for Oakley. For other transforms, this statement should not be used. .\" .It Ic hash_algorithm Ar algorithm ; -define the hash algorithm used for the phase 1 negotiation. +Defines the hash algorithm used for the phase 1 negotiation. This directive must be defined. .Ar algorithm is one of following: @@ -746,16 +847,19 @@ is one of following: for Oakley. .\" .It Ic authentication_method Ar type ; -defines the authentication method used for the phase 1 negotiation. +Defines the authentication method used for the phase 1 negotiation. This directive must be defined. .Ar type is one of: -.Ic pre_shared_key , rsasig , gssapi_krb , hybrid_rsa_server , +.Ic pre_shared_key , rsasig +(for plain RSA authentication), +.Ic gssapi_krb , hybrid_rsa_server , +.Ic hybrid_rsa_client , xauth_rsa_server , xauth_rsa_client , xauth_psk_server or -.Ic hybrid_rsa_client . +.Ic xauth_psk_client . .\" .It Ic dh_group Ar group ; -define the group used for the Diffie-Hellman exponentiations. +Defines the group used for the Diffie-Hellman exponentiations. This directive must be defined. .Ar group is one of following: @@ -766,14 +870,14 @@ Or you can define 1, 2, 5, 14, 15, 16, 17, or 18 as the DH group number. When you want to use aggressive mode, you must define the same DH group in each proposal. .It Ic lifetime time Ar number Ar timeunit ; -define lifetime of the phase 1 SA proposal. +Defines the lifetime of the phase 1 SA proposal. Refer to the description of the .Ic lifetime directive defined in the .Ic remote directive. .It Ic gss_id Ar string ; -define the GSS-API endpoint name, to be included as an attribute in the SA, +Defines the GSS-API endpoint name, to be included as an attribute in the SA, if the .Ic gssapi_krb authentication method is used. @@ -800,7 +904,7 @@ and policies in the kernel. .Ss Sainfo Specifications .Bl -tag -width Ds -compact .It Xo -.Ic sainfo ( Ar source_id destination_id | Ic anonymous ) [ from Ar idtype [ Ar string ] ] +.Ic sainfo ( Ar source_id destination_id | Ar source_id Ic anonymous | Ic anonymous Ar destination_id | Ic anonymous ) [ from Ar idtype [ Ar string ] ] [ Ic group Ar string ] .Ic { Ar statements Ic } .Xc defines the parameters of the IKE phase 2 (IPsec-SA establishment). @@ -825,18 +929,28 @@ or .Pp .Ar idtype Ar string .Pp -It means exactly the content of ID payload. +An id string should be expressed to match the exact value of an ID payload +(source is the local end, destination is the remote end). This is not like a filter rule. For example, if you define 3ffe:501:4819::/48 as .Ar source_id . 3ffe:501:4819:1000:/64 will not match. .Pp -In case of longest prefix (selecting single host) +In the case of a longest prefix (selecting a single host), .Ar address -instructs to send ID type of ADDRESS, while +instructs to send ID type of ADDRESS while .Ar subnet instructs to send ID type of SUBNET. -Otherwise these instructions are identical. +Otherwise, these instructions are identical. +.Pp +The group keyword allows an XAuth group membership check to be performed +for this sainfo section. +When the mode_cfg auth source is set to +.Ic system +or +.Ic ldap , +the XAuth user is verified to be a member of the specified group +before allowing a matching SA to be negotiated. .Pp .Bl -tag -width Ds -compact .\" @@ -859,6 +973,11 @@ See the .Ic proposal_check directive. .\" +.It Ic remoteid Ar number ; +Sainfos will only be used if their remoteid matches the ph1id of the +remote section used for phase 1. +Defaults to 0, which is also the default for ph1id. +.\" .It Ic my_identifier Ar idtype ... ; is obsolete. It does not make sense to specify an identifier in the phase 2. @@ -897,7 +1016,7 @@ Note that the kernel may not support the algorithm you have specified. .Ic des , 3des , des_iv64 , des_iv32 , .Ic rc5 , rc4 , idea , 3idea , .Ic cast128 , blowfish , null_enc , -.Ic twofish , rijndael , aes +.Ic twofish , rijndael , aes , camellia .Pq used with ESP .\" .It Ic authentication_algorithm Ar algorithms ; @@ -914,42 +1033,42 @@ Note that the kernel may not support the algorithm you have specified. .Ss Logging level .Bl -tag -width Ds -compact .It Ic log Ar level ; -define logging level. +Defines the logging level. .Ar level is one of following: -.Ic notify , debug , +.Ic error , warning , notify , info , debug and .Ic debug2 . The default is -.Ic notify . +.Ic info . If you set the logging level too high on slower machines, IKE negotiation can fail due to timing constraint changes. .El .\" -.Ss Specifying the way to pad +.Ss Specifies the way to pad .Bl -tag -width Ds -compact .It Ic padding { Ar statements Ic } -specified padding format. +specifies the padding format. The following are valid statements: .Bl -tag -width Ds -compact -.It Ic randomize (on \(ba off) ; -enable using a randomized value for padding. +.It Ic randomize (on | off) ; +Enables the use of a randomized value for padding. The default is on. -.It Ic randomize_length (on \(ba off) ; -the pad length is random. +.It Ic randomize_length (on | off) ; +The pad length will be random. The default is off. .It Ic maximum_length Ar number ; -define a maximum padding length. +Defines a maximum padding length. If .Ic randomize_length is off, this is ignored. The default is 20 bytes. -.It Ic exclusive_tail (on \(ba off) ; -means to put the number of pad bytes minus one into the last part +.It Ic exclusive_tail (on | off) ; +Means to put the number of pad bytes minus one into the last part of the padding. The default is on. -.It Ic strict_check (on \(ba off) ; -means to constrain the peer to set the number of pad bytes. +.It Ic strict_check (on | off) ; +Means to constrain the peer to set the number of pad bytes. The default is off. .El .El @@ -959,12 +1078,12 @@ The default is off. Defines the information to return for remote hosts' ISAKMP mode config requests. Also defines the authentication source for remote peers -authenticating through hybrid auth. +authenticating through Xauth. .Pp The following are valid statements: .Bl -tag -width Ds -compact -.It Ic auth_source (system \(ba radius \(ba pam) ; -Specify the source for authentication of users through hybrid auth. +.It Ic auth_source (system | radius | pam | ldap) ; +Specifies the source for authentication of users through Xauth. .Ar system means to use the Unix user database. This is the default. @@ -972,48 +1091,87 @@ This is the default. means to use a RADIUS server. It works only if .Xr racoon 8 -was built with libradius support, and the configuration is done in +was built with libradius support. Radius configuration is hanlded by .Xr radius.conf 5 . .Ar pam means to use PAM. It works only if .Xr racoon 8 was built with libpam support. -.It Ic conf_source (local \(ba radius) ; -Specify the source for IP addresses and netmask allocated through ISAKMP +.Ar ldap +means to use LDAP. +It works only if +.Xr racoon 8 +was built with libldap support. LDAP configuration is handled by +statements in the +.Ic ldapcfg +section. +.It Ic auth_groups Ar "group1", ... ; +Specifies the group memberships for Xauth in quoted group name strings. +When defined, the authenticating user must be a member of at least one +group for Xauth to succeed. +.It Ic group_source (system | ldap) ; +Specifies the source for group validataion of users through Xauth. +.Ar system +means to use the Unix user database. +This is the default. +.Ar ldap +means to use LDAP. +It works only if +.Xr racoon 8 +was built with libldap support and requires LDAP authentication. +LDAP configuration is handled by statements in the +.Ic ldapcfg +section. +.It Ic conf_source (local | radius | ldap) ; +Specifies the source for IP addresses and netmask allocated through ISAKMP mode config. .Ar local means to use the local IP pool defined by the .Ic network4 and .Ic pool_size -keywords. +statements. This is the default. .Ar radius means to use a RADIUS server. It works only if .Xr racoon 8 -was built with libradius support, and the configuration is done in +was built with libradius support and requires RADIUS authentiation. +RADIUS configuration is handled by .Xr radius.conf 5 . -RADIUS configuration requires RADIUS authentication. -.It Ic accounting (none \(ba radius \(ba pam) ; -Enable or disable accounting for Xauth logins and logouts. -Default is -.Ar none , +.Ar ldap +means to use an LDAP server. +It works only if +.Xr racoon 8 +was built with libldap support and requires LDAP authentication. +LDAP configuration is handled by +statements in the +.Ic ldapcfg +section. +.It Ic accounting (none | system | radius | pam) ; +Enables or disables accounting for Xauth logins and logouts. +The default is +.Ar none which disable accounting. +Specifying +.Ar system +enables system accounting through +.Xr utmp 5 . +Specifying .Ar radius -enable RADIUS accounting. +enables RADIUS accounting. It works only if .Xr racoon 8 -was built with libradius support, and the configuration is done in +was built with libradius support and requires RADIUS authentication. +RADIUS configuration is handled by .Xr radius.conf 5 . -RADIUS accounting require RADIUS authentication. +Specifying .Ar pam -enable PAM accounting. +enables PAM accounting. It works only if .Xr racoon 8 -was built with libpam support. -PAM accounting requires PAM authentication. +was build with libpam support and requires PAM authentication. .It Ic pool_size Ar size Specify the size of the IP address pool, either local or allocated through RADIUS. @@ -1035,18 +1193,36 @@ or if the RADIUS server returned .Ar 255.255.255.254 . Default is .Ar 0.0.0.0/0.0.0.0 . -.It Ic dns4 Ar address ; -The IPv4 address for a DNS server. -.It Ic nbns4 Ar address ; -The IPv4 address for a WINS server. +.It Ic dns4 Ar addresses ; +A list of IPv4 addresses for DNS servers, separated by commas, or on multiple +.Ic dns4 +lines. +.It Ic nbns4 Ar addresses ; +A list of IPv4 address for WINS servers. +.It Ic split_network (include | local_lan) Ar network/mask, ... +The network configuration to send, in cidr notation (e.g. 192.168.1.0/24). +If +.Ic include +is specified, the tunnel should be only used to encrypt the indicated +destinations ; otherwise, if +.Ic local_lan +is used, everything will pass through the tunnel but those destinations. +.It Ic default_domain Ar domain ; +The default DNS domain to send. +.It Ic split_dns Ar "domain", ... +The split dns configuration to send, in quoted domain name strings. +This list can be used to describe a list of domain names for which +a peer should query a modecfg assigned dns server. +DNS queries for all other domains would be handled locally. +(Cisco VPN client only). .It Ic banner Ar path ; The path of a file displayed on the client at connection time. Default is .Ar /etc/motd . .It Ic auth_throttle Ar delay ; -On each failed Xauth authentication attempt, refuse new attempts for +On each failed Xauth authentication attempt, refuse new attempts for a set .Ar delay -more seconds. +of seconds. This is to avoid dictionary attacks on Xauth passwords. Default is one second. Set to zero to disable authentication delay. @@ -1058,9 +1234,73 @@ Allow the client to save the Xauth password (Cisco VPN client only). Default is off. .El .El +.Ss Ldap configuration settings +.Bl -tag -width Ds -compact +.It Ic ldapcfg { Ar statements Ic } +Defines the parameters that will be used to communicate with an ldap +server for +.Ic xauth +authentication. +.Pp +The following are valid statements: +.Bl -tag -width Ds -compact +.It Ic version (2 | 3) ; +The ldap protocol version used to communicate with the server. +The default is +.Ic 3 . +.It Ic host Ar (hostname | address) ; +The host name or ip address of the ldap server. +The default is +.Ic localhost . +.It Ic port Ar number; +The port that the ldap server is configured to listen on. +The default is +.Ic 389 . +.It Ic base Ar distinguished name; +The ldap search base. +This option has no default value. +.It Ic subtree (on | off) ; +Use the subtree ldap search scope. +Otherwise, use the one level search scope. +The default is +.Ic off . +.It Ic bind_dn Ar distinguised name; +The user dn used to optionaly bind as before performing ldap search operations. +If this option is not specified, anonymous binds are used. +.It Ic bind_pw Ar string; +The password used when binding as +.Ic bind_dn . +.It Ic attr_user Ar attribute name; +The attribute used to specify a users name in an ldap directory. +For example, +if a user dn is "cn=jdoe,dc=my,dc=net" then the attribute would be "cn". +The default value is +.Ic cn . +.It Ic attr_addr Ar attribute name; +.It Ic attr_mask Ar attribute name; +The attributes used to specify a users network address and subnet mask in an +ldap directory. +These values are forwarded during mode_cfg negotiation when +the conf_source is set to ldap. +The default values are +.Ic racoon-address +and +.Ic racoon-netmask . +.It Ic attr_group Ar attribute name; +The attribute used to specify a group name in an ldap directory. +For example, +if a group dn is "cn=users,dc=my,dc=net" then the attribute would be "cn". +The default value is +.Ic cn . +.It Ic attr_member Ar attribute name; +The attribute used to specify group membership in an ldap directory. +The default value is +.Ic member . +.El +.El .Ss Special directives .Bl -tag -width Ds -compact -.It Ic complex_bundle (on \(ba off) ; +.It Ic complex_bundle (on | off) ; defines the interpretation of proposal in the case of SA bundle. Normally .Dq IP AH ESP IP payload @@ -1121,6 +1361,25 @@ sainfo anonymous } .Ed .Pp +If you are configuring plain RSA authentication, the remote directive +should look like the following: +.Bd -literal -offset +path certificate "/usr/local/v6/etc" ; +remote anonymous +{ + exchange_mode main,base ; + lifetime time 12 hour ; + certificate_type plain_rsa "/usr/local/v6/etc/myrsakey.priv"; + peers_certfile plain_rsa "/usr/local/v6/etc/yourrsakey.pub"; + proposal { + encryption_algorithm aes ; + hash_algorithm sha1 ; + authentication_method rsasig ; + dh_group 2 ; + } +} +.Ed +.Pp The following is a sample for the pre-shared key file. .Bd -literal -offset 10.160.94.3 mekmitasdigoat diff --git a/ipsec-tools/racoon/racoonctl.8 b/ipsec-tools/racoon/racoonctl.8 index cf292a5..b27b188 100644 --- a/ipsec-tools/racoon/racoonctl.8 +++ b/ipsec-tools/racoon/racoonctl.8 @@ -1,4 +1,6 @@ -.\" $Id: racoonctl.8,v 1.2.4.2 2005/04/18 11:10:55 manubsd Exp $ +.\" $NetBSD: racoonctl.8,v 1.13 2006/09/09 16:22:10 manu Exp $ +.\" +.\" Id: racoonctl.8,v 1.6 2006/05/07 21:32:59 manubsd Exp .\" .\" Copyright (C) 2004 Emmanuel Dreyfus .\" All rights reserved. @@ -64,6 +66,9 @@ vpn-disconnect .Nm show-event .Op Fl l +.Nm +logout-user +.Ar login .\" .Sh DESCRIPTION .Nm @@ -86,7 +91,6 @@ The following commands are available: This should cause .Xr racoon 8 to reload its configuration file. -This seems completely broken at the time this man page is written. .It show-schedule Unknown command. .It show-sa Op isakmp|esp|ah|ipsec @@ -141,6 +145,9 @@ flag causes .Nm to not stop once all the events have been read, but rather to loop awaiting and reporting new events. +.It logout-user Ar login +Delete all SA established on behalf of the Xauth user +.Ar login . .El .Pp Command shortcuts are available: @@ -163,6 +170,8 @@ vpn-connect vpn-disconnect .It se show-event +.It lu +logout-user .El .\" .Sh RETURN VALUES diff --git a/ipsec-tools/racoon/racoonctl.c b/ipsec-tools/racoon/racoonctl.c index e59b1f9..9f5f77a 100644 --- a/ipsec-tools/racoon/racoonctl.c +++ b/ipsec-tools/racoon/racoonctl.c @@ -1,4 +1,6 @@ -/* $Id: racoonctl.c,v 1.2.2.1 2005/04/21 09:07:20 monas Exp $ */ +/* $NetBSD: racoonctl.c,v 1.7 2006/10/02 07:12:26 manu Exp $ */ + +/* Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,6 +67,7 @@ #endif #include #include +#include #include "var.h" #include "vmbuf.h" @@ -77,6 +80,7 @@ #include "handler.h" #include "sockmisc.h" #include "vmbuf.h" +#include "plog.h" #include "isakmp_var.h" #include "isakmp.h" #include "isakmp_xauth.h" @@ -97,8 +101,13 @@ static vchar_t *f_flushsa __P((int, char **)); static vchar_t *f_deletesa __P((int, char **)); static vchar_t *f_exchangesa __P((int, char **)); static vchar_t *f_vpnc __P((int, char **)); +static vchar_t *f_exchangesatest __P((int, char **)); +static vchar_t *f_vpntest __P((int, char **)); static vchar_t *f_vpnd __P((int, char **)); static vchar_t *f_getevt __P((int, char **)); +#ifdef ENABLE_HYBRID +static vchar_t *f_logoutusr __P((int, char **)); +#endif struct cmd_tag { vchar_t *(*func) __P((int, char **)); @@ -119,10 +128,15 @@ struct cmd_tag { { f_exchangesa, ADMIN_ESTABLISH_SA, "es" }, { f_vpnc, ADMIN_ESTABLISH_SA, "vpn-connect" }, { f_vpnc, ADMIN_ESTABLISH_SA, "vc" }, + { f_vpntest, ADMIN_ESTABLISH_SA_VPNCONTROL, "vpntest" }, { f_vpnd, ADMIN_DELETE_ALL_SA_DST,"vpn-disconnect" }, { f_vpnd, ADMIN_DELETE_ALL_SA_DST,"vd" }, { f_getevt, ADMIN_SHOW_EVT, "show-event" }, { f_getevt, ADMIN_SHOW_EVT, "se" }, +#ifdef ENABLE_HYBRID + { f_logoutusr, ADMIN_LOGOUT_USER, "logout-user" }, + { f_logoutusr, ADMIN_LOGOUT_USER, "lu" }, +#endif { NULL, 0, NULL }, }; @@ -145,7 +159,10 @@ struct evtmsg { { EVTT_XAUTH_FAILED, "Xauth exchange failed", ERROR }, { EVTT_PEERPH1AUTH_FAILED, "Peer failed phase 1 authentication " "(certificate problem?)", ERROR }, + { EVTT_PEERPH1_NOPROP, "Peer failed phase 1 initiation " + "(proposal problem?)", ERROR }, { 0, NULL, UNSPEC }, + { EVTT_NO_ISAKMP_CFG, "No need for ISAKMP mode config ", INFO }, }; static int get_proto __P((char *)); @@ -207,6 +224,7 @@ void print_evt __P((caddr_t, int)); void print_cfg __P((caddr_t, int)); void print_err __P((caddr_t, int)); void print_ph1down __P((caddr_t, int)); +void print_ph1up __P((caddr_t, int)); int evt_poll __P((void)); char * fixed_addr __P((char *, char *, int)); @@ -329,6 +347,7 @@ evt_poll(void) { errx(1, "Cannot make combuf"); while (evt_filter & (EVTF_LOOP|EVTF_PURGE)) { + /* handle_recv closes the socket time, so open it each time */ com_init(); if (com_send(sendbuf) != 0) errx(1, "Cannot send combuf"); @@ -343,7 +362,7 @@ evt_poll(void) { (void)select(0, NULL, NULL, NULL, &tv); } - /* NOTREACHED */ + vfree(sendbuf); return 0; } @@ -555,7 +574,7 @@ f_deletesa(ac, av) buf = vmalloc(sizeof(*head) + index->l); if (buf == NULL) - return NULL; + goto out; head = (struct admin_com *)buf->v; head->ac_len = buf->l + index->l; @@ -565,6 +584,10 @@ f_deletesa(ac, av) memcpy(buf->v+sizeof(*head), index->v, index->l); +out: + if (index != NULL) + vfree(index); + return buf; } @@ -606,7 +629,7 @@ f_deleteallsadst(ac, av) buf = vmalloc(sizeof(*head) + index->l); if (buf == NULL) - return NULL; + goto out; head = (struct admin_com *)buf->v; head->ac_len = buf->l + index->l; @@ -616,6 +639,10 @@ f_deleteallsadst(ac, av) memcpy(buf->v+sizeof(*head), index->v, index->l); +out: + if (index != NULL) + vfree(index); + return buf; } @@ -691,21 +718,123 @@ f_exchangesa(ac, av) memcpy(buf->v+sizeof(*head), index->v, index->l); if (id && key) { + // overload com_len to track the number of unused bytes in buf->v char *data; acp = (struct admin_com_psk *) (buf->v + sizeof(*head) + index->l); + com_len -= sizeof(*head) + index->l; - acp->id_type = IDTYPE_LOGIN; + acp->id_type = IDTYPE_USERFQDN; acp->id_len = strlen(id) + 1; acp->key_len = strlen(key) + 1; data = (char *)(acp + 1); - strcpy(data, id); + com_len -= sizeof(*acp); + strlcpy(data, id, com_len); data = (char *)(data + acp->id_len); - strcpy(data, key); + com_len -= acp->id_len; + strlcpy(data, key, com_len); } + vfree(index); + + return buf; +} + +// %%%%% testing +static vchar_t * +f_exchangesatest(ac, av) + int ac; + char **av; +{ + vchar_t *buf, *index; + struct admin_com *head; + int proto; + int cmd = ADMIN_ESTABLISH_SA_VPNCONTROL; + size_t com_len = 0; + char *id = NULL; + char *key = NULL; + struct admin_com_psk *acp; + + if (ac < 1) + errx(1, "insufficient arguments"); + + /* Optional -u identity */ + if (strcmp(av[0], "-u") == 0) { + if (ac < 2) + errx(1, "-u require an argument"); + + id = av[1]; + if ((key = getpass("Password: ")) == NULL) + errx(1, "getpass() failed: %s", strerror(errno)); + + com_len += sizeof(*acp) + strlen(id) + 1 + strlen(key) + 1; + cmd = ADMIN_ESTABLISH_SA_VPNCONTROL; + + av += 2; + ac -= 2; + } + + /* need protocol */ + if (ac < 1) + errx(1, "insufficient arguments"); + if ((proto = get_proto(*av)) == -1) + errx(1, "unknown protocol %s", *av); + + /* get index(es) */ + av++; + ac--; + switch (proto) { + case ADMIN_PROTO_ISAKMP: + index = get_index(ac, av); + if (index == NULL) + return NULL; + break; + case ADMIN_PROTO_AH: + case ADMIN_PROTO_ESP: + index = get_index(ac, av); + if (index == NULL) + return NULL; + break; + default: + errno = EPROTONOSUPPORT; + return NULL; + } + + com_len += sizeof(*head) + index->l; + if ((buf = vmalloc(com_len)) == NULL) + errx(1, "Cannot allocate buffer"); + + head = (struct admin_com *)buf->v; + head->ac_len = buf->l; + head->ac_cmd = cmd; + head->ac_errno = 0; + head->ac_proto = proto; + + memcpy(buf->v+sizeof(*head), index->v, index->l); + + if (id && key) { + // overload com_len to track the number of unused bytes in buf->v + char *data; + acp = (struct admin_com_psk *) + (buf->v + sizeof(*head) + index->l); + com_len -= sizeof(*head) + index->l; + + acp->id_type = IDTYPE_USERFQDN; + acp->id_len = strlen(id) + 1; + acp->key_len = strlen(key) + 1; + + data = (char *)(acp + 1); + strlcpy(data, id, com_len); + + data = (char *)(data + acp->id_len); + com_len -= acp->id_len; + strlcpy(data, key, com_len); + } + + vfree(index); + return buf; } @@ -774,6 +903,72 @@ f_vpnc(ac, av) return f_exchangesa(nac, nav); } +// %%% testing +static vchar_t * +f_vpntest(ac, av) + int ac; + char **av; +{ + char *nav[] = {NULL, NULL, NULL, NULL, NULL, NULL}; + int nac = 0; + char *isakmp = "isakmp"; + char *inet = "inet"; + char *srcaddr; + struct addrinfo hints, *res; + struct sockaddr *src; + char *idx; + + if (ac < 1) + errx(1, "insufficient arguments"); + + evt_filter = (EVTF_LOOP|EVTF_CFG|EVTF_CFG_STOP|EVTF_ERR|EVTF_ERR_STOP); + time(&evt_start); + + /* Optional -u identity */ + if (strcmp(av[0], "-u") == 0) { + if (ac < 2) + errx(1, "-u require an argument"); + + nav[nac++] = av[0]; + nav[nac++] = av[1]; + + ac -= 2; + av += 2; + } + + if (ac < 1) + errx(1, "VPN gateway required"); + if (ac > 1) + warnx("Extra arguments"); + + /* + * Find the source address + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + if (getaddrinfo(av[0], "4500", &hints, &res) != 0) + errx(1, "Cannot resolve destination address"); + + if ((src = getlocaladdr(res->ai_addr)) == NULL) + errx(1, "cannot find source address"); + + if ((srcaddr = saddr2str(src)) == NULL) + errx(1, "cannot read source address"); + + /* We get "ip[port]" strip the port */ + if ((idx = index(srcaddr, '[')) == NULL) + errx(1, "unexpected source address format"); + *idx = '\0'; + + nav[nac++] = isakmp; + nav[nac++] = inet; + nav[nac++] = srcaddr; + nav[nac++] = av[0]; + + return f_exchangesa(nac, nav); +} + static vchar_t * f_vpnd(ac, av) int ac; @@ -785,7 +980,6 @@ f_vpnd(ac, av) char *inet = "inet"; char *anyaddr = "0.0.0.0"; char *idx; - vchar_t *buf, *index; if (ac < 1) errx(1, "VPN gateway required"); @@ -803,6 +997,39 @@ f_vpnd(ac, av) return f_deleteallsadst(nac, nav); } +#ifdef ENABLE_HYBRID +static vchar_t * +f_logoutusr(ac, av) + int ac; + char **av; +{ + vchar_t *buf; + struct admin_com *head; + char *user; + + /* need username */ + if (ac < 1) + errx(1, "insufficient arguments"); + user = av[0]; + if ((user == NULL) || ((strlen(user) + 1) > LOGINLEN)) + errx(1, "bad login (too long?)"); + + buf = vmalloc(sizeof(*head) + LOGINLEN); + if (buf == NULL) + return NULL; + + head = (struct admin_com *)buf->v; + head->ac_len = buf->l; + head->ac_cmd = ADMIN_LOGOUT_USER; + head->ac_errno = 0; + head->ac_proto = 0; + + strlcpy((char *)(head + 1), user, LOGINLEN); + + return buf; +} +#endif /* ENABLE_HYBRID */ + static int get_proto(str) @@ -959,28 +1186,34 @@ get_comindex(str, name, port, pref) *name = *port = *pref = NULL; - *name = strdup(str); + *name = racoon_strdup(str); + STRDUP_FATAL(*name); p = strpbrk(*name, "/["); if (p != NULL) { if (*(p + 1) == '\0') goto bad; if (*p == '/') { *p = '\0'; - *pref = strdup(p + 1); + *pref = racoon_strdup(p + 1); + STRDUP_FATAL(*pref); p = strchr(*pref, '['); if (p != NULL) { if (*(p + 1) == '\0') goto bad; *p = '\0'; - *port = strdup(p + 1); + *port = racoon_strdup(p + 1); + STRDUP_FATAL(*port); p = strchr(*pref, ']'); if (p == NULL) goto bad; *p = '\0'; } } else if (*p == '[') { + if (*pref == NULL) + goto bad; *p = '\0'; - *port = strdup(p + 1); + *port = racoon_strdup(p + 1); + STRDUP_FATAL(*port); p = strchr(*pref, ']'); if (p == NULL) goto bad; @@ -1369,7 +1602,8 @@ print_cfg(buf, len) memset(&addr4, 0, sizeof(addr4)); - if (evtdump->type != EVTT_ISAKMP_CFG_DONE) + if (evtdump->type != EVTT_ISAKMP_CFG_DONE && + evtdump->type != EVTT_NO_ISAKMP_CFG) return; len -= sizeof(*evtdump); @@ -1422,8 +1656,12 @@ print_cfg(buf, len) (n + sizeof(*attr) + ntohs(attr->lorv)); } } - - printf("Bound to address %s\n", inet_ntoa(addr4)); + + if (evtdump->type == EVTT_ISAKMP_CFG_DONE) + printf("Bound to address %s\n", inet_ntoa(addr4)); + else + printf("VPN connexion established\n"); + if (banner) { struct winsize win; int col = 0; @@ -1438,6 +1676,7 @@ print_cfg(buf, len) for (i = 0; i < col; i++) printf("%c", '='); printf("\n"); + racoon_free(banner); } if (evt_filter & EVTF_CFG_STOP) diff --git a/ipsec-tools/racoon/racoonctl.h b/ipsec-tools/racoon/racoonctl.h index 2b8b5a8..d507213 100644 --- a/ipsec-tools/racoon/racoonctl.h +++ b/ipsec-tools/racoon/racoonctl.h @@ -1,4 +1,6 @@ -/* $Id: racoonctl.h,v 1.2 2004/12/30 11:08:32 manubsd Exp $ */ +/* $NetBSD: racoonctl.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: racoonctl.h,v 1.3 2005/06/19 22:37:47 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -33,7 +35,7 @@ #define _RACOONCTL_H /* bumped on any change to the interface */ -#define RACOONCTL_INTERFACE 20041230 +#define RACOONCTL_INTERFACE 20050619 extern u_int32_t racoonctl_interface; /* bumped when introducing changes that break backward compatibility */ diff --git a/ipsec-tools/racoon/remoteconf.c b/ipsec-tools/racoon/remoteconf.c index 0185db6..c7790da 100644 --- a/ipsec-tools/racoon/remoteconf.c +++ b/ipsec-tools/racoon/remoteconf.c @@ -1,4 +1,6 @@ -/* $Id: remoteconf.c,v 1.26.2.5 2005/11/06 17:18:26 monas Exp $ */ +/* $NetBSD: remoteconf.c,v 1.9.4.1 2007/08/01 11:52:22 vanhu Exp $ */ + +/* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -60,18 +62,23 @@ #include "debug.h" #include "isakmp_var.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#endif #include "isakmp.h" #include "ipsec_doi.h" #include "oakley.h" #include "remoteconf.h" #include "localconf.h" #include "grabmyaddr.h" +#include "policy.h" #include "proposal.h" #include "vendorid.h" #include "gcmalloc.h" #include "strnames.h" #include "algorithm.h" #include "nattraversal.h" +#include "isakmp_frag.h" #include "genlist.h" #include "rsalist.h" @@ -81,7 +88,6 @@ static TAILQ_HEAD(_rmtree, remoteconf) rmtree; * Script hook names and script hook paths */ char *script_names[SCRIPT_MAX + 1] = { "phase1_up", "phase1_down" }; -vchar_t *script_paths = NULL; /*%%%*/ /* @@ -147,6 +153,11 @@ getrmconf_strict(remote, allow_anon) } TAILQ_FOREACH(p, &rmtree, chain) { +#ifdef __APPLE__ + if (p->to_delete || p->to_remove) { + continue; + } +#endif if ((remote->sa_family == AF_UNSPEC && remote->sa_family == p->remote->sa_family) || (!withport && cmpsaddrwop(remote, p->remote) == 0) @@ -173,6 +184,20 @@ getrmconf_strict(remote, allow_anon) return NULL; } +int +no_remote_configs() +{ + + struct remoteconf *p; + + TAILQ_FOREACH(p, &rmtree, chain) { + if (p->remote->sa_family == AF_UNSPEC) /* anonymous */ + continue; + return 0; + } + return 1; +} + struct remoteconf * getrmconf(remote) struct sockaddr *remote; @@ -180,6 +205,43 @@ getrmconf(remote) return getrmconf_strict(remote, 1); } +#ifdef __APPLE__ +int +link_rmconf_to_ph1 (struct remoteconf *new) +{ + if (!new) { + return(-1); + } + if (new->to_delete || + new->to_remove) { + return(-1); + } + new->linked_to_ph1++; + return(0); +} + +int +unlink_rmconf_from_ph1 (struct remoteconf *old) +{ + if (!old) { + return(-1); + } + if (old->linked_to_ph1 <= 0) { + return(-1); + } + old->linked_to_ph1--; + if (old->linked_to_ph1 == 0) { + if (old->to_remove) { + remrmconf(old); + } + if (old->to_delete) { + delrmconf(old); + } + } + return(0); +} +#endif + struct remoteconf * newrmconf() { @@ -209,18 +271,23 @@ newrmconf() new->getcert_method = ISAKMP_GETCERT_PAYLOAD; new->getcacert_method = ISAKMP_GETCERT_LOCALFILE; new->cacerttype = ISAKMP_CERT_X509SIGN; + new->certtype = ISAKMP_CERT_NONE; new->cacertfile = NULL; new->send_cert = TRUE; new->send_cr = TRUE; new->support_proxy = FALSE; for (i = 0; i <= SCRIPT_MAX; i++) - new->script[i] = -1; + new->script[i] = NULL; new->gen_policy = FALSE; new->retry_counter = lcconf->retry_counter; new->retry_interval = lcconf->retry_interval; #ifdef __APPLE__ new->nat_traversal = NATT_ON; new->natt_multiple_user = FALSE; + new->natt_keepalive = TRUE; + new->to_remove = FALSE; + new->to_delete = FALSE; + new->linked_to_ph1 = 0; #else new->nat_traversal = NATT_OFF; #endif @@ -233,7 +300,15 @@ newrmconf() new->dpd_interval = 0; /* Disable DPD checks by default */ new->dpd_retry = 5; new->dpd_maxfails = 5; + new->dpd_algo = DPD_ALGO_INBOUND_DETECT; + new->idle_timeout = 0; + new->weak_phase1_check = 0; + +#ifdef ENABLE_HYBRID + new->xauth = NULL; +#endif + new->initiate_ph1rekey = TRUE; return new; } @@ -266,8 +341,10 @@ dupidvl(entry, arg) id = newidspec(); if (!id) return (void *) -1; - if (set_identifier(&id->id, old->idtype, old->id) != 0) + if (set_identifier(&id->id, old->idtype, old->id) != 0) { + racoon_free(id); return (void *) -1; + } id->idtype = old->idtype; @@ -338,10 +415,22 @@ void delrmconf(rmconf) struct remoteconf *rmconf; { +#ifdef __APPLE__ + if (rmconf->linked_to_ph1) { + rmconf->to_delete = TRUE; + return; + } +#endif if (rmconf->remote) racoon_free(rmconf->remote); - if (rmconf->etypes) +#ifdef ENABLE_HYBRID + if (rmconf->xauth) + xauth_rmconf_delete(&rmconf->xauth); +#endif + if (rmconf->etypes) { deletypes(rmconf->etypes); + rmconf->etypes=NULL; + } if (rmconf->idv) vfree(rmconf->idv); if (rmconf->idvl_p) @@ -436,6 +525,12 @@ void remrmconf(rmconf) struct remoteconf *rmconf; { +#ifdef __APPLE__ + if (rmconf->linked_to_ph1) { + rmconf->to_remove = TRUE; + return; + } +#endif TAILQ_REMOVE(&rmtree, rmconf, chain); } @@ -622,7 +717,8 @@ dump_rmconf_single (struct remoteconf *p, void *data) plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n", s_switch (p->passive)); plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n", - s_switch (p->ike_frag)); + p->ike_frag == ISAKMP_FRAG_FORCE ? + "force" : s_switch (p->ike_frag)); plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag); plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n", s_switch (p->ini_contact)); @@ -678,13 +774,13 @@ newidspec() return new; } -int +vchar_t * script_path_add(path) vchar_t *path; { char *script_dir; - vchar_t *new_storage; vchar_t *new_path; + vchar_t *new_storage; vchar_t **sp; size_t len; size_t size; @@ -698,44 +794,24 @@ script_path_add(path) if ((new_path = vmalloc(len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory: %s\n", strerror(errno)); - return -1; + return NULL; } new_path->v[0] = '\0'; - (void)strlcat(new_path->v, script_dir, len); - (void)strlcat(new_path->v, "/", len); - (void)strlcat(new_path->v, path->v, len); + (void)strlcat(new_path->v, script_dir, new_path->l); + (void)strlcat(new_path->v, "/", new_path->l); + (void)strlcat(new_path->v, path->v, new_path->l); vfree(path); path = new_path; } - /* First time, initialize */ - if (script_paths == NULL) - len = sizeof(vchar_t *); - else - len = script_paths->l; - - /* Add a slot for a new path */ - len += sizeof(vchar_t *); - if ((new_storage = vrealloc(script_paths, len)) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "Cannot allocate memory: %s\n", strerror(errno)); - return -1; - } - script_paths = new_storage; - - size = len / sizeof(vchar_t *); - sp = (vchar_t **)script_paths->v; - sp[size - 1] = NULL; - sp[size - 2] = path; - - return (size - 2); + return path; } + struct isakmpsa * -dupisakmpsa(sa) - struct isakmpsa *sa; +dupisakmpsa(struct isakmpsa *sa) { struct isakmpsa *res = NULL; @@ -748,9 +824,7 @@ dupisakmpsa(sa) *res = *sa; #ifdef HAVE_GSSAPI - /* - * XXX gssid - */ + res->gssid=vdup(sa->gssid); #endif res->next=NULL; diff --git a/ipsec-tools/racoon/remoteconf.h b/ipsec-tools/racoon/remoteconf.h index 0a9d485..ee171da 100644 --- a/ipsec-tools/racoon/remoteconf.h +++ b/ipsec-tools/racoon/remoteconf.h @@ -1,4 +1,6 @@ -/* $Id: remoteconf.h,v 1.19.2.1 2005/05/20 00:37:42 manubsd Exp $ */ +/* $NetBSD: remoteconf.h,v 1.7 2006/10/03 08:01:56 vanhu Exp $ */ + +/* Id: remoteconf.h,v 1.26 2006/05/06 15:52:44 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -36,11 +38,16 @@ #include #include "genlist.h" +#ifdef ENABLE_HYBRID +#include "isakmp_var.h" +#include "isakmp_xauth.h" +#endif #ifdef __APPLE__ #include #endif #include "algorithm.h" + struct proposalspec { time_t lifetime; /* for isakmp/ipsec */ int lifebyte; /* for isakmp/ipsec */ @@ -75,12 +82,18 @@ struct etypes { struct etypes *next; }; +enum { + DPD_ALGO_DEFAULT = 0, + DPD_ALGO_INBOUND_DETECT, + DPD_ALGO_BLACKHOLE_DETECT, + DPD_ALGO_MAX, +}; + /* Script hooks */ #define SCRIPT_PHASE1_UP 0 #define SCRIPT_PHASE1_DOWN 1 #define SCRIPT_MAX 1 extern char *script_names[SCRIPT_MAX + 1]; -extern vchar_t *script_paths; struct remoteconf { struct sockaddr *remote; /* remote IP address */ @@ -127,14 +140,18 @@ struct remoteconf { int esp_frag; /* ESP fragmentation */ int mode_cfg; /* Gets config through mode config */ int support_proxy; /* support mip6/proxy */ +#define GENERATE_POLICY_NONE 0 +#define GENERATE_POLICY_REQUIRE 1 +#define GENERATE_POLICY_UNIQUE 2 int gen_policy; /* generate policy if no policy found */ int ini_contact; /* initial contact */ int pcheck_level; /* level of propocl checking */ int nat_traversal; /* NAT-Traversal */ #ifdef __APPLE__ int natt_multiple_user; /* special handling of multiple users behind a nat - for VPN server */ + int natt_keepalive; /* do we need to send natt keep alive */ #endif - int script[SCRIPT_MAX + 1]; /* script hooks index in script_paths */ + vchar_t *script[SCRIPT_MAX + 1]; /* script hooks paths */ int dh_group; /* use it when only aggressive mode */ struct dhgroup *dhgrp; /* use it when only aggressive mode */ /* above two can't be defined by user*/ @@ -146,7 +163,14 @@ struct remoteconf { int dpd; /* Negociate DPD support ? */ int dpd_retry; /* in seconds */ int dpd_interval; /* in seconds */ - int dpd_maxfails; + int dpd_maxfails; + int dpd_algo; + int idle_timeout; /* in seconds */ + int idle_timeout_dir; /* direction to check */ + + int ph1id; /* ph1id to be matched with sainfo sections */ + + int weak_phase1_check; /* act on unencrypted deletions ? */ struct isakmpsa *proposal; /* proposal list */ struct remoteconf *inherited_from; /* the original rmconf @@ -156,6 +180,18 @@ struct remoteconf { struct genlist *rsa_private, /* lists of PlainRSA keys to use */ *rsa_public; + +#ifdef ENABLE_HYBRID + struct xauth_rmconf *xauth; +#endif + int initiate_ph1rekey; + +#ifdef __APPLE__ + int to_remove; + int to_delete; + int linked_to_ph1; +#endif + TAILQ_ENTRY(remoteconf) chain; /* next remote conf */ }; @@ -192,6 +228,12 @@ typedef struct remoteconf * (rmconf_func_t)(struct remoteconf *rmconf, void *dat extern struct remoteconf *getrmconf __P((struct sockaddr *)); extern struct remoteconf *getrmconf_strict __P((struct sockaddr *remote, int allow_anon)); + +#ifdef __APPLE__ +extern int link_rmconf_to_ph1 __P((struct remoteconf *)); +extern int unlink_rmconf_from_ph1 __P((struct remoteconf *)); +#endif +extern int no_remote_configs __P((void)); extern struct remoteconf *copyrmconf __P((struct sockaddr *)); extern struct remoteconf *newrmconf __P((void)); extern struct remoteconf *duprmconf __P((struct remoteconf *)); @@ -217,7 +259,7 @@ extern void dumprmconf __P((void)); extern struct idspec *newidspec __P((void)); -extern int script_path_add __P((vchar_t *)); +extern vchar_t *script_path_add __P((vchar_t *)); extern void rsa_key_free __P((void *entry)); diff --git a/ipsec-tools/racoon/rsalist.c b/ipsec-tools/racoon/rsalist.c index 3db208d..850aa4c 100644 --- a/ipsec-tools/racoon/rsalist.c +++ b/ipsec-tools/racoon/rsalist.c @@ -1,4 +1,6 @@ -/* $Id: rsalist.c,v 1.3 2004/11/08 12:04:23 ludvigm Exp $ */ +/* $NetBSD: rsalist.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: rsalist.c,v 1.3 2004/11/08 12:04:23 ludvigm Exp */ /* * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. diff --git a/ipsec-tools/racoon/rsalist.h b/ipsec-tools/racoon/rsalist.h index 4ee4c4c..911670f 100644 --- a/ipsec-tools/racoon/rsalist.h +++ b/ipsec-tools/racoon/rsalist.h @@ -1,4 +1,6 @@ -/* $Id: rsalist.h,v 1.2 2004/07/12 20:43:51 ludvigm Exp $ */ +/* $NetBSD: rsalist.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: rsalist.h,v 1.2 2004/07/12 20:43:51 ludvigm Exp */ /* * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. * Contributed by: Michal Ludvig , SUSE Labs diff --git a/ipsec-tools/racoon/safefile.c b/ipsec-tools/racoon/safefile.c index b698fa7..5241092 100644 --- a/ipsec-tools/racoon/safefile.c +++ b/ipsec-tools/racoon/safefile.c @@ -1,3 +1,5 @@ +/* $NetBSD: safefile.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + /* $KAME: safefile.c,v 1.5 2001/03/05 19:54:06 thorpej Exp $ */ /* diff --git a/ipsec-tools/racoon/safefile.h b/ipsec-tools/racoon/safefile.h index 2651e7e..c8d6a6c 100644 --- a/ipsec-tools/racoon/safefile.h +++ b/ipsec-tools/racoon/safefile.h @@ -1,4 +1,6 @@ -/* $Id: safefile.h,v 1.4 2004/07/12 18:32:12 ludvigm Exp $ */ +/* $NetBSD: safefile.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: safefile.h,v 1.4 2004/07/12 18:32:12 ludvigm Exp */ /* * Copyright (C) 2000 WIDE Project. diff --git a/ipsec-tools/racoon/sainfo.c b/ipsec-tools/racoon/sainfo.c index 502914b..87093ab 100644 --- a/ipsec-tools/racoon/sainfo.c +++ b/ipsec-tools/racoon/sainfo.c @@ -90,10 +90,32 @@ getsainfo(src, dst, peer, use_nat_addr) if (use_nat_addr && lcconf->ext_nat_id == NULL) return NULL; + plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - src id:\n"); + if (src != NULL) + plogdump(LLV_DEBUG2, src->v, src->l); + else + plog(LLV_DEBUG2, LOCATION, NULL, " anonymous\n"); + plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - dst id:\n"); + if (dst != NULL) + plogdump(LLV_DEBUG2, dst->v, dst->l); + else + plog(LLV_DEBUG2, LOCATION, NULL, " anonymous\n"); if (peer == NULL) pass = 2; again: LIST_FOREACH(s, &sitree, chain) { +#ifdef __APPLE__ + if (s->to_delete || s->to_remove) { + continue; + } +#endif /* __APPLE__ */ + if (s->idsrc != NULL) { + plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - sainfo id - src & dst:\n"); + plogdump(LLV_DEBUG2, s->idsrc->v, s->idsrc->l); + plogdump(LLV_DEBUG2, s->iddst->v, s->iddst->l); + } else { + plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo - sainfo id = anonymous\n"); + } if (s->id_i != NULL) { if (pass == 2) continue; @@ -115,8 +137,12 @@ getsainfo(src, dst, peer, use_nat_addr) if (memcmp(src->v, s->idsrc->v, s->idsrc->l) == 0) { if (use_nat_addr) { - if (memcmp(lcconf->ext_nat_id->v, s->iddst->v, s->iddst->l) == 0) + if (memcmp(lcconf->ext_nat_id->v, s->iddst->v, s->iddst->l) == 0) { + plog(LLV_DEBUG, LOCATION, NULL, + "matched external nat address.\n"); + plogdump(LLV_DEBUG2, lcconf->ext_nat_id->v, lcconf->ext_nat_id->l); return s; + } } else if (memcmp(dst->v, s->iddst->v, s->iddst->l) == 0) return s; } @@ -133,6 +159,43 @@ getsainfo(src, dst, peer, use_nat_addr) return anonymous; } +#ifdef __APPLE__ +int +link_sainfo_to_ph2 (struct sainfo *new) +{ + if (!new) { + return(-1); + } + if (new->to_delete || + new->to_remove) { + return(-1); + } + new->linked_to_ph2++; + return(0); +} + +int +unlink_sainfo_from_ph2 (struct sainfo *old) +{ + if (!old) { + return(-1); + } + if (old->linked_to_ph2 <= 0) { + return(-1); + } + old->linked_to_ph2--; + if (old->linked_to_ph2 == 0) { + if (old->to_remove) { + remsainfo(old); + } + if (old->to_delete) { + delsainfo(old); + } + } + return(0); +} +#endif + struct sainfo * newsainfo() { @@ -144,6 +207,11 @@ newsainfo() new->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; new->lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX; +#ifdef __APPLE__ + new->to_remove = FALSE; + new->to_delete = FALSE; + new->linked_to_ph2 = 0; +#endif return new; } @@ -154,6 +222,13 @@ delsainfo(si) { int i; +#ifdef __APPLE__ + if (si->linked_to_ph2) { + si->to_delete = TRUE; + return; + } +#endif + for (i = 0; i < MAXALGCLASS; i++) delsainfoalg(si->algs[i]); @@ -162,6 +237,11 @@ delsainfo(si) if (si->iddst) vfree(si->iddst); +#ifdef ENABLE_HYBRID + if (si->group) + vfree(si->group); +#endif + racoon_free(si); } @@ -176,6 +256,12 @@ void remsainfo(si) struct sainfo *si; { +#ifdef __APPLE__ + if (si->linked_to_ph2) { + si->to_remove = TRUE; + return; + } +#endif LIST_REMOVE(si, chain); } @@ -186,8 +272,24 @@ flushsainfo() for (s = LIST_FIRST(&sitree); s; s = next) { next = LIST_NEXT(s, chain); - remsainfo(s); - delsainfo(s); + if (s->dynamic == 0) { + remsainfo(s); + delsainfo(s); + } + } +} + +void +flushsainfo_dynamic(u_int32_t addr) +{ + struct sainfo *s, *next; + + for (s = LIST_FIRST(&sitree); s; s = next) { + next = LIST_NEXT(s, chain); + if (s->dynamic == addr) { + remsainfo(s); + delsainfo(s); + } } } @@ -240,19 +342,35 @@ const char * sainfo2str(si) const struct sainfo *si; { + char *idsrc_str; + char *iddst_str; + char *idi_str; static char buf[256]; if (si->idsrc == NULL) snprintf(buf, sizeof(buf), "anonymous"); else { - snprintf(buf, sizeof(buf), "%s", ipsecdoi_id2str(si->idsrc)); - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " %s", ipsecdoi_id2str(si->iddst)); + idsrc_str = ipsecdoi_id2str(si->idsrc); + if (idsrc_str) { + snprintf(buf, sizeof(buf), "%s", idsrc_str); + racoon_free(idsrc_str); + } + iddst_str = ipsecdoi_id2str(si->iddst); + if (iddst_str) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " %s", iddst_str); + racoon_free(iddst_str); + } } - if (si->id_i != NULL) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " from %s", ipsecdoi_id2str(si->id_i)); + if (si->id_i != NULL) { + idi_str = ipsecdoi_id2str(si->id_i); + if (idi_str) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " from %s", idi_str); + racoon_free(idi_str); + } + } return buf; } diff --git a/ipsec-tools/racoon/sainfo.h b/ipsec-tools/racoon/sainfo.h index 77fff23..c9bf7f0 100644 --- a/ipsec-tools/racoon/sainfo.h +++ b/ipsec-tools/racoon/sainfo.h @@ -1,4 +1,6 @@ -/* $Id: sainfo.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp $ */ +/* $NetBSD: sainfo.h,v 1.5 2006/10/03 08:01:56 vanhu Exp $ */ + +/* Id: sainfo.h,v 1.5 2006/07/09 17:19:38 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -44,29 +46,43 @@ struct sainfo { * If idsrc == NULL, that is anonymous entry. */ +#ifdef ENABLE_HYBRID + vchar_t *group; +#endif + time_t lifetime; int lifebyte; int pfs_group; /* only use when pfs is required. */ vchar_t *id_i; /* identifier of the authorized initiator */ struct sainfoalg *algs[MAXALGCLASS]; - + int dynamic; /* created through vpn control socket */ +#ifdef __APPLE__ + int to_remove; + int to_delete; + int linked_to_ph2; +#endif LIST_ENTRY(sainfo) chain; }; /* algorithm type */ struct sainfoalg { int alg; - int encklen; /* key length if encryption algorithm */ + int encklen; /* key length of encryption algorithm */ struct sainfoalg *next; }; extern struct sainfo *getsainfo __P((const vchar_t *, const vchar_t *, const vchar_t *, int)); +#ifdef __APPLE__ +extern int link_sainfo_to_ph2 __P((struct sainfo *)); +extern int unlink_sainfo_from_ph2 __P((struct sainfo *)); +#endif extern struct sainfo *newsainfo __P((void)); extern void delsainfo __P((struct sainfo *)); extern void inssainfo __P((struct sainfo *)); extern void remsainfo __P((struct sainfo *)); extern void flushsainfo __P((void)); +extern void flushsainfo_dynamic __P((u_int32_t)); extern void initsainfo __P((void)); extern struct sainfoalg *newsainfoalg __P((void)); extern void delsainfoalg __P((struct sainfoalg *)); diff --git a/ipsec-tools/racoon/schedule.c b/ipsec-tools/racoon/schedule.c index 705f4ce..74f5f20 100644 --- a/ipsec-tools/racoon/schedule.c +++ b/ipsec-tools/racoon/schedule.c @@ -1,3 +1,5 @@ +/* $NetBSD: schedule.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + /* $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $ */ /* @@ -56,6 +58,7 @@ for (elm = TAILQ_FIRST(head); elm; elm = TAILQ_NEXT(elm, field)) #endif +extern int terminated; static struct timeval timeout; #ifdef FIXY2038PROBLEM @@ -83,7 +86,7 @@ schedular() now = current_time(); - for (p = TAILQ_FIRST(&sctree); p; p = next) { + for (p = TAILQ_FIRST(&sctree); p; p = next) { /* if the entry has been dead, remove it */ if (p->dead) goto next_schedule; @@ -96,7 +99,7 @@ schedular() /* mark it with dead. and call the function. */ p->dead = 1; - if (p->func != NULL) + if (p->func != NULL && !terminated) (p->func)(p->param); next_schedule: @@ -308,7 +311,7 @@ getstdin() struct scheddump *scbuf, *p; int len; sched_dump((caddr_t *)&scbuf, &len); - if (buf == NULL) + if (scbuf == NULL) return; for (p = scbuf; len; p++) { printf("xtime=%ld\n", p->xtime); diff --git a/ipsec-tools/racoon/schedule.h b/ipsec-tools/racoon/schedule.h index bb2df2b..bd66593 100644 --- a/ipsec-tools/racoon/schedule.h +++ b/ipsec-tools/racoon/schedule.h @@ -1,4 +1,6 @@ -/* $Id: schedule.h,v 1.4 2004/11/18 15:14:44 ludvigm Exp $ */ +/* $NetBSD: schedule.h,v 1.4.6.1 2007/03/21 14:29:48 vanhu Exp $ */ + +/* Id: schedule.h,v 1.5 2006/05/03 21:53:42 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -33,7 +35,7 @@ #define _SCHEDULE_H #include -#include +#include "gnuc.h" /* scheduling table */ /* the head is the nearest event. */ @@ -57,8 +59,10 @@ struct sched { /* cancel schedule */ #define SCHED_KILL(s) \ do { \ - sched_kill(s); \ - s = NULL; \ + if(s != NULL){ \ + sched_kill(s); \ + s = NULL; \ + }\ } while(0) /* must be called after it's called from scheduler. */ diff --git a/ipsec-tools/racoon/session.c b/ipsec-tools/racoon/session.c index 2f9f557..bcc4ad0 100644 --- a/ipsec-tools/racoon/session.c +++ b/ipsec-tools/racoon/session.c @@ -1,3 +1,5 @@ +/* $NetBSD: session.c,v 1.7.6.2 2007/08/01 11:52:22 vanhu Exp $ */ + /* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */ /* @@ -62,6 +64,13 @@ #include #include +#include +#include +#include + +#include +#include + #include "libpfkey.h" #include "var.h" @@ -76,6 +85,8 @@ #include "evt.h" #include "cfparse_proto.h" #include "isakmp_var.h" +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" #include "admin_var.h" #include "admin.h" #include "privsep.h" @@ -90,6 +101,11 @@ #endif #include "vpn_control_var.h" #include "policy.h" +#include "algorithm.h" /* XXX ??? */ + +#include "sainfo.h" + + extern pid_t racoon_pid; static void close_session __P((void)); @@ -109,6 +125,7 @@ static int nfds = 0; static volatile sig_atomic_t sigreq[NSIG + 1]; static int dying = 0; static struct sched *check_rtsock_sched = NULL; +int terminated = 0; int session(void) @@ -126,7 +143,11 @@ session(void) initmyaddr(); +#ifndef __APPLE__ if (isakmp_init() < 0) { +#else + if (isakmp_init(false) < 0) { +#endif /* __APPLE__ */ plog(LLV_ERROR2, LOCATION, NULL, "failed to initialize isakmp"); exit(1); @@ -145,6 +166,7 @@ session(void) "failed to initialize vpn control port"); exit(1); } + #endif init_signal(); @@ -169,12 +191,12 @@ session(void) if (!f_foreground) { racoon_pid = getpid(); if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) - strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN); + strlcpy(pid_file, _PATH_VARRUN "racoon.pid", sizeof(pid_file)); else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') - strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); + strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file)); else { - strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN); - strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); + strlcat(pid_file, _PATH_VARRUN, sizeof(pid_file)); + strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], sizeof(pid_file)); } fp = fopen(pid_file, "w"); if (fp) { @@ -191,7 +213,7 @@ session(void) "cannot open %s", pid_file); } } - + while (1) { if (!TAILQ_EMPTY(&lcconf->saved_msg_queue)) pfkey_post_handler(); @@ -218,7 +240,17 @@ session(void) plog(LLV_ERROR2, LOCATION, NULL, "failed select (%s)\n", strerror(errno)); - exit(1); + /* serious socket problem - close all listening sockets and re-open */ + if (lcconf->autograbaddr) { + isakmp_close(); + initfds(); + sched_new(5, check_rtsock, NULL); + } else { + isakmp_close_sockets(); + isakmp_open(); + initfds(); + } + continue; } /*NOTREACHED*/ } @@ -249,7 +281,7 @@ session(void) update_fds = 1; // socket closed by peer - update mask } } -#endif +#endif for (p = lcconf->myaddrs; p; p = p->next) { if (!p->addr) @@ -294,7 +326,9 @@ session(void) static void close_session() { - flushph1(); + if ( terminated ) + flushph2(false); + flushph1(false); close_sockets(); backupsa_clean(); @@ -367,7 +401,6 @@ initfds() } } } - #endif if (lcconf->sock_pfkey >= FD_SETSIZE) { @@ -385,7 +418,7 @@ initfds() FD_SET(lcconf->rtsock, &mask0); nfds = (nfds > lcconf->rtsock ? nfds : lcconf->rtsock); } - + for (p = lcconf->myaddrs; p; p = p->next) { if (!p->addr) continue; @@ -401,6 +434,7 @@ initfds() nfds++; } + static int signals[] = { SIGHUP, SIGINT, @@ -424,6 +458,9 @@ signal_handler(sig) * values to 0/1 */ sigreq[sig]++; + if ( sig == SIGTERM ){ + terminated = 1; + } } static void @@ -469,11 +506,23 @@ check_sigreq() break; #endif + case SIGUSR1: case SIGHUP: +#ifdef ENABLE_HYBRID + if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "ISAKMP mode config structure reset failed, " + "not reloading\n"); + return; + } +#endif + if ( terminated ) + break; + /* Save old configuration, load new one... */ isakmp_close(); close(lcconf->rtsock); - if (cfreparse()) { + if (cfreparse(sig)) { plog(LLV_ERROR2, LOCATION, NULL, "configuration read failed\n"); exit(1); @@ -483,8 +532,24 @@ check_sigreq() initmyaddr(); isakmp_cleanup(); +#ifdef __APPLE__ + isakmp_init(true); +#else isakmp_init(); +#endif /* __APPLE__ */ initfds(); +#if TARGET_OS_EMBEDDED + if (no_remote_configs()) { + EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); + pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC); +#ifdef ENABLE_FASTQUIT + close_session(); +#else + sched_new(1, check_flushsa_stub, NULL); +#endif + dying = 1; + } +#endif break; case SIGINT: @@ -494,8 +559,14 @@ check_sigreq() EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC); - sched_new(1, check_flushsa_stub, NULL); - dying = 1; + if ( sig == SIGTERM ){ + terminated = 1; /* in case if it hasn't been set yet */ + close_session(); + } + else + sched_new(1, check_flushsa_stub, NULL); + + dying = 1; break; default: @@ -579,12 +650,18 @@ check_flushsa() } close_session(); +#if !TARGET_OS_EMBEDDED + if (lcconf->vt) + vproc_transaction_end(NULL, lcconf->vt); +#endif } void auto_exit_do(void *p) { EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); + plog(LLV_DEBUG, LOCATION, NULL, + "performing auto exit\n"); pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC); sched_new(1, check_flushsa_stub, NULL); dying = 1; @@ -593,15 +670,14 @@ auto_exit_do(void *p) void check_auto_exit(void) { - if (lcconf->auto_exit_sched != NULL) { /* exit scheduled? */ if (lcconf->auto_exit_state != LC_AUTOEXITSTATE_ENABLED || vpn_control_connected() /* vpn control connected */ - || policies_installed()) /* policies installed in kernel */ + || policies_installed()) /* policies installed in kernel */ SCHED_KILL(lcconf->auto_exit_sched); } else { /* exit not scheduled */ if (lcconf->auto_exit_state == LC_AUTOEXITSTATE_ENABLED - && !vpn_control_connected() + && !vpn_control_connected() && !policies_installed()) if (lcconf->auto_exit_delay == 0) auto_exit_do(NULL); /* immediate exit */ @@ -659,3 +735,4 @@ close_sockets() return 0; } + diff --git a/ipsec-tools/racoon/session.h b/ipsec-tools/racoon/session.h index 6625b0b..f410be9 100644 --- a/ipsec-tools/racoon/session.h +++ b/ipsec-tools/racoon/session.h @@ -32,6 +32,8 @@ #ifndef _SESSION_H #define _SESSION_H +#include "handler.h" + extern int session __P((void)); extern RETSIGTYPE signal_handler __P((int)); extern void check_auto_exit __P((void)); diff --git a/ipsec-tools/racoon/sockmisc.c b/ipsec-tools/racoon/sockmisc.c index 14399cc..98d0a69 100644 --- a/ipsec-tools/racoon/sockmisc.c +++ b/ipsec-tools/racoon/sockmisc.c @@ -43,7 +43,8 @@ #include #endif -#if defined(IP_RECVDSTADDR) && !defined(IPV6_RECVDSTADDR) +#if defined(INET6) && !defined(INET6_ADVAPI) && \ + defined(IP_RECVDSTADDR) && !defined(IPV6_RECVDSTADDR) #define IPV6_RECVDSTADDR IP_RECVDSTADDR #endif @@ -61,6 +62,7 @@ #include "sockmisc.h" #include "debug.h" #include "gcmalloc.h" +#include "debugrm.h" #include "libpfkey.h" #ifndef IP_IPSEC_POLICY @@ -320,7 +322,7 @@ recvfromto(s, buf, buflen, flags, from, fromlen, to, tolen) u_int len; struct sockaddr_storage ss; struct msghdr m; - struct cmsghdr *cm; + struct cmsghdr *cm, *cm_prev; struct iovec iov[2]; u_char cmsgbuf[256]; #if defined(INET6) && defined(INET6_ADVAPI) @@ -352,14 +354,16 @@ recvfromto(s, buf, buflen, flags, from, fromlen, to, tolen) plog(LLV_ERROR, LOCATION, NULL, "recvmsg (%s)\n", strerror(errno)); return -1; + } else if (len == 0) { + return 0; } *fromlen = m.msg_namelen; otolen = *tolen; *tolen = 0; - for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m); - m.msg_controllen != 0 && cm; - cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) { + for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m), cm_prev = NULL; + m.msg_controllen != 0 && cm && cm != cm_prev; + cm_prev = cm, cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) { #if 0 plog(LLV_ERROR, LOCATION, NULL, "cmsg %d %d\n", cm->cmsg_level, cm->cmsg_type);) @@ -650,7 +654,8 @@ sendfromto(s, buf, buflen, src, dst, cnt) #endif (void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt SO_REUSEPORT (%s)\n", + strerror(errno)); close(sendsock); return -1; } @@ -659,7 +664,8 @@ sendfromto(s, buf, buflen, src, dst, cnt) setsockopt(sendsock, IPPROTO_IPV6, IPV6_USE_MIN_MTU, (void *)&yes, sizeof(yes)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", strerror(errno)); + "setsockopt IPV6_USE_MIN_MTU (%s)\n", + strerror(errno)); close(sendsock); return -1; } @@ -738,7 +744,7 @@ setsockopt_bypass(so, family) IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), buf, ipsec_get_policylen(buf)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", + "setsockopt IP_IPSEC_POLICY (%s)\n", strerror(errno)); return -1; } @@ -757,7 +763,7 @@ setsockopt_bypass(so, family) IP_IPSEC_POLICY : IPV6_IPSEC_POLICY), buf, ipsec_get_policylen(buf)) < 0) { plog(LLV_ERROR, LOCATION, NULL, - "setsockopt (%s)\n", + "setsockopt IP_IPSEC_POLICY (%s)\n", strerror(errno)); return -1; } @@ -772,10 +778,11 @@ newsaddr(len) { struct sockaddr *new; - new = racoon_calloc(1, len); - if (new == NULL) + if ((new = racoon_calloc(1, len)) == NULL) { plog(LLV_ERROR, LOCATION, NULL, "%s\n", strerror(errno)); + goto out; + } #ifdef __linux__ if (len == sizeof (struct sockaddr_in6)) @@ -786,7 +793,7 @@ newsaddr(len) /* initial */ new->sa_len = len; #endif - +out: return new; } @@ -869,8 +876,10 @@ naddrwop2str_fromto(const char *format, const struct netaddr *saddr, static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; char *src, *dst; - src = strdup(naddrwop2str(saddr)); - dst = strdup(naddrwop2str(daddr)); + src = racoon_strdup(naddrwop2str(saddr)); + dst = racoon_strdup(naddrwop2str(daddr)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); /* WARNING: Be careful about the format string! Don't ever pass in something that a user can modify!!! */ snprintf (buf, sizeof(buf), format, src, dst); @@ -889,8 +898,10 @@ saddr2str_fromto(format, saddr, daddr) static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100]; char *src, *dst; - src = strdup(saddr2str(saddr)); - dst = strdup(saddr2str(daddr)); + src = racoon_strdup(saddr2str(saddr)); + dst = racoon_strdup(saddr2str(daddr)); + STRDUP_FATAL(src); + STRDUP_FATAL(dst); /* WARNING: Be careful about the format string! Don't ever pass in something that a user can modify!!! */ snprintf (buf, sizeof(buf), format, src, dst); @@ -995,7 +1006,7 @@ naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr) { static const struct netaddr naddr_any; /* initialized to all-zeros */ struct sockaddr sa; - uint16_t naddr_port, saddr_port; + u_int16_t naddr_port, saddr_port; int port_score; if (!naddr || !saddr) { @@ -1027,9 +1038,12 @@ naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr) mask_sockaddr(&sa, saddr, naddr->prefix); if (loglevel >= LLV_DEBUG) { /* debug only */ char *a1, *a2, *a3; - a1 = strdup(naddrwop2str(naddr)); - a2 = strdup(saddrwop2str(saddr)); - a3 = strdup(saddrwop2str(&sa)); + a1 = racoon_strdup(naddrwop2str(naddr)); + a2 = racoon_strdup(saddrwop2str(saddr)); + a3 = racoon_strdup(saddrwop2str(&sa)); + STRDUP_FATAL(a1); + STRDUP_FATAL(a2); + STRDUP_FATAL(a3); plog(LLV_DEBUG, LOCATION, NULL, "naddr=%s, saddr=%s (masked=%s)\n", a1, a2, a3); diff --git a/ipsec-tools/racoon/sockmisc.h b/ipsec-tools/racoon/sockmisc.h index 828c0b4..5c940d6 100644 --- a/ipsec-tools/racoon/sockmisc.h +++ b/ipsec-tools/racoon/sockmisc.h @@ -49,8 +49,10 @@ extern int cmpsaddrstrict __P((const struct sockaddr *, const struct sockaddr *) #ifdef ENABLE_NATT #define CMPSADDR(saddr1, saddr2) cmpsaddrstrict((saddr1), (saddr2)) +#define CMPSADDR2(saddr1, saddr2) cmpsaddrwild((saddr1), (saddr2)) #else #define CMPSADDR(saddr1, saddr2) cmpsaddrwop((saddr1), (saddr2)) +#define CMPSADDR2(saddr1, saddr2) cmpsaddrwop((saddr1), (saddr2)) #endif extern struct sockaddr *getlocaladdr __P((struct sockaddr *)); diff --git a/ipsec-tools/racoon/strnames.c b/ipsec-tools/racoon/strnames.c index 34562ee..ad6fea3 100644 --- a/ipsec-tools/racoon/strnames.c +++ b/ipsec-tools/racoon/strnames.c @@ -1,3 +1,5 @@ +/* $NetBSD: strnames.c,v 1.7.6.1 2007/08/01 11:52:22 vanhu Exp $ */ + /* $KAME: strnames.c,v 1.25 2003/11/13 10:53:26 itojun Exp $ */ /* @@ -45,6 +47,9 @@ #include #include +#ifdef ENABLE_HYBRID +#include +#endif #include "var.h" #include "misc.h" @@ -53,6 +58,11 @@ #include "isakmp_var.h" #include "isakmp.h" +#ifdef ENABLE_HYBRID +# include "isakmp_xauth.h" +# include "isakmp_unity.h" +# include "isakmp_cfg.h" +#endif #include "ipsec_doi.h" #include "oakley.h" #include "handler.h" @@ -218,6 +228,7 @@ static struct ksmap name_isakmp_etype[] = { { ISAKMP_ETYPE_AUTH, "Authentication Only", NULL }, { ISAKMP_ETYPE_AGG, "Aggressive", NULL }, { ISAKMP_ETYPE_INFO, "Informational", NULL }, +{ ISAKMP_ETYPE_CFG, "Mode config", NULL }, { ISAKMP_ETYPE_QUICK, "Quick", NULL }, { ISAKMP_ETYPE_NEWGRP, "New Group", NULL }, { ISAKMP_ETYPE_ACKINFO, "Acknowledged Informational", NULL }, @@ -269,6 +280,9 @@ static struct ksmap name_isakmp_notify_msg[] = { { ISAKMP_NTYPE_RESPONDER_LIFETIME, "RESPONDER-LIFETIME", NULL }, { ISAKMP_NTYPE_REPLAY_STATUS, "REPLAY-STATUS", NULL }, { ISAKMP_NTYPE_INITIAL_CONTACT, "INITIAL-CONTACT", NULL }, +#ifdef ENABLE_HYBRID +{ ISAKMP_NTYPE_UNITY_HEARTBEAT, "HEARTBEAT (Unity)", NULL }, +#endif { ISAKMP_LOG_RETRY_LIMIT_REACHED, "RETRY-LIMIT-REACHED", NULL }, }; @@ -285,27 +299,27 @@ s_isakmp_notify_msg(k) } static struct ksmap name_isakmp_nptype[] = { -{ ISAKMP_NPTYPE_NONE, "none", NULL }, -{ ISAKMP_NPTYPE_SA, "sa", NULL }, -{ ISAKMP_NPTYPE_P, "prop", NULL }, -{ ISAKMP_NPTYPE_T, "trns", NULL }, -{ ISAKMP_NPTYPE_KE, "ke", NULL }, -{ ISAKMP_NPTYPE_ID, "id", NULL }, -{ ISAKMP_NPTYPE_CERT, "cert", NULL }, -{ ISAKMP_NPTYPE_CR, "cr", NULL }, -{ ISAKMP_NPTYPE_HASH, "hash", NULL }, -{ ISAKMP_NPTYPE_SIG, "sig", NULL }, -{ ISAKMP_NPTYPE_NONCE, "nonce", NULL }, -{ ISAKMP_NPTYPE_N, "notify", NULL }, -{ ISAKMP_NPTYPE_D, "delete", NULL }, -{ ISAKMP_NPTYPE_VID, "vid", NULL }, -{ ISAKMP_NPTYPE_GSS, "gss id", NULL }, +{ ISAKMP_NPTYPE_NONE, "none", NULL }, +{ ISAKMP_NPTYPE_SA, "sa", NULL }, +{ ISAKMP_NPTYPE_P, "prop", NULL }, +{ ISAKMP_NPTYPE_T, "trns", NULL }, +{ ISAKMP_NPTYPE_KE, "ke", NULL }, +{ ISAKMP_NPTYPE_ID, "id", NULL }, +{ ISAKMP_NPTYPE_CERT, "cert", NULL }, +{ ISAKMP_NPTYPE_CR, "cr", NULL }, +{ ISAKMP_NPTYPE_HASH, "hash", NULL }, +{ ISAKMP_NPTYPE_SIG, "sig", NULL }, +{ ISAKMP_NPTYPE_NONCE, "nonce", NULL }, +{ ISAKMP_NPTYPE_N, "notify", NULL }, +{ ISAKMP_NPTYPE_D, "delete", NULL }, +{ ISAKMP_NPTYPE_VID, "vid", NULL }, +{ ISAKMP_NPTYPE_ATTR, "attr", NULL }, +{ ISAKMP_NPTYPE_GSS, "gss id", NULL }, { ISAKMP_NPTYPE_NATD_RFC, "nat-d", NULL }, { ISAKMP_NPTYPE_NATOA_RFC, "nat-oa", NULL }, { ISAKMP_NPTYPE_NATD_DRAFT, "nat-d", NULL }, { ISAKMP_NPTYPE_NATOA_DRAFT, "nat-oa", NULL }, -{ ISAKMP_NPTYPE_NATD_BADDRAFT, "nat-d", NULL }, -{ ISAKMP_NPTYPE_NATOA_BADDRAFT, "nat-oa", NULL } +{ ISAKMP_NPTYPE_FRAG, "ike frag", NULL }, }; char * @@ -319,6 +333,79 @@ s_isakmp_nptype(k) return num2str(k); } +#ifdef ENABLE_HYBRID +/* isakmp_cfg.h / isakmp_unity.h / isakmp_xauth.h */ +static struct ksmap name_isakmp_cfg_type[] = { +{ INTERNAL_IP4_ADDRESS, "INTERNAL_IP4_ADDRESS", NULL }, +{ INTERNAL_IP4_NETMASK, "INTERNAL_IP4_NETMASK", NULL }, +{ INTERNAL_IP4_DNS, "INTERNAL_IP4_DNS", NULL }, +{ INTERNAL_IP4_NBNS, "INTERNAL_IP4_NBNS", NULL }, +{ INTERNAL_ADDRESS_EXPIRY, "INTERNAL_ADDRESS_EXPIRY", NULL }, +{ INTERNAL_IP4_DHCP, "INTERNAL_IP4_DHCP", NULL }, +{ APPLICATION_VERSION, "APPLICATION_VERSION", NULL }, +{ INTERNAL_IP6_ADDRESS, "INTERNAL_IP6_ADDRESS", NULL }, +{ INTERNAL_IP6_NETMASK, "INTERNAL_IP6_NETMASK", NULL }, +{ INTERNAL_IP6_DNS, "INTERNAL_IP6_DNS", NULL }, +{ INTERNAL_IP6_NBNS, "INTERNAL_IP6_NBNS", NULL }, +{ INTERNAL_IP6_DHCP, "INTERNAL_IP6_DHCP", NULL }, +{ INTERNAL_IP4_SUBNET, "INTERNAL_IP4_SUBNET", NULL }, +{ SUPPORTED_ATTRIBUTES, "SUPPORTED_ATTRIBUTES", NULL }, +{ INTERNAL_IP6_SUBNET, "INTERNAL_IP6_SUBNET", NULL }, +{ XAUTH_TYPE, "XAUTH_TYPE", NULL }, +{ XAUTH_USER_NAME, "XAUTH_USER_NAME", NULL }, +{ XAUTH_USER_PASSWORD, "XAUTH_USER_PASSWORD", NULL }, +{ XAUTH_PASSCODE, "XAUTH_PASSCODE", NULL }, +{ XAUTH_MESSAGE, "XAUTH_MESSAGE", NULL }, +{ XAUTH_CHALLENGE, "XAUTH_CHALLENGE", NULL }, +{ XAUTH_DOMAIN, "XAUTH_DOMAIN", NULL }, +{ XAUTH_STATUS, "XAUTH_STATUS", NULL }, +{ XAUTH_NEXT_PIN, "XAUTH_NEXT_PIN", NULL }, +{ XAUTH_ANSWER, "XAUTH_ANSWER", NULL }, +{ UNITY_BANNER, "UNITY_BANNER", NULL }, +{ UNITY_SAVE_PASSWD, "UNITY_SAVE_PASSWD", NULL }, +{ UNITY_DEF_DOMAIN, "UNITY_DEF_DOMAIN", NULL }, +{ UNITY_SPLITDNS_NAME, "UNITY_SPLITDNS_NAME", NULL }, +{ UNITY_SPLIT_INCLUDE, "UNITY_SPLIT_INCLUDE", NULL }, +{ UNITY_NATT_PORT, "UNITY_NATT_PORT", NULL }, +{ UNITY_LOCAL_LAN, "UNITY_LOCAL_LAN", NULL }, +{ UNITY_PFS, "UNITY_PFS", NULL }, +{ UNITY_FW_TYPE, "UNITY_FW_TYPE", NULL }, +{ UNITY_BACKUP_SERVERS, "UNITY_BACKUP_SERVERS", NULL }, +{ UNITY_DDNS_HOSTNAME, "UNITY_DDNS_HOSTNAME", NULL }, +}; + +char * +s_isakmp_cfg_type(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_cfg_type); i++) + if (name_isakmp_cfg_type[i].key == k) + return name_isakmp_cfg_type[i].str; + return num2str(k); +} + +/* isakmp_cfg.h / isakmp_unity.h / isakmp_xauth.h */ +static struct ksmap name_isakmp_cfg_ptype[] = { +{ ISAKMP_CFG_ACK, "mode config ACK", NULL }, +{ ISAKMP_CFG_SET, "mode config SET", NULL }, +{ ISAKMP_CFG_REQUEST, "mode config REQUEST", NULL }, +{ ISAKMP_CFG_REPLY, "mode config REPLY", NULL }, +}; + +char * +s_isakmp_cfg_ptype(k) + int k; +{ + int i; + for (i = 0; i < ARRAYLEN(name_isakmp_cfg_ptype); i++) + if (name_isakmp_cfg_ptype[i].key == k) + return name_isakmp_cfg_ptype[i].str; + return num2str(k); +} + +#endif + /* ipsec_doi.h */ static struct ksmap name_ipsecdoi_proto[] = { { IPSECDOI_PROTO_ISAKMP, "ISAKMP", s_ipsecdoi_trns_isakmp }, @@ -587,6 +674,7 @@ static struct ksmap name_attr_isakmp_enc[] = { { OAKLEY_ATTR_ENC_ALG_RC5, "RC5-R16-B64-CBC", NULL }, { OAKLEY_ATTR_ENC_ALG_3DES, "3DES-CBC", NULL }, { OAKLEY_ATTR_ENC_ALG_CAST, "CAST-CBC", NULL }, +{ OAKLEY_ATTR_ENC_ALG_AES, "AES-CBC", NULL }, }; char * @@ -621,19 +709,25 @@ s_attr_isakmp_hash(k) } static struct ksmap name_attr_isakmp_method[] = { -{ OAKLEY_ATTR_AUTH_METHOD_PSKEY, "pre-shared key", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_DSSSIG, "DSS signatures", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_RSASIG, "RSA signatures", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_RSAENC, "Encryption with RSA", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_RSAREV, "Revised encryption with RSA", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_EGENC, "Encryption with El-Gamal", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_EGREV, "Revised encryption with El-Gamal", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, "GSS-API on Kerberos 5", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_PSKEY, "pre-shared key", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_DSSSIG, "DSS signatures", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_RSASIG, "RSA signatures", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_RSAENC, "Encryption with RSA", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_RSAREV, "Revised encryption with RSA", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_EGENC, "Encryption with El-Gamal", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_EGREV, "Revised encryption with El-Gamal", NULL }, +#ifdef HAVE_GSSAPI +{ OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, "GSS-API on Kerberos 5", NULL }, +#endif #ifdef ENABLE_HYBRID -{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, "Hybrid DSS server", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, "Hybrid RSA server", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, "Hybrid DSS client", NULL }, -{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, "Hybrid RSA client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, "Hybrid DSS server", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, "Hybrid RSA server", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, "Hybrid DSS client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, "Hybrid RSA client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I, "XAuth pskey client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R, "XAuth pskey server", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I, "XAuth RSASIG client", NULL }, +{ OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R, "XAuth RSASIG server", NULL }, #endif }; @@ -780,7 +874,7 @@ static struct ksmap name_pfkey_type[] = { { SADB_EXPIRE, "EXPIRE", NULL }, { SADB_FLUSH, "FLUSH", NULL }, { SADB_DUMP, "DUMP", NULL }, -{ SADB_X_PROMISC, "X_PRIMISC", NULL }, +{ SADB_X_PROMISC, "X_PROMISC", NULL }, { SADB_X_PCHANGE, "X_PCHANGE", NULL }, { SADB_X_SPDUPDATE, "X_SPDUPDATE", NULL }, { SADB_X_SPDADD, "X_SPDADD", NULL }, @@ -792,10 +886,12 @@ static struct ksmap name_pfkey_type[] = { { SADB_X_SPDSETIDX, "X_SPDSETIDX", NULL }, { SADB_X_SPDEXPIRE, "X_SPDEXPIRE", NULL }, { SADB_X_SPDDELETE2, "X_SPDDELETE2", NULL }, -#ifndef __APPLE__ -#ifdef ENABLE_NATT +{ SADB_GETSASTAT, "X_GETSASTAT", NULL }, +#ifdef SADB_X_NAT_T_NEW_MAPPING { SADB_X_NAT_T_NEW_MAPPING, "X_NAT_T_NEW_MAPPING", NULL }, #endif +#ifdef SADB_X_MIGRATE +{ SADB_X_MIGRATE, "X_MIGRATE", NULL }, #endif }; diff --git a/ipsec-tools/racoon/strnames.h b/ipsec-tools/racoon/strnames.h index ed60551..02ebbb5 100644 --- a/ipsec-tools/racoon/strnames.h +++ b/ipsec-tools/racoon/strnames.h @@ -1,4 +1,6 @@ -/* $Id: strnames.h,v 1.5 2004/07/12 20:37:13 ludvigm Exp $ */ +/* $NetBSD: strnames.h,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: strnames.h,v 1.7 2005/04/18 10:04:26 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -70,5 +72,9 @@ extern char *s_doi __P((int)); extern char *s_etype __P((int)); extern char *s_idtype __P((int)); extern char *s_switch __P((int)); +#ifdef ENABLE_HYBRID +extern char *s_isakmp_cfg_type __P((int)); +extern char *s_isakmp_cfg_ptype __P((int)); +#endif #endif /* _STRNAMES_H */ diff --git a/ipsec-tools/racoon/throttle.c b/ipsec-tools/racoon/throttle.c index 73f6b92..3a5dcb4 100644 --- a/ipsec-tools/racoon/throttle.c +++ b/ipsec-tools/racoon/throttle.c @@ -1,4 +1,6 @@ -/* $Id: throttle.c,v 1.2 2004/11/30 07:40:13 manubsd Exp $ */ +/* $NetBSD: throttle.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + +/* Id: throttle.c,v 1.5 2006/04/05 20:54:50 manubsd Exp */ /* * Copyright (C) 2004 Emmanuel Dreyfus @@ -49,6 +51,7 @@ #include #include +#include #include "vmbuf.h" #include "misc.h" @@ -100,14 +103,15 @@ throttle_host(addr, authfail) now = time(NULL); +restart: TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) { - /* - * Remove outdated entries - */ + /* + * Remove outdated entries + */ if (te->penalty < now) { TAILQ_REMOVE(&throttle_list, te, next); racoon_free(te); - continue; + goto restart; } if (cmpsaddrwop(addr, (struct sockaddr *)&te->host) == 0) { diff --git a/ipsec-tools/racoon/var.h b/ipsec-tools/racoon/var.h index e2cb36f..b9418a1 100644 --- a/ipsec-tools/racoon/var.h +++ b/ipsec-tools/racoon/var.h @@ -1,4 +1,6 @@ -/* $Id: var.h,v 1.6 2004/11/20 16:16:59 monas Exp $ */ +/* $NetBSD: var.h,v 1.4.6.1 2007/06/06 15:36:38 vanhu Exp $ */ + +/* Id: var.h,v 1.6 2004/11/20 16:16:59 monas Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -76,10 +78,10 @@ do { \ if (getnameinfo((x), sysdep_sa_len(x), (y), sizeof(y), (z), sizeof(z), \ NIFLAGS) != 0) { \ - if (y) \ - strncpy((y), "(invalid)", sizeof(y)); \ - if (z) \ - strncpy((z), "(invalid)", sizeof(z)); \ + if (y != NULL) \ + strlcpy((y), "(invalid)", sizeof(y)); \ + if (z != NULL) \ + strlcpy((z), "(invalid)", sizeof(z)); \ } \ } while (0); @@ -87,8 +89,8 @@ do { \ do { \ if (getnameinfo((x), sysdep_sa_len(x), (y), sizeof(y), NULL, 0, \ NIFLAGS) != 0) { \ - if (y) \ - strncpy((y), "(invalid)", sizeof(y)); \ + if (y != NULL) \ + strlcpy((y), "(invalid)", sizeof(y)); \ } \ } while (0); diff --git a/ipsec-tools/racoon/vmbuf.c b/ipsec-tools/racoon/vmbuf.c index e0204b6..6c1aed1 100644 --- a/ipsec-tools/racoon/vmbuf.c +++ b/ipsec-tools/racoon/vmbuf.c @@ -1,3 +1,5 @@ +/* $NetBSD: vmbuf.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ + /* $KAME: vmbuf.c,v 1.11 2001/11/26 16:54:29 sakane Exp $ */ /* @@ -44,6 +46,7 @@ #include "misc.h" #include "vmbuf.h" #include "debug.h" +#include "plog.h" #include "gcmalloc.h" vchar_t * @@ -120,6 +123,11 @@ vdup(src) { vchar_t *new; + if (src == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "vdup(NULL) called\n"); + return NULL; + } + if ((new = vmalloc(src->l)) == NULL) return NULL; diff --git a/ipsec-tools/racoon/vmbuf.h b/ipsec-tools/racoon/vmbuf.h index 5191be9..9bc6943 100644 --- a/ipsec-tools/racoon/vmbuf.h +++ b/ipsec-tools/racoon/vmbuf.h @@ -60,6 +60,11 @@ do { \ } \ } while(0); +#if defined(__APPLE__) && defined(__MACH__) +/* vfree is already defined in Apple's system libraries */ +#define vfree vmbuf_free +#endif + extern vchar_t *vmalloc __P((size_t)); extern vchar_t *vrealloc __P((vchar_t *, size_t)); extern void vfree __P((vchar_t *)); diff --git a/ipsec-tools/racoon/vpn.c b/ipsec-tools/racoon/vpn.c new file mode 100644 index 0000000..4e6e8d2 --- /dev/null +++ b/ipsec-tools/racoon/vpn.c @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2007 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#ifndef HAVE_NETINET6_IPSEC +#include +#else +#include +#endif + + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef ENABLE_HYBRID +#include +#endif + +#include "var.h" +#include "misc.h" +#include "vmbuf.h" +#include "plog.h" +#include "sockmisc.h" +#include "debug.h" +#include "handler.h" +#include "schedule.h" +#include "localconf.h" +#include "remoteconf.h" +#include "grabmyaddr.h" +#include "isakmp_var.h" +#include "isakmp.h" +#include "oakley.h" +#include "evt.h" +#include "pfkey.h" +#include "ipsec_doi.h" +#include "admin.h" +#include "admin_var.h" +#include "isakmp_inf.h" +#ifdef ENABLE_HYBRID +#include "isakmp_cfg.h" +#include "isakmp_unity.h" +#endif +#include "session.h" +#include "gcmalloc.h" +#include "sainfo.h" +#include "ipsec_doi.h" +#include "nattraversal.h" + +#include "vpn_control.h" +#include "vpn_control_var.h" +#include "strnames.h" +#include "ike_session.h" + + +static int vpn_get_ph2pfs(struct ph1handle *); + +int +vpn_connect(struct bound_addr *srv) +{ + int error = -1; + struct sockaddr *dst; + struct remoteconf *rmconf; + struct sockaddr *remote = NULL; + struct sockaddr *local = NULL; + u_int16_t port; + + dst = racoon_calloc(1, sizeof(struct sockaddr)); // this should come from the bound_addr parameter + if (dst == NULL) + goto out; + ((struct sockaddr_in *)(dst))->sin_len = sizeof(struct sockaddr_in); + ((struct sockaddr_in *)(dst))->sin_family = AF_INET; + ((struct sockaddr_in *)(dst))->sin_port = 500; + ((struct sockaddr_in *)(dst))->sin_addr.s_addr = srv->address; + + /* + * Find the source address + */ + if ((local = getlocaladdr(dst)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot get local address\n"); + goto out1; + } + + /* find appropreate configuration */ + rmconf = getrmconf(dst); + if (rmconf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no configuration found " + "for %s\n", saddrwop2str(dst)); + goto out1; + } + + /* get remote IP address and port number. */ + if ((remote = dupsaddr(dst)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to duplicate address\n"); + goto out1; + } + + switch (remote->sa_family) { + case AF_INET: + ((struct sockaddr_in *)remote)->sin_port = + ((struct sockaddr_in *)rmconf->remote)->sin_port; + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)remote)->sin6_port = + ((struct sockaddr_in6 *)rmconf->remote)->sin6_port; + break; +#endif + default: + plog(LLV_ERROR, LOCATION, NULL, + "invalid family: %d\n", + remote->sa_family); + goto out1; + break; + } + + port = ntohs(getmyaddrsport(local)); + if (set_port(local, port) == NULL) + goto out1; + + plog(LLV_INFO, LOCATION, NULL, + "accept a request to establish IKE-SA: " + "%s\n", saddrwop2str(remote)); + + /* begin ident mode */ + if (isakmp_ph1begin_i(rmconf, remote, local, 1) < 0) + goto out1; + + error = 0; + +out1: + if (dst != NULL) + racoon_free(dst); + if (local != NULL) + racoon_free(local); + if (remote != NULL) + racoon_free(remote); +out: + + return error; +} + +int +vpn_disconnect(struct bound_addr *srv) +{ + struct sockaddr_in saddr; + + bzero(&saddr, sizeof(saddr)); + saddr.sin_len = sizeof(saddr); + saddr.sin_addr.s_addr = srv->address; + saddr.sin_port = 0; + saddr.sin_family = AF_INET; + ike_sessions_stopped_by_controller(&saddr, + 0, + ike_session_stopped_by_vpn_disconnect); + if (purgephXbydstaddrwop((struct sockaddr *)(&saddr)) > 0) { + return 0; + } else { + return -1; + } +} + +int +vpn_start_ph2(struct bound_addr *addr, struct vpnctl_cmd_start_ph2 *pkt) +{ + struct vpnctl_sa_selector *selector_ptr; + struct vpnctl_algo *algo_ptr, *next_algo; + int i, j, defklen; + struct sainfoalg *new_algo; + struct sainfo *new_sainfo = NULL, *check; + u_int16_t class, algorithm, keylen; + struct ph1handle *ph1; + struct sockaddr_in saddr; + + struct id { + u_int8_t type; /* ID Type */ + u_int8_t proto_id; /* Protocol ID */ + u_int16_t port; /* Port */ + u_int32_t addr; /* IPv4 address */ + u_int32_t mask; + } *id_ptr; + + /* verify ph1 exists */ + bzero(&saddr, sizeof(saddr)); + saddr.sin_len = sizeof(saddr); + saddr.sin_addr.s_addr = addr->address; + saddr.sin_port = 0; + saddr.sin_family = AF_INET; + ph1 = getph1bydstaddrwop((struct sockaddr *)(&saddr)); + if (ph1 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot start phase2 - no phase1 found.\n"); + return -1; + } + if (ph1->status != PHASE1ST_ESTABLISHED) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot start phase2 - phase1 not established.\n"); + return -1; + } + + selector_ptr = (struct vpnctl_sa_selector *)(pkt + 1); + algo_ptr = (struct vpnctl_algo *)(selector_ptr + ntohs(pkt->selector_count)); + + for (i = 0; i < ntohs(pkt->selector_count); i++, selector_ptr++) { + new_sainfo = newsainfo(); + if (new_sainfo == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate sainfo struct.\n"); + goto fail; + } + + if (ntohl(selector_ptr->src_tunnel_mask) == 0xFFFFFFFF) + new_sainfo->idsrc = vmalloc(sizeof(struct id) - sizeof(u_int32_t)); + else + new_sainfo->idsrc = vmalloc(sizeof(struct id)); + if (new_sainfo->idsrc == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate id struct.\n"); + goto fail; + } + if (selector_ptr->dst_tunnel_mask == 0xFFFFFFFF) + new_sainfo->iddst = vmalloc(sizeof(struct id) - sizeof(u_int32_t)); + else + new_sainfo->iddst = vmalloc(sizeof(struct id)); + if (new_sainfo->iddst == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate id struct.\n"); + goto fail; + } + + id_ptr = (struct id *)new_sainfo->idsrc->v; + if (ntohl(selector_ptr->src_tunnel_mask) == 0xFFFFFFFF) + id_ptr->type = IPSECDOI_ID_IPV4_ADDR; + else { + id_ptr->type = IPSECDOI_ID_IPV4_ADDR_SUBNET; + id_ptr->mask = selector_ptr->src_tunnel_mask; + } + id_ptr->addr = selector_ptr->src_tunnel_address; + id_ptr->port = selector_ptr->src_tunnel_port; + id_ptr->proto_id = selector_ptr->ul_protocol; + + id_ptr = (struct id *)new_sainfo->iddst->v; + if (selector_ptr->dst_tunnel_mask == 0xFFFFFFFF) + id_ptr->type = IPSECDOI_ID_IPV4_ADDR; + else { + id_ptr->type = IPSECDOI_ID_IPV4_ADDR_SUBNET; + id_ptr->mask = selector_ptr->dst_tunnel_mask; + } + id_ptr->addr = selector_ptr->dst_tunnel_address; + id_ptr->port = selector_ptr->dst_tunnel_port; + id_ptr->proto_id = selector_ptr->ul_protocol; + + new_sainfo->dynamic = addr->address; + new_sainfo->lifetime = ntohl(pkt->lifetime); + + if (ntohs(pkt->pfs_group) != 0) { + new_sainfo->pfs_group = algtype2doi(algclass_isakmp_dh, ntohs(pkt->pfs_group)); + if (new_sainfo->pfs_group == -1) { + plog(LLV_ERROR, LOCATION, NULL, "invalid dh group specified\n"); + goto fail; + } + } + for (j = 0, next_algo = algo_ptr; j < ntohs(pkt->algo_count); j++, next_algo++) { + + new_algo = newsainfoalg(); + if (new_algo == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate algorithm structure\n"); + goto fail; + } + + class = ntohs(next_algo->algo_class); + algorithm = ntohs(next_algo->algo); + keylen = ntohs(next_algo->key_len); + + new_algo->alg = algtype2doi(class, algorithm); + if (new_algo->alg == -1) { + plog(LLV_ERROR, LOCATION, NULL, "algorithm mismatched\n"); + racoon_free(new_algo); + goto fail; + } + + defklen = default_keylen(class, algorithm); + if (defklen == 0) { + if (keylen) { + plog(LLV_ERROR, LOCATION, NULL, "keylen not allowed\n"); + racoon_free(new_algo); + goto fail; + } + } else { + if (keylen && check_keylen(class, algorithm, keylen) < 0) { + plog(LLV_ERROR, LOCATION, NULL, "invalid keylen %d\n", keylen); + racoon_free(new_algo); + goto fail; + } + } + + if (keylen) + new_algo->encklen = keylen; + else + new_algo->encklen = defklen; + + /* check if it's supported algorithm by kernel */ + if (!(class == algclass_ipsec_auth && algorithm == algtype_non_auth) + && pk_checkalg(class, algorithm, new_algo->encklen)) { + int a = algclass2doi(class); + int b = new_algo->alg; + if (a == IPSECDOI_ATTR_AUTH) + a = IPSECDOI_PROTO_IPSEC_AH; + plog(LLV_ERROR, LOCATION, NULL, + "algorithm %s not supported by the kernel (missing module?)\n", s_ipsecdoi_trns(a, b)); + racoon_free(new_algo); + goto fail; + } + inssainfoalg(&new_sainfo->algs[class], new_algo); + } + + if (new_sainfo->algs[algclass_ipsec_enc] == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "no encryption algorithm at %s\n", sainfo2str(new_sainfo)); + goto fail; + } + if (new_sainfo->algs[algclass_ipsec_auth] == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "no authentication algorithm at %s\n", sainfo2str(new_sainfo)); + goto fail; + } + if (new_sainfo->algs[algclass_ipsec_comp] == 0) { + plog(LLV_ERROR, LOCATION, NULL, + "no compression algorithm at %s\n", sainfo2str(new_sainfo)); + goto fail; + } + + /* duplicate check */ + check = getsainfo(new_sainfo->idsrc, new_sainfo->iddst, new_sainfo->id_i, 0); + if (check && (!check->idsrc && !new_sainfo->idsrc)) { + plog(LLV_ERROR, LOCATION, NULL,"duplicated sainfo: %s\n", sainfo2str(new_sainfo)); + goto fail; + } + plog(LLV_DEBUG2, LOCATION, NULL, "create sainfo: %s\n", sainfo2str(new_sainfo)); + inssainfo(new_sainfo); + new_sainfo = NULL; + } + + return 0; + +fail: + if (new_sainfo) + delsainfo(new_sainfo); + flushsainfo_dynamic(addr); + return -1; +} + +static int +vpn_get_ph2pfs(struct ph1handle *ph1) +{ +} + + +int +vpn_get_config(struct ph1handle *iph1, struct vpnctl_status_phase_change **msg, size_t *msg_size) +{ + + struct vpnctl_modecfg_params *params; + struct myaddrs *myaddr; + u_int16_t ifname_len, msize; + u_int8_t *cptr; + + *msg = NULL; + msize = 0; + + if (((struct sockaddr_in *)iph1->local)->sin_family != AF_INET) { + plog(LLV_ERROR, LOCATION, NULL, + "IPv6 not supported for mode config.\n"); + return -1; + } + + if (iph1->mode_cfg->attr_list == NULL) + return 1; /* haven't received configuration yet */ + + myaddr = find_myaddr(iph1->local, 0); + if (myaddr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to find address structure.\n"); + return -1; + } + + msize = sizeof(struct vpnctl_status_phase_change) + + sizeof(struct vpnctl_modecfg_params); + msize += iph1->mode_cfg->attr_list->l; + + *msg = racoon_calloc(1, msize); + if (*msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "faled to allocate space for message.\n"); + return -1; + } + + (*msg)->hdr.flags = htons(VPNCTL_FLAG_MODECFG_USED); + params = (struct vpnctl_modecfg_params *)(*msg + 1); + params->outer_local_addr = ((struct sockaddr_in *)iph1->local)->sin_addr.s_addr; + params->outer_remote_port = htons(0); + params->outer_local_port = htons(0); + ifname_len = strlen(myaddr->ifname); + memset(¶ms->ifname, 0, IFNAMSIZ); + memcpy(¶ms->ifname, myaddr->ifname, ifname_len < IFNAMSIZ ? ifname_len : IFNAMSIZ-1); + cptr = (u_int8_t *)(params + 1); + memcpy(cptr, iph1->mode_cfg->attr_list->v, iph1->mode_cfg->attr_list->l); + *msg_size = msize; + + return 0; +} + + +int +vpn_xauth_reply(u_int32_t address, void *attr_list, size_t attr_len) +{ + + struct isakmp_pl_attr *reply; + void* attr_ptr; + vchar_t *payload = NULL; + struct ph1handle *iph1; + struct sockaddr_in saddr; + int error = -1; + int tlen = attr_len; + struct isakmp_data *attr; + char *dataptr = (char *)attr_list; + + /* find ph1 */ + bzero(&saddr, sizeof(saddr)); + saddr.sin_len = sizeof(saddr); + saddr.sin_addr.s_addr = address; + saddr.sin_port = 0; + saddr.sin_family = AF_INET; + iph1 = getph1bydstaddrwop((struct sockaddr *)(&saddr)); + if (iph1 == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "cannot reply to xauth request - no ph1 found.\n"); + goto end; + } + + if (iph1->xauth_awaiting_userinput == 0) { + plog(LLV_ERROR, LOCATION, NULL, "Huh? recvd xauth reply data with no xauth reply pending \n"); + goto end; + } + + /* validate attr lengths */ + while (tlen > 0) + { + int tlv; + + attr = (struct isakmp_data *)dataptr; + tlv = (attr->type & htons(0x8000)) == 0; + + if (tlv) { + tlen -= ntohs(attr->lorv); + dataptr += ntohs(attr->lorv); + } + tlen -= sizeof(u_int32_t); + dataptr += sizeof(u_int32_t); + } + if (tlen != 0) { + plog(LLV_ERROR, LOCATION, NULL, "invalid auth info received from VPN Control socket.\n"); + goto end; + } + + payload = vmalloc(sizeof(struct isakmp_pl_attr) + attr_len); + if (payload == NULL) { + plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory for xauth reply\n"); + goto end; + } + memset(payload->v, 0, sizeof(reply)); + + reply = (struct isakmp_pl_attr *)payload->v; + reply->h.len = htons(payload->l); + reply->type = ISAKMP_CFG_REPLY; + reply->id = iph1->pended_xauth_id; /* network byte order */ + iph1->xauth_awaiting_userinput = 0; /* no longer waiting */ + attr_ptr = reply + 1; + memcpy(attr_ptr, attr_list, attr_len); + + plog(LLV_DEBUG, LOCATION, NULL, + "Sending MODE_CFG REPLY\n"); + error = isakmp_cfg_send(iph1, payload, + ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, iph1->xauth_awaiting_userinput_msg); + VPTRINIT(iph1->xauth_awaiting_userinput_msg); + ike_session_stop_xauth_timer(iph1); + +end: + if (payload) + vfree(payload); + return error; +} + diff --git a/ipsec-tools/racoon/vpn.h b/ipsec-tools/racoon/vpn.h new file mode 100644 index 0000000..ff8274b --- /dev/null +++ b/ipsec-tools/racoon/vpn.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2007 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +int vpn_connect __P((struct bound_addr *)); diff --git a/ipsec-tools/racoon/vpn_control.c b/ipsec-tools/racoon/vpn_control.c index f3217a0..cc81603 100644 --- a/ipsec-tools/racoon/vpn_control.c +++ b/ipsec-tools/racoon/vpn_control.c @@ -78,6 +78,7 @@ #ifdef HAVE_UNISTD_H #include #endif +#include #include "var.h" #include "misc.h" @@ -113,7 +114,93 @@ static struct sockaddr_un sunaddr; static int vpncontrol_process(struct vpnctl_socket_elem *, char *); static int vpncontrol_reply(int, char *); static void vpncontrol_close_comm(struct vpnctl_socket_elem *); +static int checklaunchd(); +extern int vpn_get_config __P((struct ph1handle *, struct vpnctl_status_phase_change **, size_t *)); +extern int vpn_xauth_reply __P((u_int32_t, void *, size_t)); + + +int +checklaunchd() +{ + launch_data_t checkin_response = NULL; + launch_data_t checkin_request = NULL; + launch_data_t sockets_dict, listening_fd_array; + launch_data_t listening_fd; + struct sockaddr_storage fdsockaddr; + socklen_t fdsockaddrlen = sizeof(fdsockaddr); + int socketct; + int i; + int listenerct; + int returnval = 0; + int fd; + + /* check in with launchd */ + if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to launch_data_new_string.\n"); + goto done; + } + if ((checkin_response = launch_msg(checkin_request)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to launch_msg.\n"); + goto done; + } + if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { + plog(LLV_ERROR, LOCATION, NULL, + "launch_data_get_type error %d\n", + launch_data_get_errno(checkin_response)); + goto done; + } + if ( (sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS)) == NULL){ + plog(LLV_ERROR, LOCATION, NULL, + "failed to launch_data_dict_lookup.\n"); + goto done; + } + if ( !(socketct = launch_data_dict_get_count(sockets_dict))){ + plog(LLV_ERROR, LOCATION, NULL, + "launch_data_dict_get_count returns no socket defined.\n"); + goto done; + } + + if ( (listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners")) == NULL ){ + plog(LLV_ERROR, LOCATION, NULL, + "failed to launch_data_dict_lookup.\n"); + goto done; + } + listenerct = launch_data_array_get_count(listening_fd_array); + for (i = 0; i < listenerct; i++) { + listening_fd = launch_data_array_get_index(listening_fd_array, i); + fd = launch_data_get_fd( listening_fd ); + if ( getsockname( fd , (struct sockaddr*)&fdsockaddr, &fdsockaddrlen)){ + continue; + } + + /* Is this the VPN control socket? */ + if ( (((struct sockaddr*)&fdsockaddr)->sa_family) == AF_UNIX && + (!(strcmp(vpncontrolsock_path, ((struct sockaddr_un *)&fdsockaddr)->sun_path)))) + { + plog(LLV_INFO, LOCATION, NULL, + "found launchd socket.\n"); + returnval = fd; + break; + } + } + // TODO: check if we have any leaked fd + if ( listenerct == i){ + plog(LLV_ERROR, LOCATION, NULL, + "failed to find launchd socket\n"); + returnval = 0; + } + +done: + if (checkin_request) + launch_data_free(checkin_request); + if (checkin_response) + launch_data_free(checkin_response); + return(returnval); +} + int vpncontrol_handler() { @@ -162,7 +249,7 @@ vpncontrol_comm_handler(struct vpnctl_socket_elem *elem) goto end; } if (len == 0) { - plog(LLV_NOTIFY, LOCATION, NULL, + plog(LLV_DEBUG, LOCATION, NULL, "vpn_control socket closed by peer.\n"); vpncontrol_close_comm(elem); return -1; @@ -215,13 +302,23 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf) plog(LLV_DEBUG, LOCATION, NULL, "received bind command on vpn control socket.\n"); - addr = racoon_malloc(sizeof(struct bound_addr)); + addr = racoon_calloc(1, sizeof(struct bound_addr)); if (addr == NULL) { plog(LLV_ERROR, LOCATION, NULL, "memory error: %s\n", strerror(errno)); error = -1; break; } + if (ntohs(pkt->vers_len)) { + addr->version = vmalloc(ntohs(pkt->vers_len)); + if (addr->version == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "memory error: %s\n", strerror(errno)); + error = -1; + break; + } + memcpy(addr->version->v, pkt + 1, ntohs(pkt->vers_len)); + } addr->address = pkt->address; LIST_INSERT_HEAD(&elem->bound_addresses, addr, chain); lcconf->auto_exit_state |= LC_AUTOEXITSTATE_CLIENT; /* client side */ @@ -239,7 +336,10 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf) LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) { if (pkt->address == 0xFFFFFFFF || pkt->address == addr->address) { + flushsainfo_dynamic(addr->address); LIST_REMOVE(addr, chain); + if (addr->version) + vfree(addr->version); racoon_free(addr); } } @@ -287,7 +387,108 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf) break; case VPNCTL_CMD_PING: - break; // just reply for now + break; /* just reply for now */ + + case VPNCTL_CMD_XAUTH_INFO: + { + struct vpnctl_cmd_xauth_info *pkt = (struct vpnctl_cmd_xauth_info *)combuf; + struct bound_addr *addr; + struct bound_addr *t_addr; + void *attr_list; + + plog(LLV_DEBUG, LOCATION, NULL, + "received xauth info command vpn control socket.\n"); + LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) { + if (pkt->address == addr->address) { + /* reply to the last xauth request */ + attr_list = pkt + 1; + error = vpn_xauth_reply(pkt->address, attr_list, ntohs(pkt->hdr.len) - sizeof(u_int32_t)); + break; + } + } + } + break; + + case VPNCTL_CMD_CONNECT: + { + struct vpnctl_cmd_connect *pkt = (struct vpnctl_cmd_connect *)combuf; + struct bound_addr *addr; + struct bound_addr *t_addr; + + plog(LLV_DEBUG, LOCATION, NULL, + "received connect command on vpn control socket.\n"); + LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) { + if (pkt->address == addr->address) { + /* start the connection */ + error = vpn_connect(addr); + break; + } + } + } + break; + + case VPNCTL_CMD_DISCONNECT: + { + struct vpnctl_cmd_connect *pkt = (struct vpnctl_cmd_connect *)combuf; + struct bound_addr *addr; + struct bound_addr *t_addr; + + plog(LLV_DEBUG, LOCATION, NULL, + "received disconnect command on vpn control socket.\n"); + LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) { + if (pkt->address == addr->address) { + /* stop the connection */ + error = vpn_disconnect(addr); + break; + } + } + } + break; + + case VPNCTL_CMD_START_PH2: + { + struct vpnctl_cmd_start_ph2 *pkt = (struct vpnctl_cmd_start_ph2 *)combuf; + struct bound_addr *addr; + struct bound_addr *t_addr; + + plog(LLV_DEBUG, LOCATION, NULL, + "received start_ph2 command on vpn control socket.\n"); + plogdump(LLV_DEBUG2, pkt, ntohs(hdr->len) + sizeof(struct vpnctl_hdr)); + LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) { + if (pkt->address == addr->address) { + /* start the connection */ + error = vpn_start_ph2(addr, pkt); + break; + } + } + } + break; + + case VPNCTL_CMD_START_DPD: + { + struct vpnctl_cmd_start_dpd *pkt = (struct vpnctl_cmd_start_dpd *)combuf; + struct bound_addr *srv; + struct bound_addr *t_addr; + + plog(LLV_DEBUG, LOCATION, NULL, + "received start_dpd command on vpn control socket.\n"); + LIST_FOREACH_SAFE(srv, &elem->bound_addresses, chain, t_addr) { + if (pkt->address == srv->address) { + struct sockaddr_in daddr; + + bzero(&daddr, sizeof(daddr)); + daddr.sin_len = sizeof(daddr); + daddr.sin_addr.s_addr = srv->address; + daddr.sin_port = 0; + daddr.sin_family = AF_INET; + + /* start the dpd */ + error = ph1_force_dpd(&daddr); + break; + } + } + } + break; default: plog(LLV_ERROR, LOCATION, NULL, @@ -320,10 +521,73 @@ vpncontrol_reply(int so, char *combuf) return 0; } +int +vpncontrol_notify_need_authinfo(struct ph1handle *iph1, void* attr_list, size_t attr_len) +{ + struct vpnctl_status_need_authinfo *msg = NULL; + struct vpnctl_socket_elem *sock_elem; + struct bound_addr *bound_addr; + size_t tlen, msg_size; + u_int32_t address; + void *ptr; + + if (!iph1) + goto end; + + plog(LLV_DEBUG, LOCATION, NULL, + "sending vpn_control xauth need info status\n"); + + msg = (struct vpnctl_status_need_authinfo *)racoon_malloc(msg_size = sizeof(struct vpnctl_status_need_authinfo) + attr_len); + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate space for vpn control message.\n"); + return -1; + } + msg->hdr.flags = 0; + + if (iph1->remote->sa_family == AF_INET) + address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; + else + goto end; // for now + + msg->hdr.cookie = msg->hdr.reserved = msg->hdr.result = 0; + msg->hdr.len = htons((msg_size) - sizeof(struct vpnctl_hdr)); + if (!ike_session_is_client_ph1_rekey(iph1)) { + msg->hdr.msg_type = htons(VPNCTL_STATUS_NEED_AUTHINFO); + } else { + msg->hdr.msg_type = htons(VPNCTL_STATUS_NEED_REAUTHINFO); + } + msg->address = address; + ptr = msg + 1; + memcpy(ptr, attr_list, attr_len); + + LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) { + LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) { + if (bound_addr->address == 0xFFFFFFFF || + bound_addr->address == address) { + plog(LLV_DEBUG, LOCATION, NULL, + "vpn control writing %d bytes\n", msg_size); + plogdump(LLV_DEBUG, msg, msg_size); + tlen = send(sock_elem->sock, msg, msg_size, 0); + if (tlen < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to send vpn_control need authinfo status: %s\n", strerror(errno)); + } + break; + } + } + } + +end: + if (msg) + racoon_free(msg); + return 0; +} + int vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t address, u_int16_t data_len, u_int8_t *data) { - struct vpnctl_status_failed *msg; + struct vpnctl_status_failed *msg = NULL; struct vpnctl_socket_elem *sock_elem; struct bound_addr *bound_addr; size_t tlen, len; @@ -346,7 +610,7 @@ vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t ad if (data_len > 0) memcpy(msg->data, data, data_len); plog(LLV_DEBUG, LOCATION, NULL, - "sending vpn_control ike notify failed message - code=%d from=%s.\n", notify_code, + "sending vpn_control ike failed message - code=%d from=%s.\n", notify_code, (from == FROM_LOCAL ? "local" : "remote")); LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) { @@ -362,6 +626,9 @@ vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t ad } } } + + if (msg) + racoon_free(msg); return 0; } @@ -369,36 +636,55 @@ vpncontrol_notify_ike_failed(u_int16_t notify_code, u_int16_t from, u_int32_t ad int vpncontrol_notify_phase_change(int start, u_int16_t from, struct ph1handle *iph1, struct ph2handle *iph2) { - struct vpnctl_status_phase_change msg; + struct vpnctl_status_phase_change *msg; struct vpnctl_socket_elem *sock_elem; struct bound_addr *bound_addr; - size_t tlen; + size_t tlen, msg_size; u_int32_t address; + + plog(LLV_DEBUG, LOCATION, NULL, + "sending vpn_control phase change status\n"); + + if (iph1 && !start && iph1->mode_cfg) { + if (vpn_get_config(iph1, &msg, &msg_size) == 1) + return 0; /* mode config not finished yet */ + } else { + msg = racoon_malloc(msg_size = sizeof(struct vpnctl_status_phase_change)); + msg->hdr.flags = 0; + } + if (msg == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "unable to allocate space for vpn control message.\n"); + return -1; + } if (iph1) { if (iph1->remote->sa_family == AF_INET) address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; else - return 0; // for now - msg.hdr.msg_type = htons(start ? + goto end; // for now + msg->hdr.msg_type = htons(start ? (from == FROM_LOCAL ? VPNCTL_STATUS_PH1_START_US : VPNCTL_STATUS_PH1_START_PEER) : VPNCTL_STATUS_PH1_ESTABLISHED); } else { if (iph2->dst->sa_family == AF_INET) address = ((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr; else - return 0; // for now - msg.hdr.msg_type = htons(start ? VPNCTL_STATUS_PH2_START : VPNCTL_STATUS_PH2_ESTABLISHED); + goto end; // for now + msg->hdr.msg_type = htons(start ? VPNCTL_STATUS_PH2_START : VPNCTL_STATUS_PH2_ESTABLISHED); } - msg.hdr.flags = msg.hdr.cookie = msg.hdr.reserved = msg.hdr.result = 0; - msg.hdr.len = htons(sizeof(struct vpnctl_status_phase_change) - sizeof(struct vpnctl_hdr)); - msg.address = address; + msg->hdr.cookie = msg->hdr.reserved = msg->hdr.result = 0; + msg->hdr.len = htons((msg_size) - sizeof(struct vpnctl_hdr)); + msg->address = address; LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) { LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) { if (bound_addr->address == 0xFFFFFFFF || bound_addr->address == address) { - tlen = send(sock_elem->sock, &msg, sizeof(struct vpnctl_status_phase_change), 0); + plog(LLV_DEBUG, LOCATION, NULL, + "vpn control writing %d bytes\n", msg_size); + plogdump(LLV_DEBUG, msg, msg_size); + tlen = send(sock_elem->sock, msg, msg_size, 0); if (tlen < 0) { plog(LLV_ERROR, LOCATION, NULL, "failed to send vpn_control phase change status: %s\n", strerror(errno)); @@ -408,6 +694,9 @@ vpncontrol_notify_phase_change(int start, u_int16_t from, struct ph1handle *iph1 } } +end: + if (msg) + racoon_free(msg); return 0; } @@ -420,56 +709,62 @@ vpncontrol_init() return 0; } - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), - "%s", vpncontrolsock_path); - - lcconf->sock_vpncontrol = socket(AF_UNIX, SOCK_STREAM, 0); - if (lcconf->sock_vpncontrol == -1) { - plog(LLV_ERROR, LOCATION, NULL, - "socket: %s\n", strerror(errno)); - return -1; + if ( (lcconf->sock_vpncontrol = checklaunchd()) ){ + return 0; } + else { + + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), + "%s", vpncontrolsock_path); - unlink(sunaddr.sun_path); - if (bind(lcconf->sock_vpncontrol, (struct sockaddr *)&sunaddr, - sizeof(sunaddr)) != 0) { - plog(LLV_ERROR, LOCATION, NULL, - "bind(sockname:%s): %s\n", - sunaddr.sun_path, strerror(errno)); - (void)close(lcconf->sock_vpncontrol); - return -1; - } + lcconf->sock_vpncontrol = socket(AF_UNIX, SOCK_STREAM, 0); + if (lcconf->sock_vpncontrol == -1) { + plog(LLV_ERROR, LOCATION, NULL, + "socket: %s\n", strerror(errno)); + return -1; + } - if (chown(sunaddr.sun_path, vpncontrolsock_owner, vpncontrolsock_group) != 0) { - plog(LLV_ERROR, LOCATION, NULL, - "chown(%s, %d, %d): %s\n", - sunaddr.sun_path, vpncontrolsock_owner, - vpncontrolsock_group, strerror(errno)); - (void)close(lcconf->sock_vpncontrol); - return -1; - } + unlink(sunaddr.sun_path); + if (bind(lcconf->sock_vpncontrol, (struct sockaddr *)&sunaddr, + sizeof(sunaddr)) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "bind(sockname:%s): %s\n", + sunaddr.sun_path, strerror(errno)); + (void)close(lcconf->sock_vpncontrol); + return -1; + } - if (chmod(sunaddr.sun_path, vpncontrolsock_mode) != 0) { - plog(LLV_ERROR, LOCATION, NULL, - "chmod(%s, 0%03o): %s\n", - sunaddr.sun_path, vpncontrolsock_mode, strerror(errno)); - (void)close(lcconf->sock_vpncontrol); - return -1; - } + if (chown(sunaddr.sun_path, vpncontrolsock_owner, vpncontrolsock_group) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "chown(%s, %d, %d): %s\n", + sunaddr.sun_path, vpncontrolsock_owner, + vpncontrolsock_group, strerror(errno)); + (void)close(lcconf->sock_vpncontrol); + return -1; + } - if (listen(lcconf->sock_vpncontrol, 5) != 0) { - plog(LLV_ERROR, LOCATION, NULL, - "listen(sockname:%s): %s\n", - sunaddr.sun_path, strerror(errno)); - (void)close(lcconf->sock_vpncontrol); - return -1; - } - plog(LLV_DEBUG, LOCATION, NULL, - "opened %s as racoon management.\n", sunaddr.sun_path); + if (chmod(sunaddr.sun_path, vpncontrolsock_mode) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "chmod(%s, 0%03o): %s\n", + sunaddr.sun_path, vpncontrolsock_mode, strerror(errno)); + (void)close(lcconf->sock_vpncontrol); + return -1; + } - return 0; + if (listen(lcconf->sock_vpncontrol, 5) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "listen(sockname:%s): %s\n", + sunaddr.sun_path, strerror(errno)); + (void)close(lcconf->sock_vpncontrol); + return -1; + } + plog(LLV_DEBUG, LOCATION, NULL, + "opened %s as racoon management.\n", sunaddr.sun_path); + + return 0; + } } @@ -479,12 +774,16 @@ vpncontrol_close() struct vpnctl_socket_elem *elem; struct vpnctl_socket_elem *t_elem; + plog(LLV_DEBUG, LOCATION, NULL, + "vpncontrol_close.\n"); + if (lcconf->sock_vpncontrol != -1) { close(lcconf->sock_vpncontrol); lcconf->sock_vpncontrol = -1; } LIST_FOREACH_SAFE(elem, &lcconf->vpnctl_comm_socks, chain, t_elem) vpncontrol_close_comm(elem); + } static void @@ -492,12 +791,18 @@ vpncontrol_close_comm(struct vpnctl_socket_elem *elem) { struct bound_addr *addr; struct bound_addr *t_addr; + + plog(LLV_DEBUG, LOCATION, NULL, + "vpncontrol_close_comm.\n"); LIST_REMOVE(elem, chain); if (elem->sock != -1) close(elem->sock); LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) { + flushsainfo_dynamic(addr->address); LIST_REMOVE(addr, chain); + if (addr->version) + vfree(addr->version); racoon_free(addr); } racoon_free(elem); diff --git a/ipsec-tools/racoon/vpn_control.h b/ipsec-tools/racoon/vpn_control.h index cabbb16..fd545d8 100644 --- a/ipsec-tools/racoon/vpn_control.h +++ b/ipsec-tools/racoon/vpn_control.h @@ -54,11 +54,15 @@ #ifndef _VPN_CONTROL_H #define _VPN_CONTROL_H +#include "algorithm_types.h" +#include + #define VPNCONTROLSOCK_PATH ADMINPORTDIR "/vpncontrol.sock" #define FROM_LOCAL 0 #define FROM_REMOTE 1 + extern char *vpncontrolsock_path; extern uid_t vpncontrolsock_owner; extern gid_t vpncontrolsock_group; @@ -72,13 +76,94 @@ extern mode_t vpncontrolsock_mode; #define VPNCTL_CMD_UNBIND 0x0002 #define VPNCTL_CMD_REDIRECT 0x0003 #define VPNCTL_CMD_PING 0x0004 +#define VPNCTL_CMD_CONNECT 0x0011 +#define VPNCTL_CMD_DISCONNECT 0x0012 +#define VPNCTL_CMD_START_PH2 0x0013 +#define VPNCTL_CMD_XAUTH_INFO 0x0014 +#define VPNCTL_CMD_START_DPD 0x0015 #define VPNCTL_STATUS_IKE_FAILED 0x8001 #define VPNCTL_STATUS_PH1_START_US 0x8011 #define VPNCTL_STATUS_PH1_START_PEER 0x8012 #define VPNCTL_STATUS_PH1_ESTABLISHED 0x8013 #define VPNCTL_STATUS_PH2_START 0x8021 #define VPNCTL_STATUS_PH2_ESTABLISHED 0x8022 +#define VPNCTL_STATUS_NEED_AUTHINFO 0x8101 +#define VPNCTL_STATUS_NEED_REAUTHINFO 0x8102 + +/* + * Flags + */ +#define VPNCTL_FLAG_MODECFG_USED 0x0001 + +/* + * XAUTH Attribute Types + */ +#ifndef __IPSEC_BUILD__ +#define XAUTH_TYPE 16520 +#define XAUTH_USER_NAME 16521 +#define XAUTH_USER_PASSWORD 16522 +#define XAUTH_PASSCODE 16523 +#define XAUTH_MESSAGE 16524 +#define XAUTH_CHALLENGE 16525 +#define XAUTH_DOMAIN 16526 +#define XAUTH_STATUS 16527 +#define XAUTH_NEXT_PIN 16528 +#define XAUTH_ANSWER 16529 + + +/* Types for XAUTH_TYPE */ +#define XAUTH_TYPE_GENERIC 0 +#define XAUTH_TYPE_CHAP 1 +#define XAUTH_TYPE_OTP 2 +#define XAUTH_TYPE_SKEY 3 + + +/* Mode cfg Attribute types */ +#define INTERNAL_IP4_ADDRESS 1 +#define INTERNAL_IP4_NETMASK 2 +#define INTERNAL_IP4_DNS 3 +#define INTERNAL_IP4_NBNS 4 +#define INTERNAL_ADDRESS_EXPIRY 5 +#define INTERNAL_IP4_DHCP 6 +#define APPLICATION_VERSION 7 +#define INTERNAL_IP6_ADDRESS 8 +#define INTERNAL_IP6_NETMASK 9 +#define INTERNAL_IP6_DNS 10 +#define INTERNAL_IP6_NBNS 11 +#define INTERNAL_IP6_DHCP 12 +#define INTERNAL_IP4_SUBNET 13 +#define SUPPORTED_ATTRIBUTES 14 +#define INTERNAL_IP6_SUBNET 15 +#define UNITY_BANNER 28672 +#define UNITY_SAVE_PASSWD 28673 +#define UNITY_DEF_DOMAIN 28674 +#define UNITY_SPLITDNS_NAME 28675 +#define UNITY_SPLIT_INCLUDE 28676 +#define UNITY_NATT_PORT 28677 +#define UNITY_LOCAL_LAN 28678 +#define UNITY_PFS 28679 +#define UNITY_FW_TYPE 28680 +#define UNITY_BACKUP_SERVERS 28681 +#define UNITY_DDNS_HOSTNAME 28682 + +/* 3.3 Data Attributes + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + !A! Attribute Type ! AF=0 Attribute Length ! + !F! ! AF=1 Attribute Value ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . AF=0 Attribute Value . + . AF=1 Not Transmitted . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +struct isakmp_data { + u_int16_t type; /* defined by DOI-spec, and Attribute Format */ + u_int16_t lorv; /* if f equal 1, Attribute Length */ + /* if f equal 0, Attribute Value */ + /* if f equal 1, Attribute Value */ +}; +#endif /* commands and status for vpn control. */ /* network byte order. */ @@ -99,6 +184,8 @@ struct vpnctl_hdr { struct vpnctl_cmd_bind { struct vpnctl_hdr hdr; u_int32_t address; /* 0xFFFFFFFF = all */ + u_int16_t vers_len; /* if zero - no version provided */ + /* name/version string of length vers_len */ }; /* unbind to stop receiving status for specified address */ @@ -107,14 +194,64 @@ struct vpnctl_cmd_unbind { u_int32_t address; /* 0xFFFFFFFF = all */ }; -/* redirect client to specified address */ -struct vpnctl_cmd_redirect { + +/* connect to specified address */ +struct vpnctl_cmd_connect{ struct vpnctl_hdr hdr; u_int32_t address; +}; + +struct vpnctl_sa_selector { + u_int32_t src_tunnel_address; + u_int32_t src_tunnel_mask; + u_int32_t dst_tunnel_address; + u_int32_t dst_tunnel_mask; + u_int16_t src_tunnel_port; + u_int16_t dst_tunnel_port; + u_int16_t ul_protocol; + u_int16_t reserved; +}; + +struct vpnctl_algo { + u_int16_t algo_class; + u_int16_t algo; + u_int16_t key_len; /* for enc algorithms only */ + u_int16_t reserved; +}; + +/* start phase 2 */ +struct vpnctl_cmd_start_ph2 { + struct vpnctl_hdr hdr; + u_int32_t address; + u_int32_t lifetime; /* seconds */ + u_int16_t pfs_group; /* defined in algorithm_types.h */ + u_int16_t selector_count; + u_int16_t algo_count; + u_int16_t reserved; + /* array of struct vpnctl_sa_selector */ + /* array of struct vpnctl_algo */ +}; + +/* set xauth info */ +struct vpnctl_cmd_xauth_info { + struct vpnctl_hdr hdr; + u_int32_t address; + /* packed array of variable sized struct isakmp_data */ +}; + +/* redirect client to specified address */ +struct vpnctl_cmd_redirect { + struct vpnctl_hdr hdr; + u_int32_t address; u_int32_t redirect_address; u_int16_t force; }; +/* start dpd */ +struct vpnctl_cmd_start_dpd { + struct vpnctl_hdr hdr; + u_int32_t address; +}; /* * IKE Notify codes - mirrors codes in isakmp.h @@ -150,6 +287,9 @@ struct vpnctl_cmd_redirect { #define VPNCTL_NTYPE_UNSUPPORTED_EXCHANGE_TYPE 29 #define VPNCTL_NTYPE_UNEQUAL_PAYLOAD_LENGTHS 30 #define VPNCTL_NTYPE_LOAD_BALANCE 40501 +#define VPNCTL_NTYPE_PEER_DEAD 50001 /* detected by DPD */ +#define VPNCTL_NTYPE_PH1_DELETE 50002 /* received a delete payload leaving no PH1 SA for the remote address */ +#define VPNCTL_NTYPE_IDLE_TIMEOUT 50003 #define VPNCTL_NTYPE_INTERNAL_ERROR -1 @@ -157,8 +297,37 @@ struct vpnctl_cmd_redirect { struct vpnctl_status_phase_change { struct vpnctl_hdr hdr; u_int32_t address; + /* The following is included when VPNCTL_FLAG_MODECFG_USED flag set */ + // struct vpnctl_modecfg_params mode_cfg; + +}; + + +/* packet format for auth needed status */ +struct vpnctl_status_need_authinfo { + struct vpnctl_hdr hdr; + u_int32_t address; + /* packed array of variable sized struct isakmp_data */ }; + +struct split_address { + u_int32_t splitaddr; + u_int32_t splitmask; +}; + +struct vpnctl_modecfg_params { + u_int32_t outer_local_addr; + u_int16_t outer_remote_port; + u_int16_t outer_local_port; + u_int8_t ifname[IFNAMSIZ]; + /* + * ifname for outer_local_addr (not null terminated) + * followed by packed array of attributes (struct isakmp_data) + */ +}; + + /* Packet formats for failed status */ struct vpnctl_status_failed { struct vpnctl_hdr hdr; diff --git a/ipsec-tools/racoon/vpn_control_var.h b/ipsec-tools/racoon/vpn_control_var.h index 59ad69e..79cf667 100644 --- a/ipsec-tools/racoon/vpn_control_var.h +++ b/ipsec-tools/racoon/vpn_control_var.h @@ -54,6 +54,8 @@ #ifndef _VPN_CONTROL_VAR_H #define _VPN_CONTROL_VAR_H +#include "vpn_control.h" + extern int vpncontrol_handler __P((void)); extern int vpncontrol_comm_handler __P((struct vpnctl_socket_elem *)); extern int vpncontrol_notify_ike_failed __P((u_int16_t, u_int16_t, u_int32_t, u_int16_t, u_int8_t*)); @@ -61,5 +63,9 @@ extern int vpncontrol_notify_phase_change __P((int, u_int16_t, struct ph1handle* extern int vpncontrol_init __P((void)); extern void vpncontrol_close __P((void)); extern int vpn_control_connected __P((void)); +extern int vpn_connect __P((struct bound_addr *)); +extern int vpn_disconnect __P((struct bound_addr *)); +extern int vpn_start_ph2 __P((struct bound_addr *, struct vpnctl_cmd_start_ph2 *)); +extern int vpncontrol_notify_need_authinfo __P((struct ph1handle *, void*, size_t)); #endif /* _VPN_CONTROL_VAR_H */ diff --git a/ipsec-tools/setkey/ipsecPolicyTracer.c b/ipsec-tools/setkey/ipsecPolicyTracer.c new file mode 100644 index 0000000..9b06ac5 --- /dev/null +++ b/ipsec-tools/setkey/ipsecPolicyTracer.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#import +#include +#include "ipsecPolicyTracer.h" +#include "ipsecMessageTracer.h" + +const char *ipsecConfigTracerFailedString = "Tracer Failed"; +const char *ipsecPolicyInvalidEventString = "Invalid Event"; +const char *ipsecPolicyString = "IPSEC"; + +const char * const ipsecPolicyEventStrings[IPSECPOLICYEVENTCODE_MAX] = { CONSTSTR("NONE") /* index place holder */, + CONSTSTR("setkey Error"), + }; + +const char * +ipsecPolicyEventCodeToString (ipsecPolicyEventCode_t eventCode) +{ + if (eventCode <= IPSECPOLICYEVENTCODE_NONE || eventCode >= IPSECPOLICYEVENTCODE_MAX) + return ipsecPolicyInvalidEventString; + return(ipsecPolicyEventStrings[eventCode]); +} + +static +void +ipsecPolicyLogEvent (const char *event_msg, const char *failure_signature) +{ + aslmsg m; + + if (!event_msg) { + return; + } + + m = asl_new(ASL_TYPE_MSG); + asl_set(m, ASL_KEY_FACILITY, PLAINIPSECDOMAIN); + asl_set(m, ASL_KEY_MSG, ipsecPolicyString); +#if 0 /* we don't want to send filenames to MessageTracer server */ + if (failure_signature) { + asl_set(m, "com.apple.message.domain", PLAINIPSECDOMAIN); + asl_set(m, "com.apple.message.result", "failure"); // failure + asl_set(m, "com.apple.message.signature", failure_signature); + } + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg); +#else + if (failure_signature) { + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s (failure: %s)", event_msg, failure_signature); + } else { + asl_log(NULL, m, ASL_LEVEL_NOTICE, "%s", event_msg); + } +#endif + asl_free(m); +} + +void +ipsecPolicyTracerEvent (const char *filename, ipsecPolicyEventCode_t eventCode, const char *event, const char *failure_reason) +{ + char buf[1024]; + + if (filename == NULL) { + ipsecPolicyLogEvent(CONSTSTR("tracer failed. (Invalid filename)."), ipsecConfigTracerFailedString); + return; + } + if (eventCode <= IPSECPOLICYEVENTCODE_NONE || eventCode >= IPSECPOLICYEVENTCODE_MAX) { + ipsecPolicyLogEvent(CONSTSTR("tracer failed. (Invalid event code)."), ipsecConfigTracerFailedString); + return; + } + if (event == NULL) { + ipsecPolicyLogEvent(CONSTSTR("tracer failed. (Invalid event)."), ipsecConfigTracerFailedString); + return; + } + + buf[0] = (char)0; + snprintf(buf, sizeof(buf), "%s. (%s, filename %s).", ipsecPolicyEventCodeToString(eventCode), failure_reason, filename); + ipsecPolicyLogEvent(CONSTSTR(buf), event); +} diff --git a/ipsec-tools/setkey/ipsecPolicyTracer.h b/ipsec-tools/setkey/ipsecPolicyTracer.h new file mode 100644 index 0000000..4e9ff3b --- /dev/null +++ b/ipsec-tools/setkey/ipsecPolicyTracer.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IPSECPOLICYTRACER_H +#define _IPSECPOLICYTRACER_H + +typedef enum ipsecPolicyEventCode { + IPSECPOLICYEVENTCODE_NONE = 0, + IPSECPOLICYEVENTCODE_SETKEY_ERROR, + IPSECPOLICYEVENTCODE_MAX, +} ipsecPolicyEventCode_t; + +const char * ipsecPolicyEventCodeToString (ipsecPolicyEventCode_t); +void ipsecPolicyTracerEvent (const char *, ipsecPolicyEventCode_t, const char *, const char *); + +#endif /* _IPSECPOLICYTRACER_H */ diff --git a/ipsec-tools/setkey/setkey.c b/ipsec-tools/setkey/setkey.c index 1c9445f..5afba1b 100644 --- a/ipsec-tools/setkey/setkey.c +++ b/ipsec-tools/setkey/setkey.c @@ -74,8 +74,9 @@ //#include "package_version.h" #define extern /* so that variables in extern.h are not extern... */ #include "extern.h" +#include "ipsecPolicyTracer.h" +#include "ipsecMessageTracer.h" -#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0') void usage __P((/*int*/)); int main __P((int, char **)); @@ -172,6 +173,10 @@ main(argc, argv) case 'f': f_mode = MODE_SCRIPT; if ((fp = fopen(optarg, "r")) == NULL) { + IPSECPOLICYTRACEREVENT(optarg, + IPSECPOLICYEVENTCODE_SETKEY_ERROR, + CONSTSTR("could not open policy file"), + CONSTSTR("setkey -f : fopen erred")); err(1, "fopen"); /*NOTREACHED*/ } @@ -244,6 +249,10 @@ main(argc, argv) if (argc > 0) { while (argc--) if (fileproc(*argv++) < 0) { + IPSECPOLICYTRACEREVENT(argv[-1], + IPSECPOLICYEVENTCODE_SETKEY_ERROR, + CONSTSTR("could not parse policy file"), + CONSTSTR("setkey: fileproc erred")); err(1, "%s", argv[-1]); /*NOTREACHED*/ } @@ -252,6 +261,10 @@ main(argc, argv) so = pfkey_open(); if (so < 0) { + IPSECPOLICYTRACEREVENT(argv[-1], + IPSECPOLICYEVENTCODE_SETKEY_ERROR, + CONSTSTR("couldn't open pfkey socket"), + CONSTSTR("setkey: pfkey_open erred")); perror("pfkey_open"); exit(1); } @@ -273,6 +286,10 @@ main(argc, argv) break; case MODE_STDIN: if (get_supported() < 0) { + IPSECPOLICYTRACEREVENT("STDIN", + IPSECPOLICYEVENTCODE_SETKEY_ERROR, + CONSTSTR(ipsec_strerror()), + CONSTSTR("setkey: get_supported erred")); errx(1, "%s", ipsec_strerror()); /*NOTREACHED*/ } diff --git a/ipsec.plist b/ipsec.plist new file mode 100644 index 0000000..2b0ea9c --- /dev/null +++ b/ipsec.plist @@ -0,0 +1,29 @@ +( + { + "OpenSourceModifications" = ( + "Several security updates, memory leak fixes from 0.7.1 (ported by Les Aug/08)", + ); + OpenSourceProject = racoon; + OpenSourceVersion = "0.6.7"; + OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools"; + OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src"; + }, + { + OpenSourceProject = libipsec; + OpenSourceVersion = "0.6.5"; + OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools"; + OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src"; + }, + { + OpenSourceProject = setkey; + OpenSourceVersion = "0.6.5"; + OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools"; + OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src"; + }, + { + OpenSourceProject = racoonctl; + OpenSourceVersion = "0.6.5"; + OpenSourceWebsiteURL = "http://www.sourceforge.net/projects/ipsec-tools"; + OpenSourceURL = "http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src"; + }, +) \ No newline at end of file diff --git a/ipsec.xcodeproj/project.pbxproj b/ipsec.xcodeproj/project.pbxproj index 964f919..57d9478 100644 --- a/ipsec.xcodeproj/project.pbxproj +++ b/ipsec.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 42; + objectVersion = 45; objects = { /* Begin PBXAggregateTarget section */ @@ -11,6 +11,7 @@ isa = PBXAggregateTarget; buildConfigurationList = 25D3DAB8098952B20025F703 /* Build configuration list for PBXAggregateTarget "IPSec (Aggregate)" */; buildPhases = ( + 72265DD80F818ED700730A7D /* CopyFiles */, ); dependencies = ( 25D3DDE30989AFDE0025F703 /* PBXTargetDependency */, @@ -22,6 +23,21 @@ name = "IPSec (Aggregate)"; productName = "IPSec (Aggregate)"; }; + 812530AA0D3FE994006BDF4F /* IPSec Embedded (Aggregate) */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 812530B50D3FE994006BDF4F /* Build configuration list for PBXAggregateTarget "IPSec Embedded (Aggregate)" */; + buildPhases = ( + ); + dependencies = ( + 812531110D3FEA28006BDF4F /* PBXTargetDependency */, + 81DDFDD90D622C4E00C5CB87 /* PBXTargetDependency */, + 8125312C0D3FEA44006BDF4F /* PBXTargetDependency */, + 81DDFDDB0D622C5100C5CB87 /* PBXTargetDependency */, + 81DDFDF10D627DE300C5CB87 /* PBXTargetDependency */, + ); + name = "IPSec Embedded (Aggregate)"; + productName = "IPSec (Aggregate) Embedded"; + }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ @@ -59,9 +75,6 @@ 258CF2D40A191A5000166B38 /* plainrsa-gen.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F258FB0988657000D15623 /* plainrsa-gen.8 */; }; 258CF2E10A191A9200166B38 /* racoon.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F259090988657000D15623 /* racoon.8 */; }; 258CF2E40A191AD500166B38 /* racoon.conf.5 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2590A0988657000D15623 /* racoon.conf.5 */; }; - 258CF2E60A191B1800166B38 /* racoon.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2589A098864D700D15623 /* racoon.conf */; }; - 258CF2FB0A191B4F00166B38 /* anonymous.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F25898098864D700D15623 /* anonymous.conf */; }; - 258CF2FC0A191B5400166B38 /* psk.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F25899098864D700D15623 /* psk.txt */; }; 25BC48740A0BC7B000A181A0 /* eaytest.c in Sources */ = {isa = PBXBuildFile; fileRef = 25BC48730A0BC7B000A181A0 /* eaytest.c */; }; 25BE7E0109E5D3F4009B6B84 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; }; 25BE7E1209E5D550009B6B84 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE84709D879700042CC7F /* libssl.dylib */; }; @@ -93,12 +106,8 @@ 25DE2DE90A8BD40E0010A46D /* vpn_control.c in Sources */ = {isa = PBXBuildFile; fileRef = 25DE2DE60A8BD40E0010A46D /* vpn_control.c */; }; 25E08C9E09D9E681001A11CF /* prsa_par.y in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBA809D8B727002DC960 /* prsa_par.y */; }; 25E08C9F09D9E682001A11CF /* prsa_tok.l in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBAA09D8B727002DC960 /* prsa_tok.l */; }; - 25EAE83209D875790042CC7F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83109D875790042CC7F /* Security.framework */; }; - 25EAE83809D875BF0042CC7F /* DirectoryService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83709D875BF0042CC7F /* DirectoryService.framework */; }; 25EAE84809D879700042CC7F /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE84709D879700042CC7F /* libssl.dylib */; }; 25EAE84B09D879DE0042CC7F /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE84A09D879DE0042CC7F /* libcrypto.dylib */; }; - 25EAE87209D87A160042CC7F /* libgssapi_krb5.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87109D87A160042CC7F /* libgssapi_krb5.dylib */; }; - 25EAE87409D87A390042CC7F /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87309D87A390042CC7F /* libpam.dylib */; }; 25EAE87709D87A770042CC7F /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87609D87A770042CC7F /* libiconv.dylib */; }; 25EAE8C109D87B080042CC7F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE8C009D87B080042CC7F /* CoreFoundation.framework */; }; 25EAE8C609D87B990042CC7F /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; }; @@ -115,7 +124,6 @@ 25F2592A0988657000D15623 /* backupsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B10988657000D15623 /* backupsa.c */; }; 25F2592B0988657000D15623 /* cfparse.y in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B40988657000D15623 /* cfparse.y */; }; 25F2592C0988657000D15623 /* cftoken.l in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B60988657000D15623 /* cftoken.l */; }; - 25F2592D0988657000D15623 /* crypto_cssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B70988657000D15623 /* crypto_cssm.c */; }; 25F2592E0988657000D15623 /* crypto_openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B90988657000D15623 /* crypto_openssl.c */; }; 25F2592F0988657000D15623 /* dnssec.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258BE0988657000D15623 /* dnssec.c */; }; 25F259310988657000D15623 /* evt.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C20988657000D15623 /* evt.c */; }; @@ -137,7 +145,6 @@ 25F259460988657000D15623 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258ED0988657000D15623 /* main.c */; }; 25F259470988657000D15623 /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EE0988657000D15623 /* misc.c */; }; 25F259490988657000D15623 /* oakley.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F30988657000D15623 /* oakley.c */; }; - 25F2594A0988657000D15623 /* open_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F50988657000D15623 /* open_dir.c */; }; 25F2594C0988657000D15623 /* pfkey_racoon.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F80988657000D15623 /* pfkey_racoon.c */; }; 25F2594F0988657000D15623 /* plog.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FD0988657000D15623 /* plog.c */; }; 25F259500988657000D15623 /* policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FF0988657000D15623 /* policy.c */; }; @@ -154,8 +161,129 @@ 25F259610988657000D15623 /* throttle.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259210988657000D15623 /* throttle.c */; }; 25F259620988657000D15623 /* vendorid.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259240988657000D15623 /* vendorid.c */; }; 25F259630988657000D15623 /* vmbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259260988657000D15623 /* vmbuf.c */; }; + 72265DDC0F818F9300730A7D /* ipsec.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 72265DDB0F818F9300730A7D /* ipsec.plist */; }; + 72B433770E3677D800D67508 /* com.apple.racoon.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 724F99500E3672FD00C56897 /* com.apple.racoon.plist */; }; + 812530C00D3FE9DC006BDF4F /* rijndael-alg-fst.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258A10988651000D15623 /* rijndael-alg-fst.c */; }; + 812530C10D3FE9DC006BDF4F /* rijndael-api-fst.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258A30988651000D15623 /* rijndael-api-fst.c */; }; + 812530C20D3FE9DC006BDF4F /* admin.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258AC0988657000D15623 /* admin.c */; }; + 812530C30D3FE9DC006BDF4F /* algorithm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258AE0988657000D15623 /* algorithm.c */; }; + 812530C40D3FE9DC006BDF4F /* backupsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B10988657000D15623 /* backupsa.c */; }; + 812530C50D3FE9DC006BDF4F /* cfparse.y in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B40988657000D15623 /* cfparse.y */; }; + 812530C60D3FE9DC006BDF4F /* cftoken.l in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B60988657000D15623 /* cftoken.l */; }; + 812530C70D3FE9DC006BDF4F /* crypto_openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B90988657000D15623 /* crypto_openssl.c */; }; + 812530C80D3FE9DC006BDF4F /* dnssec.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258BE0988657000D15623 /* dnssec.c */; }; + 812530C90D3FE9DC006BDF4F /* evt.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C20988657000D15623 /* evt.c */; }; + 812530CA0D3FE9DC006BDF4F /* genlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C50988657000D15623 /* genlist.c */; }; + 812530CB0D3FE9DC006BDF4F /* getcertsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C70988657000D15623 /* getcertsbyname.c */; }; + 812530CC0D3FE9DC006BDF4F /* grabmyaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258C90988657000D15623 /* grabmyaddr.c */; }; + 812530CD0D3FE9DC006BDF4F /* gssapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258CB0988657000D15623 /* gssapi.c */; }; + 812530CE0D3FE9DC006BDF4F /* handler.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258CD0988657000D15623 /* handler.c */; }; + 812530CF0D3FE9DC006BDF4F /* ipsec_doi.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258CF0988657000D15623 /* ipsec_doi.c */; }; + 812530D00D3FE9DC006BDF4F /* isakmp_agg.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D10988657000D15623 /* isakmp_agg.c */; }; + 812530D10D3FE9DC006BDF4F /* isakmp_base.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D30988657000D15623 /* isakmp_base.c */; }; + 812530D20D3FE9DC006BDF4F /* isakmp_ident.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D90988657000D15623 /* isakmp_ident.c */; }; + 812530D30D3FE9DC006BDF4F /* isakmp_inf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258DB0988657000D15623 /* isakmp_inf.c */; }; + 812530D40D3FE9DC006BDF4F /* isakmp_newg.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258DD0988657000D15623 /* isakmp_newg.c */; }; + 812530D50D3FE9DC006BDF4F /* isakmp_quick.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258DF0988657000D15623 /* isakmp_quick.c */; }; + 812530D60D3FE9DC006BDF4F /* isakmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E60988657000D15623 /* isakmp.c */; }; + 812530D70D3FE9DC006BDF4F /* localconf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E90988657000D15623 /* localconf.c */; }; + 812530D80D3FE9DC006BDF4F /* logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EB0988657000D15623 /* logger.c */; }; + 812530D90D3FE9DC006BDF4F /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258ED0988657000D15623 /* main.c */; }; + 812530DA0D3FE9DC006BDF4F /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EE0988657000D15623 /* misc.c */; }; + 812530DB0D3FE9DC006BDF4F /* oakley.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F30988657000D15623 /* oakley.c */; }; + 812530DC0D3FE9DC006BDF4F /* pfkey_racoon.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F80988657000D15623 /* pfkey_racoon.c */; }; + 812530DD0D3FE9DC006BDF4F /* plog.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FD0988657000D15623 /* plog.c */; }; + 812530DE0D3FE9DC006BDF4F /* policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258FF0988657000D15623 /* policy.c */; }; + 812530DF0D3FE9DC006BDF4F /* privsep.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259010988657000D15623 /* privsep.c */; }; + 812530E00D3FE9DC006BDF4F /* proposal.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259030988657000D15623 /* proposal.c */; }; + 812530E10D3FE9DC006BDF4F /* remoteconf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2590E0988657000D15623 /* remoteconf.c */; }; + 812530E20D3FE9DC006BDF4F /* safefile.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259120988657000D15623 /* safefile.c */; }; + 812530E30D3FE9DC006BDF4F /* sainfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259140988657000D15623 /* sainfo.c */; }; + 812530E40D3FE9DC006BDF4F /* schedule.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259160988657000D15623 /* schedule.c */; }; + 812530E50D3FE9DC006BDF4F /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259180988657000D15623 /* session.c */; }; + 812530E60D3FE9DC006BDF4F /* sockmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591A0988657000D15623 /* sockmisc.c */; }; + 812530E70D3FE9DC006BDF4F /* str2val.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591D0988657000D15623 /* str2val.c */; }; + 812530E80D3FE9DC006BDF4F /* strnames.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591F0988657000D15623 /* strnames.c */; }; + 812530E90D3FE9DC006BDF4F /* throttle.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259210988657000D15623 /* throttle.c */; }; + 812530EA0D3FE9DC006BDF4F /* vendorid.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259240988657000D15623 /* vendorid.c */; }; + 812530EB0D3FE9DC006BDF4F /* vmbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259260988657000D15623 /* vmbuf.c */; }; + 812530EC0D3FE9DC006BDF4F /* nattraversal.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F00988657000D15623 /* nattraversal.c */; }; + 812530ED0D3FE9DC006BDF4F /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; }; + 812530EE0D3FE9DC006BDF4F /* rsalist.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259100988657000D15623 /* rsalist.c */; }; + 812530EF0D3FE9DC006BDF4F /* isakmp_cfg.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258D50988657000D15623 /* isakmp_cfg.c */; }; + 812530F00D3FE9DC006BDF4F /* isakmp_unity.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E10988657000D15623 /* isakmp_unity.c */; }; + 812530F10D3FE9DC006BDF4F /* isakmp_xauth.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E40988657000D15623 /* isakmp_xauth.c */; }; + 812530F20D3FE9DC006BDF4F /* vpn_control.c in Sources */ = {isa = PBXBuildFile; fileRef = 25DE2DE60A8BD40E0010A46D /* vpn_control.c */; }; + 812530F30D3FE9DC006BDF4F /* vpn.c in Sources */ = {isa = PBXBuildFile; fileRef = 81CA08910CE3BC870055C0AF /* vpn.c */; }; + 812530F80D3FE9DC006BDF4F /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87609D87A770042CC7F /* libiconv.dylib */; }; + 812530F90D3FE9DC006BDF4F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE8C009D87B080042CC7F /* CoreFoundation.framework */; }; + 812530FC0D3FE9DC006BDF4F /* racoon.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F259090988657000D15623 /* racoon.8 */; }; + 812530FE0D3FE9DC006BDF4F /* racoon.conf.5 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2590A0988657000D15623 /* racoon.conf.5 */; }; + 812531160D3FEA33006BDF4F /* racoonctl.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2590C0988657000D15623 /* racoonctl.c */; }; + 812531170D3FEA33006BDF4F /* str2val.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591D0988657000D15623 /* str2val.c */; }; + 812531180D3FEA33006BDF4F /* kmpstat.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258E80988657000D15623 /* kmpstat.c */; }; + 812531190D3FEA33006BDF4F /* vmbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F259260988657000D15623 /* vmbuf.c */; }; + 8125311A0D3FEA33006BDF4F /* sockmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2591A0988657000D15623 /* sockmisc.c */; }; + 8125311B0D3FEA33006BDF4F /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258EE0988657000D15623 /* misc.c */; }; + 8125311C0D3FEA33006BDF4F /* pfkey_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777ED09ABE58400C99783 /* pfkey_dump.c */; }; + 8125311D0D3FEA33006BDF4F /* key_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777B909ABE3E100C99783 /* key_debug.c */; }; + 8125311E0D3FEA33006BDF4F /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; }; + 812531220D3FEA33006BDF4F /* racoonctl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F2590B0988657000D15623 /* racoonctl.8 */; }; + 812A64ED0D4AA082004CB7EB /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 812A64EC0D4AA082004CB7EB /* Security.framework */; }; + 8167917B0D650BAA006B523F /* racoon.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103A0D5BE18800C7B441 /* racoon.conf */; }; + 8176A6B90D45661700BC5251 /* libldap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8176A6B80D45661700BC5251 /* libldap.dylib */; }; + 817FFC4E0D6134A7004A8DD8 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; }; + 817FFC4F0D6134AD004A8DD8 /* rsaparse.o in Frameworks */ = {isa = PBXBuildFile; fileRef = 25E08C9A09D9E64A001A11CF /* rsaparse.o */; }; + 817FFC5A0D613729004A8DD8 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; }; + 818710410D5BE22B00C7B441 /* psk.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103D0D5BE1CF00C7B441 /* psk.txt */; }; + 818710420D5BE22F00C7B441 /* racoon.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103B0D5BE1B400C7B441 /* racoon.conf */; }; + 818710510D5BE29300C7B441 /* psk.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103D0D5BE1CF00C7B441 /* psk.txt */; }; + 818710530D5BE2B500C7B441 /* anonymous.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8187103C0D5BE1CF00C7B441 /* anonymous.conf */; }; + 81C325A80D46A36900E65EB7 /* crypto_cssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B70988657000D15623 /* crypto_cssm.c */; }; + 81C386AA0D451EC300975D5E /* crypto_cssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258B70988657000D15623 /* crypto_cssm.c */; }; + 81C387560D45208700975D5E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83109D875790042CC7F /* Security.framework */; }; + 81C387570D45208700975D5E /* DirectoryService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE83709D875BF0042CC7F /* DirectoryService.framework */; }; + 81C3877A0D4524E700975D5E /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87309D87A390042CC7F /* libpam.dylib */; }; + 81C387890D4524F600975D5E /* libgssapi_krb5.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EAE87109D87A160042CC7F /* libgssapi_krb5.dylib */; }; + 81C387EC0D45268300975D5E /* open_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F258F50988657000D15623 /* open_dir.c */; }; + 81C964590DA2CBEF00257BC8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C964580DA2CBEF00257BC8 /* SystemConfiguration.framework */; }; + 81C9645E0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */; }; + 81C9645F0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */; }; + 81CA08920CE3BC870055C0AF /* vpn.c in Sources */ = {isa = PBXBuildFile; fileRef = 81CA08910CE3BC870055C0AF /* vpn.c */; }; + 81DDFD9B0D622C1700C5CB87 /* parse.y in Sources */ = {isa = PBXBuildFile; fileRef = 25F258870988648C00D15623 /* parse.y */; }; + 81DDFD9C0D622C1700C5CB87 /* pfkey_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777ED09ABE58400C99783 /* pfkey_dump.c */; }; + 81DDFD9D0D622C1700C5CB87 /* key_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F777B909ABE3E100C99783 /* key_debug.c */; }; + 81DDFD9E0D622C1700C5CB87 /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25D949A209A6AAD700CA0F24 /* pfkey.c */; }; + 81DDFD9F0D622C1700C5CB87 /* setkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 25F2588A0988648C00D15623 /* setkey.c */; }; + 81DDFDA00D622C1700C5CB87 /* token.l in Sources */ = {isa = PBXBuildFile; fileRef = 25F2588D0988648C00D15623 /* token.l */; }; + 81DDFDA20D622C1700C5CB87 /* libipsec.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */; }; + 81DDFDA40D622C1700C5CB87 /* setkey.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 25F258890988648C00D15623 /* setkey.8 */; }; + 81DDFDBA0D622C2700C5CB87 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 25D9499F09A6AAD700CA0F24 /* config.h */; }; + 81DDFDBB0D622C2700C5CB87 /* ipsec_strerror.h in Headers */ = {isa = PBXBuildFile; fileRef = 252DF9570989B4EE00E5B678 /* ipsec_strerror.h */; }; + 81DDFDBD0D622C2700C5CB87 /* ipsec_dump_policy.c in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9520989B4EE00E5B678 /* ipsec_dump_policy.c */; }; + 81DDFDBE0D622C2700C5CB87 /* ipsec_get_policylen.c in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9530989B4EE00E5B678 /* ipsec_get_policylen.c */; }; + 81DDFDBF0D622C2700C5CB87 /* ipsec_strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9560989B4EE00E5B678 /* ipsec_strerror.c */; }; + 81DDFDC00D622C2700C5CB87 /* policy_parse.y in Sources */ = {isa = PBXBuildFile; fileRef = 252DF95E0989B4EE00E5B678 /* policy_parse.y */; }; + 81DDFDC10D622C2700C5CB87 /* policy_token.l in Sources */ = {isa = PBXBuildFile; fileRef = 252DF9600989B4EE00E5B678 /* policy_token.l */; }; + 81DDFDC40D622C2700C5CB87 /* ipsec_set_policy.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 252DF9540989B4EE00E5B678 /* ipsec_set_policy.3 */; }; + 81DDFDC50D622C2700C5CB87 /* ipsec_strerror.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 252DF9550989B4EE00E5B678 /* ipsec_strerror.3 */; }; + 81DDFDC60D622C2700C5CB87 /* ipsec_get_policylen.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0680B5D8D8900840BC7 /* ipsec_get_policylen.3 */; }; + 81DDFDC70D622C2700C5CB87 /* ipsec_dump_policy.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0670B5D8D7000840BC7 /* ipsec_dump_policy.3 */; }; + 81DDFDD00D622C3500C5CB87 /* prsa_par.y in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBA809D8B727002DC960 /* prsa_par.y */; }; + 81DDFDD10D622C3500C5CB87 /* prsa_tok.l in Sources */ = {isa = PBXBuildFile; fileRef = 2589CBAA09D8B727002DC960 /* prsa_tok.l */; }; 81EDB0690B5D8D9600840BC7 /* ipsec_get_policylen.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0680B5D8D8900840BC7 /* ipsec_get_policylen.3 */; }; 81EDB06A0B5D8D9A00840BC7 /* ipsec_dump_policy.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 81EDB0670B5D8D7000840BC7 /* ipsec_dump_policy.3 */; }; + 834072A90EDCC5AC00B6CCE8 /* com.apple.racoon.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 724F99500E3672FD00C56897 /* com.apple.racoon.plist */; }; + 8D5B16750E5F7F4E00E72675 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5B16230E5F7E9300E72675 /* libresolv.dylib */; }; + 8D5B167D0E5F7F9F00E72675 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5B16230E5F7E9300E72675 /* libresolv.dylib */; }; + BA5B6F2A0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */; }; + BA5B6F2B0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */; }; + BA5B6F2C0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */; }; + BA5B6F2D0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */; }; + BA5B6F310EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */; }; + BA5B6F320EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */; }; + BA6F109B0EA1DEC200546773 /* ike_session.c in Sources */ = {isa = PBXBuildFile; fileRef = BA6F109A0EA1DEC200546773 /* ike_session.c */; }; + BA6F109C0EA1DEC200546773 /* ike_session.c in Sources */ = {isa = PBXBuildFile; fileRef = BA6F109A0EA1DEC200546773 /* ike_session.c */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -250,6 +378,62 @@ remoteGlobalIDString = 25E08C9909D9E64A001A11CF; remoteInfo = rsaparse; }; + 812531100D3FEA28006BDF4F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 812530BA0D3FE9DC006BDF4F; + remoteInfo = "racoon arm"; + }; + 8125312B0D3FEA44006BDF4F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 812531120D3FEA33006BDF4F; + remoteInfo = "racoonctl arm"; + }; + 81DDFDD80D622C4E00C5CB87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 81DDFDB80D622C2700C5CB87; + remoteInfo = "libipsec Embedded"; + }; + 81DDFDDA0D622C5100C5CB87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 81DDFDCE0D622C3500C5CB87; + remoteInfo = "rsaparse Embedded"; + }; + 81DDFDDE0D622D1700C5CB87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 81DDFDB80D622C2700C5CB87; + remoteInfo = "libipsec Embedded"; + }; + 81DDFDE00D622D2A00C5CB87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 81DDFDCE0D622C3500C5CB87; + remoteInfo = "rsaparse Embedded"; + }; + 81DDFDE30D622D8C00C5CB87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 81DDFDB80D622C2700C5CB87; + remoteInfo = "libipsec Embedded"; + }; + 81DDFDF00D627DE300C5CB87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23D2D790087071FC00C51098 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 81DDFD970D622C1700C5CB87; + remoteInfo = "setkey Embedded"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -309,31 +493,134 @@ 258CF2F80A191B3900166B38 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; - dstPath = /usr/share/man/man5; - dstSubfolderSpec = 0; + dstPath = usr/share/man/man5; + dstSubfolderSpec = 16; files = ( 258CF2E40A191AD500166B38 /* racoon.conf.5 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; - 258CF2F90A191B3900166B38 /* CopyFiles */ = { + 258CF2FA0A191B3900166B38 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /private/etc/racoon; dstSubfolderSpec = 0; files = ( - 258CF2FC0A191B5400166B38 /* psk.txt in CopyFiles */, - 258CF2E60A191B1800166B38 /* racoon.conf in CopyFiles */, + 818710410D5BE22B00C7B441 /* psk.txt in CopyFiles */, + 818710420D5BE22F00C7B441 /* racoon.conf in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; - 258CF2FA0A191B3900166B38 /* CopyFiles */ = { + 72265DD80F818ED700730A7D /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/local/OpenSourceVersions/; + dstSubfolderSpec = 0; + files = ( + 72265DDC0F818F9300730A7D /* ipsec.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 724A38A20E3676FB00F6B25F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + 72B433770E3677D800D67508 /* com.apple.racoon.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 725F453B0E36A15C005BB55C /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + 834072A90EDCC5AC00B6CCE8 /* com.apple.racoon.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 812530FB0D3FE9DC006BDF4F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man8; + dstSubfolderSpec = 0; + files = ( + 812530FC0D3FE9DC006BDF4F /* racoon.8 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 812530FD0D3FE9DC006BDF4F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man5; + dstSubfolderSpec = 0; + files = ( + 812530FE0D3FE9DC006BDF4F /* racoon.conf.5 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 812530FF0D3FE9DC006BDF4F /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /private/etc/racoon/remote; dstSubfolderSpec = 0; files = ( - 258CF2FB0A191B4F00166B38 /* anonymous.conf in CopyFiles */, + 818710530D5BE2B500C7B441 /* anonymous.conf in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 812531020D3FE9DC006BDF4F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /private/etc/racoon; + dstSubfolderSpec = 0; + files = ( + 818710510D5BE29300C7B441 /* psk.txt in CopyFiles */, + 8167917B0D650BAA006B523F /* racoon.conf in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 812531210D3FEA33006BDF4F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man8; + dstSubfolderSpec = 0; + files = ( + 812531220D3FEA33006BDF4F /* racoonctl.8 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 81DDFDA30D622C1700C5CB87 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man8; + dstSubfolderSpec = 0; + files = ( + 81DDFDA40D622C1700C5CB87 /* setkey.8 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 81DDFDC30D622C2700C5CB87 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man3; + dstSubfolderSpec = 0; + files = ( + 81DDFDC40D622C2700C5CB87 /* ipsec_set_policy.3 in CopyFiles */, + 81DDFDC50D622C2700C5CB87 /* ipsec_strerror.3 in CopyFiles */, + 81DDFDC60D622C2700C5CB87 /* ipsec_get_policylen.3 in CopyFiles */, + 81DDFDC70D622C2700C5CB87 /* ipsec_dump_policy.3 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 834072BB0EDCC5C400B6CCE8 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( ); runOnlyForDeploymentPostprocessing = 1; }; @@ -386,9 +673,6 @@ 25F25895098864AB00D15623 /* sample-policy01.cf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "sample-policy01.cf"; sourceTree = ""; }; 25F25896098864AB00D15623 /* sample-policy02.cf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "sample-policy02.cf"; sourceTree = ""; }; 25F25897098864AB00D15623 /* sample.cf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = sample.cf; sourceTree = ""; }; - 25F25898098864D700D15623 /* anonymous.conf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = anonymous.conf; sourceTree = ""; }; - 25F25899098864D700D15623 /* psk.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = psk.txt; sourceTree = ""; }; - 25F2589A098864D700D15623 /* racoon.conf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = racoon.conf; sourceTree = ""; }; 25F2589B098864F500D15623 /* FAQ */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = FAQ; sourceTree = ""; }; 25F2589C098864F500D15623 /* README.certificate */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.certificate; sourceTree = ""; }; 25F2589D098864F500D15623 /* README.gssapi */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.gssapi; sourceTree = ""; }; @@ -520,8 +804,37 @@ 25F259270988657000D15623 /* vmbuf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vmbuf.h; sourceTree = ""; }; 25F777B909ABE3E100C99783 /* key_debug.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = key_debug.c; path = Common/key_debug.c; sourceTree = ""; }; 25F777ED09ABE58400C99783 /* pfkey_dump.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pfkey_dump.c; path = Common/pfkey_dump.c; sourceTree = ""; }; + 72265DDB0F818F9300730A7D /* ipsec.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = ipsec.plist; sourceTree = ""; }; + 724F99500E3672FD00C56897 /* com.apple.racoon.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.racoon.plist; sourceTree = ""; }; + 8125310A0D3FE9DC006BDF4F /* racoon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = racoon; sourceTree = BUILT_PRODUCTS_DIR; }; + 812531290D3FEA33006BDF4F /* racoonctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = racoonctl; sourceTree = BUILT_PRODUCTS_DIR; }; + 812A64EC0D4AA082004CB7EB /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = SDKs/Purple/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; + 8176A6B80D45661700BC5251 /* libldap.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libldap.dylib; path = /usr/lib/libldap.dylib; sourceTree = ""; }; + 81856B700D6B8BC5001DAE21 /* algorithm_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = algorithm_types.h; sourceTree = ""; }; + 8187103A0D5BE18800C7B441 /* racoon.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = racoon.conf; path = Sample/Embedded/racoon.conf; sourceTree = ""; }; + 8187103B0D5BE1B400C7B441 /* racoon.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = racoon.conf; path = Sample/racoon.conf; sourceTree = ""; }; + 8187103C0D5BE1CF00C7B441 /* anonymous.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = anonymous.conf; path = Sample/anonymous.conf; sourceTree = ""; }; + 8187103D0D5BE1CF00C7B441 /* psk.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = psk.txt; path = Sample/psk.txt; sourceTree = ""; }; + 81C964580DA2CBEF00257BC8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; + 81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = ""; }; + 81CA08910CE3BC870055C0AF /* vpn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vpn.c; sourceTree = ""; }; + 81DDFDAA0D622C1700C5CB87 /* setkey */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = setkey; sourceTree = BUILT_PRODUCTS_DIR; }; + 81DDFDCD0D622C2700C5CB87 /* libipsec.A.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libipsec.A.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + 81DDFDD70D622C3500C5CB87 /* rsaparse.o */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.objfile"; includeInIndex = 0; path = rsaparse.o; sourceTree = BUILT_PRODUCTS_DIR; }; 81EDB0670B5D8D7000840BC7 /* ipsec_dump_policy.3 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = ipsec_dump_policy.3; path = libipsec/ipsec_dump_policy.3; sourceTree = ""; }; 81EDB0680B5D8D8900840BC7 /* ipsec_get_policylen.3 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = ipsec_get_policylen.3; path = libipsec/ipsec_get_policylen.3; sourceTree = ""; }; + 8D5B16230E5F7E9300E72675 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.dylib; path = /usr/lib/libresolv.dylib; sourceTree = ""; }; + BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipsecConfigTracer.c; sourceTree = ""; }; + BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipsecSessionTracer.c; sourceTree = ""; }; + BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipsecPolicyTracer.c; sourceTree = ""; }; + BA5B6F350EC1A03C003774E7 /* ipsecMessageTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ipsecMessageTracer.h; path = Common/ipsecMessageTracer.h; sourceTree = ""; }; + BA5B6F360EC1A03C003774E7 /* ipsecConfigTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipsecConfigTracer.h; sourceTree = ""; }; + BA5B6F370EC1A03C003774E7 /* ipsecSessionTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipsecSessionTracer.h; sourceTree = ""; }; + BA5B6F380EC1A03C003774E7 /* ipsecPolicyTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipsecPolicyTracer.h; sourceTree = ""; }; + BA5B6F4F0EC1A136003774E7 /* vpn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vpn.h; sourceTree = ""; }; + BA6F10940EA1D67700546773 /* ike_session.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ike_session.h; sourceTree = ""; }; + BA6F109A0EA1DEC200546773 /* ike_session.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ike_session.c; sourceTree = ""; }; + C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = AspenSDK.xcconfig; path = AppleInternal/XcodeConfig/AspenSDK.xcconfig; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -579,16 +892,19 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 81C387570D45208700975D5E /* DirectoryService.framework in Frameworks */, + 81C387560D45208700975D5E /* Security.framework in Frameworks */, + 25EAE8C109D87B080042CC7F /* CoreFoundation.framework in Frameworks */, + 8D5B16750E5F7F4E00E72675 /* libresolv.dylib in Frameworks */, 2537A1C709E49D0600D0ECDA /* libipsec.A.dylib in Frameworks */, - 25EAE83209D875790042CC7F /* Security.framework in Frameworks */, - 25EAE83809D875BF0042CC7F /* DirectoryService.framework in Frameworks */, 25EAE84809D879700042CC7F /* libssl.dylib in Frameworks */, 25EAE84B09D879DE0042CC7F /* libcrypto.dylib in Frameworks */, - 25EAE87209D87A160042CC7F /* libgssapi_krb5.dylib in Frameworks */, - 25EAE87409D87A390042CC7F /* libpam.dylib in Frameworks */, + 81C387890D4524F600975D5E /* libgssapi_krb5.dylib in Frameworks */, + 81C3877A0D4524E700975D5E /* libpam.dylib in Frameworks */, 25EAE87709D87A770042CC7F /* libiconv.dylib in Frameworks */, - 25EAE8C109D87B080042CC7F /* CoreFoundation.framework in Frameworks */, 25DC9ED709DB170800C89F86 /* rsaparse.o in Frameworks */, + 8176A6B90D45661700BC5251 /* libldap.dylib in Frameworks */, + 81C9645F0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -608,12 +924,59 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 812530F40D3FE9DC006BDF4F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 817FFC4F0D6134AD004A8DD8 /* rsaparse.o in Frameworks */, + 8D5B167D0E5F7F9F00E72675 /* libresolv.dylib in Frameworks */, + 817FFC4E0D6134A7004A8DD8 /* libipsec.A.dylib in Frameworks */, + 812530F80D3FE9DC006BDF4F /* libiconv.dylib in Frameworks */, + 812530F90D3FE9DC006BDF4F /* CoreFoundation.framework in Frameworks */, + 812A64ED0D4AA082004CB7EB /* Security.framework in Frameworks */, + 81C964590DA2CBEF00257BC8 /* SystemConfiguration.framework in Frameworks */, + 81C9645E0DA2CC2D00257BC8 /* SystemConfiguration.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8125311F0D3FEA33006BDF4F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 817FFC5A0D613729004A8DD8 /* libipsec.A.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 81DDFDA10D622C1700C5CB87 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 81DDFDA20D622C1700C5CB87 /* libipsec.A.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 81DDFDC20D622C2700C5CB87 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 81DDFDD20D622C3500C5CB87 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 23D2D78C087071FC00C51098 = { isa = PBXGroup; children = ( + 72265DDB0F818F9300730A7D /* ipsec.plist */, + C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */, 25E5E82D0981A61900F2834C /* ipsec-tools */, 2589CB5409D8AE95002DC960 /* Libraries */, 25D3DB4C098998230025F703 /* Frameworks */, @@ -633,6 +996,11 @@ 254347B609DCB839007943DE /* test-policy */, 254347C509DCBA07007943DE /* test-pfkey */, 2537A1A809E4864800D0ECDA /* libipsec.A.dylib */, + 8125310A0D3FE9DC006BDF4F /* racoon */, + 812531290D3FEA33006BDF4F /* racoonctl */, + 81DDFDAA0D622C1700C5CB87 /* setkey */, + 81DDFDCD0D622C2700C5CB87 /* libipsec.A.dylib */, + 81DDFDD70D622C3500C5CB87 /* rsaparse.o */, ); name = Products; sourceTree = ""; @@ -640,6 +1008,8 @@ 2589CB5409D8AE95002DC960 /* Libraries */ = { isa = PBXGroup; children = ( + 8176A6B80D45661700BC5251 /* libldap.dylib */, + 8D5B16230E5F7E9300E72675 /* libresolv.dylib */, 25EAE87609D87A770042CC7F /* libiconv.dylib */, 25EAE87309D87A390042CC7F /* libpam.dylib */, 25EAE87109D87A160042CC7F /* libgssapi_krb5.dylib */, @@ -670,6 +1040,9 @@ 25D3DB4C098998230025F703 /* Frameworks */ = { isa = PBXGroup; children = ( + 81C964580DA2CBEF00257BC8 /* SystemConfiguration.framework */, + 81C9645D0DA2CC2D00257BC8 /* SystemConfiguration.framework */, + 812A64EC0D4AA082004CB7EB /* Security.framework */, 25EAE83109D875790042CC7F /* Security.framework */, 25EAE83709D875BF0042CC7F /* DirectoryService.framework */, 25EAE8C009D87B080042CC7F /* CoreFoundation.framework */, @@ -680,6 +1053,7 @@ 25D9497C09A6AA7600CA0F24 /* Common */ = { isa = PBXGroup; children = ( + BA5B6F350EC1A03C003774E7 /* ipsecMessageTracer.h */, 25F777ED09ABE58400C99783 /* pfkey_dump.c */, 25F777B909ABE3E100C99783 /* key_debug.c */, 25D9499F09A6AAD700CA0F24 /* config.h */, @@ -703,6 +1077,8 @@ 25F257FF0987FB0E00D15623 /* setkey */ = { isa = PBXGroup; children = ( + BA5B6F380EC1A03C003774E7 /* ipsecPolicyTracer.h */, + BA5B6F300EC19F80003774E7 /* ipsecPolicyTracer.c */, 254347C709DCBA1B007943DE /* test-pfkey.c */, 25F258840988648C00D15623 /* extern.h */, 25F258870988648C00D15623 /* parse.y */, @@ -719,12 +1095,19 @@ 25F258000987FB1600D15623 /* racoon */ = { isa = PBXGroup; children = ( + BA5B6F280EC19F40003774E7 /* ipsecConfigTracer.c */, + BA5B6F360EC1A03C003774E7 /* ipsecConfigTracer.h */, + BA5B6F290EC19F40003774E7 /* ipsecSessionTracer.c */, + BA5B6F370EC1A03C003774E7 /* ipsecSessionTracer.h */, + BA6F109A0EA1DEC200546773 /* ike_session.c */, + BA6F10940EA1D67700546773 /* ike_session.h */, 2589CBA809D8B727002DC960 /* prsa_par.y */, 2589CBAA09D8B727002DC960 /* prsa_tok.l */, 25F258AB0988657000D15623 /* admin_var.h */, 25F258AC0988657000D15623 /* admin.c */, 25F258AD0988657000D15623 /* admin.h */, 25F258AE0988657000D15623 /* algorithm.c */, + 81856B700D6B8BC5001DAE21 /* algorithm_types.h */, 25F258AF0988657000D15623 /* algorithm.h */, 25F258B00988657000D15623 /* arc4random.h */, 25F258B10988657000D15623 /* backupsa.c */, @@ -733,6 +1116,7 @@ 25F258B40988657000D15623 /* cfparse.y */, 25F258B50988657000D15623 /* cftoken_proto.h */, 25F258B60988657000D15623 /* cftoken.l */, + 724F99500E3672FD00C56897 /* com.apple.racoon.plist */, 25F258B70988657000D15623 /* crypto_cssm.c */, 25F258B80988657000D15623 /* crypto_cssm.h */, 25F258B90988657000D15623 /* crypto_openssl.c */, @@ -843,7 +1227,9 @@ 25DE2DE50A8BD40E0010A46D /* vpn_control_var.h */, 25DE2DE60A8BD40E0010A46D /* vpn_control.c */, 25DE2DE70A8BD40E0010A46D /* vpn_control.h */, - 25F2584E0988620300D15623 /* Sample */, + 81CA08910CE3BC870055C0AF /* vpn.c */, + BA5B6F4F0EC1A136003774E7 /* vpn.h */, + 818710380D5BE15400C7B441 /* Sample */, 25F2584D098861F500D15623 /* Documents */, 25F2584C098861ED00D15623 /* Crypto */, ); @@ -885,14 +1271,23 @@ path = Documents; sourceTree = ""; }; - 25F2584E0988620300D15623 /* Sample */ = { + 818710380D5BE15400C7B441 /* Sample */ = { isa = PBXGroup; children = ( - 25F25898098864D700D15623 /* anonymous.conf */, - 25F25899098864D700D15623 /* psk.txt */, - 25F2589A098864D700D15623 /* racoon.conf */, + 8187103C0D5BE1CF00C7B441 /* anonymous.conf */, + 8187103D0D5BE1CF00C7B441 /* psk.txt */, + 8187103B0D5BE1B400C7B441 /* racoon.conf */, + 818710390D5BE16600C7B441 /* Embedded */, ); - path = Sample; + name = Sample; + sourceTree = ""; + }; + 818710390D5BE16600C7B441 /* Embedded */ = { + isa = PBXGroup; + children = ( + 8187103A0D5BE18800C7B441 /* racoon.conf */, + ); + name = Embedded; sourceTree = ""; }; /* End PBXGroup section */ @@ -907,6 +1302,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 81DDFDB90D622C2700C5CB87 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 81DDFDBA0D622C2700C5CB87 /* config.h in Headers */, + 81DDFDBB0D622C2700C5CB87 /* ipsec_strerror.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -1022,8 +1426,8 @@ 25F258020987FBFA00D15623 /* Sources */, 25F258030987FBFA00D15623 /* Frameworks */, 258CF2E20A191AB000166B38 /* CopyFiles */, + 724A38A20E3676FB00F6B25F /* CopyFiles */, 258CF2F80A191B3900166B38 /* CopyFiles */, - 258CF2F90A191B3900166B38 /* CopyFiles */, 258CF2FA0A191B3900166B38 /* CopyFiles */, 258CF31B0A1941A200166B38 /* ShellScript */, ); @@ -1076,13 +1480,110 @@ productReference = 25F2580F0987FC3400D15623 /* racoonctl */; productType = "com.apple.product-type.tool"; }; + 812530BA0D3FE9DC006BDF4F /* racoon Embedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 812531050D3FE9DC006BDF4F /* Build configuration list for PBXNativeTarget "racoon Embedded" */; + buildPhases = ( + 812530BF0D3FE9DC006BDF4F /* Sources */, + 812530F40D3FE9DC006BDF4F /* Frameworks */, + 812530FB0D3FE9DC006BDF4F /* CopyFiles */, + 812530FD0D3FE9DC006BDF4F /* CopyFiles */, + 812530FF0D3FE9DC006BDF4F /* CopyFiles */, + 812531020D3FE9DC006BDF4F /* CopyFiles */, + 725F453B0E36A15C005BB55C /* CopyFiles */, + 812531040D3FE9DC006BDF4F /* ShellScript */, + 834072BB0EDCC5C400B6CCE8 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 81DDFDDF0D622D1700C5CB87 /* PBXTargetDependency */, + 81DDFDE10D622D2A00C5CB87 /* PBXTargetDependency */, + ); + name = "racoon Embedded"; + productName = racoon; + productReference = 8125310A0D3FE9DC006BDF4F /* racoon */; + productType = "com.apple.product-type.tool"; + }; + 812531120D3FEA33006BDF4F /* racoonctl Embedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 812531240D3FEA33006BDF4F /* Build configuration list for PBXNativeTarget "racoonctl Embedded" */; + buildPhases = ( + 812531150D3FEA33006BDF4F /* Sources */, + 8125311F0D3FEA33006BDF4F /* Frameworks */, + 812531210D3FEA33006BDF4F /* CopyFiles */, + 812531230D3FEA33006BDF4F /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "racoonctl Embedded"; + productName = racoonctl; + productReference = 812531290D3FEA33006BDF4F /* racoonctl */; + productType = "com.apple.product-type.tool"; + }; + 81DDFD970D622C1700C5CB87 /* setkey Embedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 81DDFDA60D622C1700C5CB87 /* Build configuration list for PBXNativeTarget "setkey Embedded" */; + buildPhases = ( + 81DDFD9A0D622C1700C5CB87 /* Sources */, + 81DDFDA10D622C1700C5CB87 /* Frameworks */, + 81DDFDA30D622C1700C5CB87 /* CopyFiles */, + 81DDFDA50D622C1700C5CB87 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 81DDFDE40D622D8C00C5CB87 /* PBXTargetDependency */, + ); + name = "setkey Embedded"; + productName = setkey; + productReference = 81DDFDAA0D622C1700C5CB87 /* setkey */; + productType = "com.apple.product-type.tool"; + }; + 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 81DDFDC90D622C2700C5CB87 /* Build configuration list for PBXNativeTarget "libipsec Embedded" */; + buildPhases = ( + 81DDFDB90D622C2700C5CB87 /* Headers */, + 81DDFDBC0D622C2700C5CB87 /* Sources */, + 81DDFDC20D622C2700C5CB87 /* Frameworks */, + 81DDFDC30D622C2700C5CB87 /* CopyFiles */, + 81DDFDC80D622C2700C5CB87 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libipsec Embedded"; + productName = libipsec; + productReference = 81DDFDCD0D622C2700C5CB87 /* libipsec.A.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; + 81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 81DDFDD30D622C3500C5CB87 /* Build configuration list for PBXNativeTarget "rsaparse Embedded" */; + buildPhases = ( + 81DDFDCF0D622C3500C5CB87 /* Sources */, + 81DDFDD20D622C3500C5CB87 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "rsaparse Embedded"; + productName = rsaparse; + productReference = 81DDFDD70D622C3500C5CB87 /* rsaparse.o */; + productType = "com.apple.product-type.objfile"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 23D2D790087071FC00C51098 /* Project object */ = { isa = PBXProject; buildConfigurationList = 25D3DACC098952B20025F703 /* Build configuration list for PBXProject "ipsec" */; - compatibilityVersion = "Xcode 2.4"; + compatibilityVersion = "Xcode 3.0"; hasScannedForEncodings = 0; mainGroup = 23D2D78C087071FC00C51098; productRefGroup = 23D2D79C087074CC00C51098 /* Products */; @@ -1099,6 +1600,12 @@ 254347B509DCB839007943DE /* test-policy */, 254347C409DCBA07007943DE /* test-pfkey */, 2537A1A709E4864800D0ECDA /* libipsec */, + 812530AA0D3FE994006BDF4F /* IPSec Embedded (Aggregate) */, + 812530BA0D3FE9DC006BDF4F /* racoon Embedded */, + 812531120D3FEA33006BDF4F /* racoonctl Embedded */, + 81DDFD970D622C1700C5CB87 /* setkey Embedded */, + 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */, + 81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */, ); }; /* End PBXProject section */ @@ -1169,38 +1676,90 @@ shellPath = /bin/sh; shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_set_policy.3\n/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_strerror.3\n/bin/ln -s libipsec.A.dylib $DSTROOT/usr/lib/libipsec.dylib\n"; }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 2537A1A509E4864800D0ECDA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; + 812531040D3FE9DC006BDF4F /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; files = ( - 2537A1B509E4867700D0ECDA /* ipsec_dump_policy.c in Sources */, - 2537A1B609E4867700D0ECDA /* ipsec_get_policylen.c in Sources */, - 2537A1B709E4867800D0ECDA /* ipsec_strerror.c in Sources */, - 2537A1B909E4867900D0ECDA /* policy_parse.y in Sources */, - 2537A1BA09E4867A00D0ECDA /* policy_token.l in Sources */, ); - runOnlyForDeploymentPostprocessing = 0; + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "/bin/chmod 600 $DSTROOT/private/etc/racoon/psk.txt\n/bin/chmod 644 $DSTROOT/private/etc/racoon/racoon.conf\n/bin/chmod 600 $DSTROOT/private/etc/racoon/remote/anonymous.conf\n/bin/chmod 444 $DSTROOT/usr/share/man/man5/racoon.conf.5\n/bin/chmod 444 $DSTROOT/usr/share/man/man8/racoon.8\n"; }; - 2543476C09DCB477007943DE /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; + 812531230D3FEA33006BDF4F /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; files = ( - 2543477109DCB492007943DE /* plainrsa-gen.c in Sources */, - 2543478A09DCB49C007943DE /* plog.c in Sources */, - 2543478C09DCB4A6007943DE /* logger.c in Sources */, - 25BE7E7F09E5DE4C009B6B84 /* pfkey_dump.c in Sources */, - 25BE7E8809E5E499009B6B84 /* pfkey.c in Sources */, - 25BE7E8A09E5E4A6009B6B84 /* key_debug.c in Sources */, - 25BE7E8E09E5E5BE009B6B84 /* crypto_openssl.c in Sources */, - 25BE7E9009E5E61F009B6B84 /* misc.c in Sources */, - 25BE7E9209E5E635009B6B84 /* vmbuf.c in Sources */, ); - runOnlyForDeploymentPostprocessing = 0; + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man8/racoonctl.8"; }; - 2543479009DCB57E007943DE /* Sources */ = { + 81DDFDA50D622C1700C5CB87 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man8/setkey.8"; + }; + 81DDFDC80D622C2700C5CB87 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_set_policy.3\n/bin/chmod 444 $DSTROOT/usr/share/man/man3/ipsec_strerror.3\n/bin/ln -s libipsec.A.dylib $DSTROOT/usr/lib/libipsec.dylib\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2537A1A509E4864800D0ECDA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2537A1B509E4867700D0ECDA /* ipsec_dump_policy.c in Sources */, + 2537A1B609E4867700D0ECDA /* ipsec_get_policylen.c in Sources */, + 2537A1B709E4867800D0ECDA /* ipsec_strerror.c in Sources */, + 2537A1B909E4867900D0ECDA /* policy_parse.y in Sources */, + 2537A1BA09E4867A00D0ECDA /* policy_token.l in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2543476C09DCB477007943DE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2543477109DCB492007943DE /* plainrsa-gen.c in Sources */, + 2543478A09DCB49C007943DE /* plog.c in Sources */, + 2543478C09DCB4A6007943DE /* logger.c in Sources */, + 25BE7E7F09E5DE4C009B6B84 /* pfkey_dump.c in Sources */, + 25BE7E8809E5E499009B6B84 /* pfkey.c in Sources */, + 25BE7E8A09E5E4A6009B6B84 /* key_debug.c in Sources */, + 25BE7E8E09E5E5BE009B6B84 /* crypto_openssl.c in Sources */, + 25BE7E9009E5E61F009B6B84 /* misc.c in Sources */, + 25BE7E9209E5E635009B6B84 /* vmbuf.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2543479009DCB57E007943DE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -1254,7 +1813,7 @@ 25F2592A0988657000D15623 /* backupsa.c in Sources */, 25F2592B0988657000D15623 /* cfparse.y in Sources */, 25F2592C0988657000D15623 /* cftoken.l in Sources */, - 25F2592D0988657000D15623 /* crypto_cssm.c in Sources */, + 81C386AA0D451EC300975D5E /* crypto_cssm.c in Sources */, 25F2592E0988657000D15623 /* crypto_openssl.c in Sources */, 25F2592F0988657000D15623 /* dnssec.c in Sources */, 25F259310988657000D15623 /* evt.c in Sources */, @@ -1276,7 +1835,7 @@ 25F259460988657000D15623 /* main.c in Sources */, 25F259470988657000D15623 /* misc.c in Sources */, 25F259490988657000D15623 /* oakley.c in Sources */, - 25F2594A0988657000D15623 /* open_dir.c in Sources */, + 81C387EC0D45268300975D5E /* open_dir.c in Sources */, 25F2594C0988657000D15623 /* pfkey_racoon.c in Sources */, 25F2594F0988657000D15623 /* plog.c in Sources */, 25F259500988657000D15623 /* policy.c in Sources */, @@ -1300,6 +1859,10 @@ 25DC9ED509DB16F800C89F86 /* isakmp_unity.c in Sources */, 25DC9ED609DB16FA00C89F86 /* isakmp_xauth.c in Sources */, 25DE2DE90A8BD40E0010A46D /* vpn_control.c in Sources */, + 81CA08920CE3BC870055C0AF /* vpn.c in Sources */, + BA6F109B0EA1DEC200546773 /* ike_session.c in Sources */, + BA5B6F2A0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */, + BA5B6F2B0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1313,6 +1876,7 @@ 25ECCDA209AD479A00883CA3 /* pfkey.c in Sources */, 25F258910988648C00D15623 /* setkey.c in Sources */, 25F258940988648C00D15623 /* token.l in Sources */, + BA5B6F310EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1332,6 +1896,120 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 812530BF0D3FE9DC006BDF4F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 812530C00D3FE9DC006BDF4F /* rijndael-alg-fst.c in Sources */, + 812530C10D3FE9DC006BDF4F /* rijndael-api-fst.c in Sources */, + 812530C20D3FE9DC006BDF4F /* admin.c in Sources */, + 812530C30D3FE9DC006BDF4F /* algorithm.c in Sources */, + 812530C40D3FE9DC006BDF4F /* backupsa.c in Sources */, + 812530C50D3FE9DC006BDF4F /* cfparse.y in Sources */, + 812530C60D3FE9DC006BDF4F /* cftoken.l in Sources */, + 81C325A80D46A36900E65EB7 /* crypto_cssm.c in Sources */, + 812530C70D3FE9DC006BDF4F /* crypto_openssl.c in Sources */, + 812530C80D3FE9DC006BDF4F /* dnssec.c in Sources */, + 812530C90D3FE9DC006BDF4F /* evt.c in Sources */, + 812530CA0D3FE9DC006BDF4F /* genlist.c in Sources */, + 812530CB0D3FE9DC006BDF4F /* getcertsbyname.c in Sources */, + 812530CC0D3FE9DC006BDF4F /* grabmyaddr.c in Sources */, + 812530CD0D3FE9DC006BDF4F /* gssapi.c in Sources */, + 812530CE0D3FE9DC006BDF4F /* handler.c in Sources */, + 812530CF0D3FE9DC006BDF4F /* ipsec_doi.c in Sources */, + 812530D00D3FE9DC006BDF4F /* isakmp_agg.c in Sources */, + 812530D10D3FE9DC006BDF4F /* isakmp_base.c in Sources */, + 812530D20D3FE9DC006BDF4F /* isakmp_ident.c in Sources */, + 812530D30D3FE9DC006BDF4F /* isakmp_inf.c in Sources */, + 812530D40D3FE9DC006BDF4F /* isakmp_newg.c in Sources */, + 812530D50D3FE9DC006BDF4F /* isakmp_quick.c in Sources */, + 812530D60D3FE9DC006BDF4F /* isakmp.c in Sources */, + 812530D70D3FE9DC006BDF4F /* localconf.c in Sources */, + 812530D80D3FE9DC006BDF4F /* logger.c in Sources */, + 812530D90D3FE9DC006BDF4F /* main.c in Sources */, + 812530DA0D3FE9DC006BDF4F /* misc.c in Sources */, + 812530DB0D3FE9DC006BDF4F /* oakley.c in Sources */, + 812530DC0D3FE9DC006BDF4F /* pfkey_racoon.c in Sources */, + 812530DD0D3FE9DC006BDF4F /* plog.c in Sources */, + 812530DE0D3FE9DC006BDF4F /* policy.c in Sources */, + 812530DF0D3FE9DC006BDF4F /* privsep.c in Sources */, + 812530E00D3FE9DC006BDF4F /* proposal.c in Sources */, + 812530E10D3FE9DC006BDF4F /* remoteconf.c in Sources */, + 812530E20D3FE9DC006BDF4F /* safefile.c in Sources */, + 812530E30D3FE9DC006BDF4F /* sainfo.c in Sources */, + 812530E40D3FE9DC006BDF4F /* schedule.c in Sources */, + 812530E50D3FE9DC006BDF4F /* session.c in Sources */, + 812530E60D3FE9DC006BDF4F /* sockmisc.c in Sources */, + 812530E70D3FE9DC006BDF4F /* str2val.c in Sources */, + 812530E80D3FE9DC006BDF4F /* strnames.c in Sources */, + 812530E90D3FE9DC006BDF4F /* throttle.c in Sources */, + 812530EA0D3FE9DC006BDF4F /* vendorid.c in Sources */, + 812530EB0D3FE9DC006BDF4F /* vmbuf.c in Sources */, + 812530EC0D3FE9DC006BDF4F /* nattraversal.c in Sources */, + 812530ED0D3FE9DC006BDF4F /* pfkey.c in Sources */, + 812530EE0D3FE9DC006BDF4F /* rsalist.c in Sources */, + 812530EF0D3FE9DC006BDF4F /* isakmp_cfg.c in Sources */, + 812530F00D3FE9DC006BDF4F /* isakmp_unity.c in Sources */, + 812530F10D3FE9DC006BDF4F /* isakmp_xauth.c in Sources */, + 812530F20D3FE9DC006BDF4F /* vpn_control.c in Sources */, + 812530F30D3FE9DC006BDF4F /* vpn.c in Sources */, + BA6F109C0EA1DEC200546773 /* ike_session.c in Sources */, + BA5B6F2C0EC19F40003774E7 /* ipsecConfigTracer.c in Sources */, + BA5B6F2D0EC19F40003774E7 /* ipsecSessionTracer.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 812531150D3FEA33006BDF4F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 812531160D3FEA33006BDF4F /* racoonctl.c in Sources */, + 812531170D3FEA33006BDF4F /* str2val.c in Sources */, + 812531180D3FEA33006BDF4F /* kmpstat.c in Sources */, + 812531190D3FEA33006BDF4F /* vmbuf.c in Sources */, + 8125311A0D3FEA33006BDF4F /* sockmisc.c in Sources */, + 8125311B0D3FEA33006BDF4F /* misc.c in Sources */, + 8125311C0D3FEA33006BDF4F /* pfkey_dump.c in Sources */, + 8125311D0D3FEA33006BDF4F /* key_debug.c in Sources */, + 8125311E0D3FEA33006BDF4F /* pfkey.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 81DDFD9A0D622C1700C5CB87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81DDFD9B0D622C1700C5CB87 /* parse.y in Sources */, + 81DDFD9C0D622C1700C5CB87 /* pfkey_dump.c in Sources */, + 81DDFD9D0D622C1700C5CB87 /* key_debug.c in Sources */, + 81DDFD9E0D622C1700C5CB87 /* pfkey.c in Sources */, + 81DDFD9F0D622C1700C5CB87 /* setkey.c in Sources */, + 81DDFDA00D622C1700C5CB87 /* token.l in Sources */, + BA5B6F320EC19F80003774E7 /* ipsecPolicyTracer.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 81DDFDBC0D622C2700C5CB87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81DDFDBD0D622C2700C5CB87 /* ipsec_dump_policy.c in Sources */, + 81DDFDBE0D622C2700C5CB87 /* ipsec_get_policylen.c in Sources */, + 81DDFDBF0D622C2700C5CB87 /* ipsec_strerror.c in Sources */, + 81DDFDC00D622C2700C5CB87 /* policy_parse.y in Sources */, + 81DDFDC10D622C2700C5CB87 /* policy_token.l in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 81DDFDCF0D622C3500C5CB87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81DDFDD00D622C3500C5CB87 /* prsa_par.y in Sources */, + 81DDFDD10D622C3500C5CB87 /* prsa_tok.l in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -1400,6 +2078,46 @@ target = 25E08C9909D9E64A001A11CF /* rsaparse */; targetProxy = 25E08CE909D9F0A2001A11CF /* PBXContainerItemProxy */; }; + 812531110D3FEA28006BDF4F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 812530BA0D3FE9DC006BDF4F /* racoon Embedded */; + targetProxy = 812531100D3FEA28006BDF4F /* PBXContainerItemProxy */; + }; + 8125312C0D3FEA44006BDF4F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 812531120D3FEA33006BDF4F /* racoonctl Embedded */; + targetProxy = 8125312B0D3FEA44006BDF4F /* PBXContainerItemProxy */; + }; + 81DDFDD90D622C4E00C5CB87 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */; + targetProxy = 81DDFDD80D622C4E00C5CB87 /* PBXContainerItemProxy */; + }; + 81DDFDDB0D622C5100C5CB87 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */; + targetProxy = 81DDFDDA0D622C5100C5CB87 /* PBXContainerItemProxy */; + }; + 81DDFDDF0D622D1700C5CB87 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */; + targetProxy = 81DDFDDE0D622D1700C5CB87 /* PBXContainerItemProxy */; + }; + 81DDFDE10D622D2A00C5CB87 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 81DDFDCE0D622C3500C5CB87 /* rsaparse Embedded */; + targetProxy = 81DDFDE00D622D2A00C5CB87 /* PBXContainerItemProxy */; + }; + 81DDFDE40D622D8C00C5CB87 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 81DDFDB80D622C2700C5CB87 /* libipsec Embedded */; + targetProxy = 81DDFDE30D622D8C00C5CB87 /* PBXContainerItemProxy */; + }; + 81DDFDF10D627DE300C5CB87 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 81DDFD970D622C1700C5CB87 /* setkey Embedded */; + targetProxy = 81DDFDF00D627DE300C5CB87 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -1463,7 +2181,7 @@ DYLIB_CURRENT_VERSION = 300; EXECUTABLE_PREFIX = lib; GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1", @@ -1493,6 +2211,7 @@ ALTERNATE_MODE = ""; ALTERNATE_OWNER = "$(inherited)"; ARCHS = ( + armv6, i386, ppc, ppc64, @@ -1519,7 +2238,7 @@ LEXFLAGS = "$(LEXFLAGS) -P__libipsec"; PREBINDING = NO; PRODUCT_NAME = ipsec.A; - VALID_ARCHS = "ppc64 i386 x86_64 ppc"; + VALID_ARCHS = "armv6 ppc64 i386 x86_64 ppc"; YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec"; ZERO_LINK = YES; }; @@ -1533,7 +2252,7 @@ i386, ); COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; + GCC_DYNAMIC_NO_PIC = YES; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; @@ -1549,7 +2268,7 @@ PREBINDING = NO; PRODUCT_NAME = "plainrsa-gen"; SKIP_INSTALL = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Development; @@ -1563,7 +2282,7 @@ ); COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1", @@ -1572,11 +2291,11 @@ INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 555; INSTALL_OWNER = root; - INSTALL_PATH = /use/sbin; + INSTALL_PATH = /usr/sbin; PREBINDING = NO; PRODUCT_NAME = "plainrsa-gen"; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Deployment; @@ -1601,7 +2320,7 @@ PREBINDING = NO; PRODUCT_NAME = "plainrsa-gen"; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Default; @@ -1631,7 +2350,7 @@ PREBINDING = NO; PRODUCT_NAME = eaytest; SKIP_INSTALL = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Development; @@ -1660,7 +2379,7 @@ PRODUCT_NAME = eaytest; SKIP_INSTALL = YES; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Deployment; @@ -1688,7 +2407,7 @@ PRODUCT_NAME = eaytest; SKIP_INSTALL = YES; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Default; @@ -1715,7 +2434,7 @@ PREBINDING = NO; PRODUCT_NAME = "test-policy"; SKIP_INSTALL = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Development; @@ -1741,7 +2460,7 @@ PRODUCT_NAME = "test-policy"; SKIP_INSTALL = YES; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Deployment; @@ -1765,7 +2484,7 @@ PRODUCT_NAME = "test-policy"; SKIP_INSTALL = YES; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Default; @@ -1789,7 +2508,7 @@ PREBINDING = NO; PRODUCT_NAME = "test-pfkey"; SKIP_INSTALL = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Development; @@ -1812,7 +2531,7 @@ PRODUCT_NAME = "test-pfkey"; SKIP_INSTALL = YES; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Deployment; @@ -1833,7 +2552,7 @@ PRODUCT_NAME = "test-pfkey"; SKIP_INSTALL = YES; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; ZERO_LINK = NO; }; name = Default; @@ -1847,6 +2566,8 @@ OTHER_REZFLAGS = ""; PRODUCT_NAME = "IPSec (Aggregate)"; SECTORDER_FLAGS = ""; + SKIP_INSTALL = NO; + VALID_ARCHS = "ppc64 ppc7400 ppc970 i386 x86_64 ppc"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -1858,12 +2579,13 @@ 25D3DABA098952B20025F703 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = "IPSec (Aggregate)"; SECTORDER_FLAGS = ""; + SKIP_INSTALL = NO; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -1875,11 +2597,13 @@ 25D3DABB098952B20025F703 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { + COPY_PHASE_STRIP = NO; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = "IPSec (Aggregate)"; SECTORDER_FLAGS = ""; + SKIP_INSTALL = NO; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -1924,7 +2648,7 @@ "$(OTHER_CFLAGS_QUOTED_3)", ); OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\""; - OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\""; OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ""; @@ -1933,7 +2657,7 @@ PRODUCT_NAME = racoon; SECTORDER_FLAGS = ""; SKIP_INSTALL = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -1956,7 +2680,7 @@ ); COPY_PHASE_STRIP = NO; DSTROOT = "/tmp/$(PROJECT_NAME).dst"; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ""; @@ -1979,7 +2703,7 @@ "$(OTHER_CFLAGS_QUOTED_3)", ); OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\""; - OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\""; OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ""; @@ -1987,7 +2711,7 @@ PREBINDING = NO; PRODUCT_NAME = racoon; SECTORDER_FLAGS = ""; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2009,7 +2733,7 @@ ); COPY_PHASE_STRIP = NO; DSTROOT = "/tmp/$(PROJECT_NAME).dst"; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ""; @@ -2032,7 +2756,7 @@ "$(OTHER_CFLAGS_QUOTED_3)", ); OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\""; - OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\""; OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ""; @@ -2040,7 +2764,7 @@ PREBINDING = NO; PRODUCT_NAME = racoon; SECTORDER_FLAGS = ""; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2058,7 +2782,7 @@ i386, ); COPY_PHASE_STRIP = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1", @@ -2082,7 +2806,7 @@ PRODUCT_NAME = setkey; SECTORDER_FLAGS = ""; SKIP_INSTALL = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "armv6 i386 ppc x86_64"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2100,7 +2824,7 @@ i386, ); COPY_PHASE_STRIP = YES; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1", @@ -2125,7 +2849,7 @@ SECTORDER_FLAGS = ""; SKIP_INSTALL = NO; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "armv6 i386 ppc x86_64"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2138,10 +2862,11 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = ( - ppc, i386, + ppc, + armv6, ); - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1", @@ -2165,7 +2890,7 @@ PRODUCT_NAME = setkey; SECTORDER_FLAGS = ""; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "armv6 i386 ppc x86_64"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2199,14 +2924,14 @@ INSTALL_MODE_FLAG = 555; INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; - OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/var/run\\\""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = racoonctl; SECTORDER_FLAGS = ""; SKIP_INSTALL = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2226,7 +2951,7 @@ i386, ); COPY_PHASE_STRIP = YES; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1", @@ -2240,14 +2965,14 @@ INSTALL_MODE_FLAG = 555; INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; - OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/var/run\\\""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = racoonctl; SECTORDER_FLAGS = ""; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2266,7 +2991,7 @@ ppc, i386, ); - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1", @@ -2280,14 +3005,14 @@ INSTALL_MODE_FLAG = 555; INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; - OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/var/run\\\""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = racoonctl; SECTORDER_FLAGS = ""; STRIP_INSTALLED_PRODUCT = YES; - VALID_ARCHS = "i386 ppc"; + VALID_ARCHS = "x86_64 i386 ppc"; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -2299,8 +3024,13 @@ 25D3DACD098952B20025F703 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { + ADDITIONAL_SDKS = ""; ARCHS = ( + armv6, i386, + ppc64, + arm, + x86_64, ppc, ); }; @@ -2309,8 +3039,13 @@ 25D3DACE098952B20025F703 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { + ADDITIONAL_SDKS = ""; ARCHS = ( + armv6, i386, + ppc64, + arm, + x86_64, ppc, ); }; @@ -2319,8 +3054,13 @@ 25D3DACF098952B20025F703 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { + ADDITIONAL_SDKS = ""; ARCHS = ( + armv6, i386, + ppc64, + arm, + x86_64, ppc, ); }; @@ -2342,7 +3082,8 @@ LEXFLAGS = "$(LEXFLAGS) -Pprsa"; PREBINDING = NO; PRODUCT_NAME = rsaparse; - VALID_ARCHS = "i386 ppc"; + SKIP_INSTALL = NO; + VALID_ARCHS = "i386 ppc x86_64 armv6"; YACCFLAGS = "$(YACCFLAGS) -pprsa"; }; name = Development; @@ -2362,7 +3103,8 @@ LEXFLAGS = "$(LEXFLAGS) -Pprsa"; PREBINDING = NO; PRODUCT_NAME = rsaparse; - VALID_ARCHS = "i386 ppc"; + SKIP_INSTALL = NO; + VALID_ARCHS = "i386 ppc x86_64 armv6"; YACCFLAGS = "$(YACCFLAGS) -pprsa"; ZERO_LINK = NO; }; @@ -2372,8 +3114,9 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = ( - ppc, i386, + ppc, + armv6, ); COPY_PHASE_STRIP = NO; GCC_MODEL_TUNING = G5; @@ -2381,93 +3124,699 @@ LEXFLAGS = "$(LEXFLAGS) -Pprsa"; PREBINDING = NO; PRODUCT_NAME = rsaparse; - VALID_ARCHS = "i386 ppc"; + SKIP_INSTALL = NO; + VALID_ARCHS = "i386 ppc x86_64 armv6"; YACCFLAGS = "$(YACCFLAGS) -pprsa"; }; name = Default; }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2537A1A909E4866800D0ECDA /* Build configuration list for PBXNativeTarget "libipsec" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2537A1AA09E4866800D0ECDA /* Development */, - 2537A1AB09E4866800D0ECDA /* Deployment */, - 2537A1AC09E4866800D0ECDA /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 2543478609DCB494007943DE /* Build configuration list for PBXNativeTarget "plainrsa-gen" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2543478709DCB494007943DE /* Development */, - 2543478809DCB494007943DE /* Deployment */, - 2543478909DCB494007943DE /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 2543479909DCB596007943DE /* Build configuration list for PBXNativeTarget "eaytest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2543479A09DCB596007943DE /* Development */, - 2543479B09DCB596007943DE /* Deployment */, - 2543479C09DCB596007943DE /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 254347BD09DCB851007943DE /* Build configuration list for PBXNativeTarget "test-policy" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 254347BE09DCB851007943DE /* Development */, - 254347BF09DCB851007943DE /* Deployment */, - 254347C009DCB851007943DE /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 254347C909DCBA1B007943DE /* Build configuration list for PBXNativeTarget "test-pfkey" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 254347CA09DCBA1B007943DE /* Development */, - 254347CB09DCBA1B007943DE /* Deployment */, - 254347CC09DCBA1B007943DE /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + 812530B60D3FE994006BDF4F /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ADDITIONAL_SDKS = ""; + COPY_PHASE_STRIP = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "IPSec Embedded (Aggregate)"; + SECTORDER_FLAGS = ""; + SKIP_INSTALL = NO; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Development; }; - 25D3DAB8098952B20025F703 /* Build configuration list for PBXAggregateTarget "IPSec (Aggregate)" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 25D3DAB9098952B20025F703 /* Development */, - 25D3DABA098952B20025F703 /* Deployment */, - 25D3DABB098952B20025F703 /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + 812530B70D3FE994006BDF4F /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ADDITIONAL_SDKS = ""; + COPY_PHASE_STRIP = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "IPSec Embedded (Aggregate)"; + SECTORDER_FLAGS = ""; + SKIP_INSTALL = NO; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Deployment; }; - 25D3DABC098952B20025F703 /* Build configuration list for PBXNativeTarget "racoon" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 25D3DABD098952B20025F703 /* Development */, - 25D3DABE098952B20025F703 /* Deployment */, - 25D3DABF098952B20025F703 /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + 812530B90D3FE994006BDF4F /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ADDITIONAL_SDKS = ""; + COPY_PHASE_STRIP = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = "IPSec Embedded (Aggregate)"; + SECTORDER_FLAGS = ""; + SKIP_INSTALL = NO; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; }; - 25D3DAC0098952B20025F703 /* Build configuration list for PBXNativeTarget "setkey" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 25D3DAC1098952B20025F703 /* Development */, - 25D3DAC2098952B20025F703 /* Deployment */, - 25D3DAC3098952B20025F703 /* Default */, + 812531060D3FE9DC006BDF4F /* Development */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = "$(inherited)"; + ALTERNATE_OWNER = "$(inherited)"; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/entitlements.plist"; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SDKROOT)/System/Library/Frameworks\\\"", + "\\\"$(DEVELOPER_DIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks\\\"", + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + ../Common, + Crypto, + /tmp/ipsec.dst/usr/include, + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + LEXFLAGS = ""; + OTHER_CFLAGS = ( + "$(OTHER_CFLAGS_QUOTED_1)", + "$(OTHER_CFLAGS_QUOTED_2)", + "$(OTHER_CFLAGS_QUOTED_3)", + ); + OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\""; + OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-lcrypto"; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = racoon; + SECTORDER_FLAGS = ""; + SKIP_INSTALL = YES; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + YACCFLAGS = "$(YACCFLAGS) -d"; + YACC_GENERATE_DEBUGGING_DIRECTIVES = NO; + }; + name = Development; + }; + 812531070D3FE9DC006BDF4F /* Deployment */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = "$(inherited)"; + ALTERNATE_OWNER = "$(inherited)"; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/entitlements.plist"; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DSTROOT = "/tmp/$(PROJECT_NAME).dst"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SDKROOT)/System/Library/Frameworks\\\"", + "\\\"$(DEVELOPER_DIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks\\\"", + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + ../Common, + Crypto, + /tmp/ipsec.dst/usr/include, + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + OTHER_CFLAGS = ( + "$(OTHER_CFLAGS_QUOTED_1)", + "$(OTHER_CFLAGS_QUOTED_2)", + "$(OTHER_CFLAGS_QUOTED_3)", + ); + OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\""; + OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-lcrypto"; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = racoon; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + YACCFLAGS = "$(YACCFLAGS) -d"; + }; + name = Deployment; + }; + 812531090D3FE9DC006BDF4F /* Default */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = "$(inherited)"; + ALTERNATE_OWNER = "$(inherited)"; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/entitlements.plist"; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DSTROOT = "/tmp/$(PROJECT_NAME).dst"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SDKROOT)/System/Library/Frameworks\\\"", + "\\\"$(DEVELOPER_DIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.Internal.sdk/System/Library/Frameworks\\\"", + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + ../Common, + Crypto, + /tmp/ipsec.dst/usr/include, + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + OTHER_CFLAGS = ( + "$(OTHER_CFLAGS_QUOTED_1)", + "$(OTHER_CFLAGS_QUOTED_2)", + "$(OTHER_CFLAGS_QUOTED_3)", + ); + OTHER_CFLAGS_QUOTED_1 = "-DSYSCONFDIR=\\\"/etc/racoon\\\""; + OTHER_CFLAGS_QUOTED_2 = "-DADMINPORTDIR=\\\"/var/run\\\""; + OTHER_CFLAGS_QUOTED_3 = "-DPATHRACOON=\\\"/usr/sbin/racoon\\\""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-lcrypto"; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = racoon; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + YACCFLAGS = "$(YACCFLAGS) -d"; + }; + name = Default; + }; + 812531250D3FEA33006BDF4F /* Development */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = "$(inherited)"; + ALTERNATE_OWNER = "$(inherited)"; + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + "$(DSTROOT)/usr/include", + "$(inherited)", + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/tmp/racoon\\\""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = racoonctl; + SECTORDER_FLAGS = ""; + SKIP_INSTALL = YES; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Development; + }; + 812531260D3FEA33006BDF4F /* Deployment */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = "$(inherited)"; + ALTERNATE_OWNER = "$(inherited)"; + COPY_PHASE_STRIP = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + "$(DSTROOT)/usr/include", + "$(inherited)", + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/tmp/racoon\\\""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = racoonctl; + SECTORDER_FLAGS = ""; + STRIP_INSTALLED_PRODUCT = YES; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Deployment; + }; + 812531280D3FEA33006BDF4F /* Default */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = "$(inherited)"; + ALTERNATE_OWNER = "$(inherited)"; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + "$(DSTROOT)/usr/include", + "$(inherited)", + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + OTHER_CFLAGS = "-DADMINPORTDIR=\\\"/tmp/racoon\\\""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = racoonctl; + SECTORDER_FLAGS = ""; + STRIP_INSTALLED_PRODUCT = YES; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 81DDFDA70D622C1700C5CB87 /* Development */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + "$(DSTROOT)/usr/include", + ../Common, + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + LIBRARY_SEARCH_PATHS = ""; + MACH_O_TYPE = mh_execute; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRELINK_LIBS = ""; + PRODUCT_NAME = setkey; + SECTORDER_FLAGS = ""; + SKIP_INSTALL = YES; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + YACCFLAGS = ""; + }; + name = Development; + }; + 81DDFDA80D622C1700C5CB87 /* Deployment */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + "$(DSTROOT)/usr/include", + ../Common, + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + LIBRARY_SEARCH_PATHS = ""; + MACH_O_TYPE = mh_execute; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRELINK_LIBS = ""; + PRODUCT_NAME = setkey; + SECTORDER_FLAGS = ""; + SKIP_INSTALL = NO; + STRIP_INSTALLED_PRODUCT = YES; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Deployment; + }; + 81DDFDA90D622C1700C5CB87 /* Default */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1\nHAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + "$(DSTROOT)/usr/include", + ../Common, + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/sbin; + LIBRARY_SEARCH_PATHS = ""; + MACH_O_TYPE = mh_execute; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRELINK_LIBS = ""; + PRODUCT_NAME = setkey; + SECTORDER_FLAGS = ""; + STRIP_INSTALLED_PRODUCT = YES; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 81DDFDCA0D622C2700C5CB87 /* Development */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = ""; + ALTERNATE_OWNER = "$(inherited)"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)"; + DYLIB_CURRENT_VERSION = 300; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + ../Common, + "$(HEADER_SEARCH_PATHS)", + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/lib; + LEXFLAGS = "$(LEXFLAGS) -P__libipsec"; + PREBINDING = NO; + PRODUCT_NAME = ipsec.A; + SKIP_INSTALL = YES; + YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec"; + ZERO_LINK = YES; + }; + name = Development; + }; + 81DDFDCB0D622C2700C5CB87 /* Deployment */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = ""; + ALTERNATE_OWNER = "$(inherited)"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)"; + DYLIB_CURRENT_VERSION = 300; + EXECUTABLE_PREFIX = lib; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + ../Common, + "$(HEADER_SEARCH_PATHS)", + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/lib; + LEXFLAGS = "$(LEXFLAGS) -P__libipsec"; + PREBINDING = NO; + PRODUCT_NAME = ipsec.A; + YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec"; + ZERO_LINK = YES; + }; + name = Deployment; + }; + 81DDFDCC0D622C2700C5CB87 /* Default */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + ALTERNATE_GROUP = "$(inherited)"; + ALTERNATE_MODE = ""; + ALTERNATE_OWNER = "$(inherited)"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)"; + DYLIB_CURRENT_VERSION = 300; + EXECUTABLE_PREFIX = lib; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + "HAVE_CONFIG_H=1", + "$(GCC_PREPROCESSOR_DEFINITIONS)", + ); + HEADER_SEARCH_PATHS = ( + ../Common, + "$(HEADER_SEARCH_PATHS)", + ); + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 555; + INSTALL_OWNER = root; + INSTALL_PATH = /usr/lib; + LEXFLAGS = "$(LEXFLAGS) -P__libipsec"; + PREBINDING = NO; + PRODUCT_NAME = ipsec.A; + YACCFLAGS = "$(YACCFLAGS) -d -p__libipsec"; + ZERO_LINK = YES; + }; + name = Default; + }; + 81DDFDD40D622C3500C5CB87 /* Development */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = ""; + LEXFLAGS = "$(LEXFLAGS) -Pprsa"; + PREBINDING = NO; + PRODUCT_NAME = rsaparse; + SKIP_INSTALL = NO; + YACCFLAGS = "$(YACCFLAGS) -pprsa"; + }; + name = Development; + }; + 81DDFDD50D622C3500C5CB87 /* Deployment */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = ""; + LEXFLAGS = "$(LEXFLAGS) -Pprsa"; + PREBINDING = NO; + PRODUCT_NAME = rsaparse; + SKIP_INSTALL = NO; + YACCFLAGS = "$(YACCFLAGS) -pprsa"; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 81DDFDD60D622C3500C5CB87 /* Default */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C172BD980E6369BE0030F8EB /* AspenSDK.xcconfig */; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = ""; + LEXFLAGS = "$(LEXFLAGS) -Pprsa"; + PREBINDING = NO; + PRODUCT_NAME = rsaparse; + SKIP_INSTALL = NO; + YACCFLAGS = "$(YACCFLAGS) -pprsa"; + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2537A1A909E4866800D0ECDA /* Build configuration list for PBXNativeTarget "libipsec" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2537A1AA09E4866800D0ECDA /* Development */, + 2537A1AB09E4866800D0ECDA /* Deployment */, + 2537A1AC09E4866800D0ECDA /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 2543478609DCB494007943DE /* Build configuration list for PBXNativeTarget "plainrsa-gen" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2543478709DCB494007943DE /* Development */, + 2543478809DCB494007943DE /* Deployment */, + 2543478909DCB494007943DE /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 2543479909DCB596007943DE /* Build configuration list for PBXNativeTarget "eaytest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2543479A09DCB596007943DE /* Development */, + 2543479B09DCB596007943DE /* Deployment */, + 2543479C09DCB596007943DE /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 254347BD09DCB851007943DE /* Build configuration list for PBXNativeTarget "test-policy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 254347BE09DCB851007943DE /* Development */, + 254347BF09DCB851007943DE /* Deployment */, + 254347C009DCB851007943DE /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 254347C909DCBA1B007943DE /* Build configuration list for PBXNativeTarget "test-pfkey" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 254347CA09DCBA1B007943DE /* Development */, + 254347CB09DCBA1B007943DE /* Deployment */, + 254347CC09DCBA1B007943DE /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 25D3DAB8098952B20025F703 /* Build configuration list for PBXAggregateTarget "IPSec (Aggregate)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 25D3DAB9098952B20025F703 /* Development */, + 25D3DABA098952B20025F703 /* Deployment */, + 25D3DABB098952B20025F703 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 25D3DABC098952B20025F703 /* Build configuration list for PBXNativeTarget "racoon" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 25D3DABD098952B20025F703 /* Development */, + 25D3DABE098952B20025F703 /* Deployment */, + 25D3DABF098952B20025F703 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 25D3DAC0098952B20025F703 /* Build configuration list for PBXNativeTarget "setkey" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 25D3DAC1098952B20025F703 /* Development */, + 25D3DAC2098952B20025F703 /* Deployment */, + 25D3DAC3098952B20025F703 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Deployment; }; 25D3DAC4098952B20025F703 /* Build configuration list for PBXNativeTarget "racoonctl" */ = { isa = XCConfigurationList; @@ -2477,7 +3826,7 @@ 25D3DAC7098952B20025F703 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Deployment; }; 25D3DACC098952B20025F703 /* Build configuration list for PBXProject "ipsec" */ = { isa = XCConfigurationList; @@ -2487,7 +3836,7 @@ 25D3DACF098952B20025F703 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Deployment; }; 25E08CA209D9E6A4001A11CF /* Build configuration list for PBXNativeTarget "rsaparse" */ = { isa = XCConfigurationList; @@ -2497,7 +3846,67 @@ 25E08CA509D9E6A4001A11CF /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Deployment; + }; + 812530B50D3FE994006BDF4F /* Build configuration list for PBXAggregateTarget "IPSec Embedded (Aggregate)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 812530B60D3FE994006BDF4F /* Development */, + 812530B70D3FE994006BDF4F /* Deployment */, + 812530B90D3FE994006BDF4F /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 812531050D3FE9DC006BDF4F /* Build configuration list for PBXNativeTarget "racoon Embedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 812531060D3FE9DC006BDF4F /* Development */, + 812531070D3FE9DC006BDF4F /* Deployment */, + 812531090D3FE9DC006BDF4F /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 812531240D3FEA33006BDF4F /* Build configuration list for PBXNativeTarget "racoonctl Embedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 812531250D3FEA33006BDF4F /* Development */, + 812531260D3FEA33006BDF4F /* Deployment */, + 812531280D3FEA33006BDF4F /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 81DDFDA60D622C1700C5CB87 /* Build configuration list for PBXNativeTarget "setkey Embedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81DDFDA70D622C1700C5CB87 /* Development */, + 81DDFDA80D622C1700C5CB87 /* Deployment */, + 81DDFDA90D622C1700C5CB87 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 81DDFDC90D622C2700C5CB87 /* Build configuration list for PBXNativeTarget "libipsec Embedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81DDFDCA0D622C2700C5CB87 /* Development */, + 81DDFDCB0D622C2700C5CB87 /* Deployment */, + 81DDFDCC0D622C2700C5CB87 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; + }; + 81DDFDD30D622C3500C5CB87 /* Build configuration list for PBXNativeTarget "rsaparse Embedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 81DDFDD40D622C3500C5CB87 /* Development */, + 81DDFDD50D622C3500C5CB87 /* Deployment */, + 81DDFDD60D622C3500C5CB87 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Deployment; }; /* End XCConfigurationList section */ };