diff options
Diffstat (limited to 'linux/net/ipsec/pfkey_v2_parser.c')
-rw-r--r-- | linux/net/ipsec/pfkey_v2_parser.c | 3420 |
1 files changed, 0 insertions, 3420 deletions
diff --git a/linux/net/ipsec/pfkey_v2_parser.c b/linux/net/ipsec/pfkey_v2_parser.c deleted file mode 100644 index d170ddea5..000000000 --- a/linux/net/ipsec/pfkey_v2_parser.c +++ /dev/null @@ -1,3420 +0,0 @@ -/* - * @(#) RFC2367 PF_KEYv2 Key management API message parser - * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: pfkey_v2_parser.c,v 1.4 2004/09/29 22:27:41 as Exp $ - */ - -/* - * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. - */ - -char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.4 2004/09/29 22:27:41 as Exp $"; - -#include <linux/config.h> -#include <linux/version.h> -#include <linux/kernel.h> /* printk() */ - -#include "freeswan/ipsec_param.h" - -#ifdef MALLOC_SLAB -# include <linux/slab.h> /* kmalloc() */ -#else /* MALLOC_SLAB */ -# include <linux/malloc.h> /* kmalloc() */ -#endif /* MALLOC_SLAB */ -#include <linux/errno.h> /* error codes */ -#include <linux/types.h> /* size_t */ -#include <linux/interrupt.h> /* mark_bh */ - -#include <linux/netdevice.h> /* struct device, and other headers */ -#include <linux/etherdevice.h> /* eth_type_trans */ -#include <linux/ip.h> /* struct iphdr */ -#include <linux/skbuff.h> - -#include <freeswan.h> - -#include <crypto/des.h> - -#ifdef SPINLOCK -# ifdef SPINLOCK_23 -# include <linux/spinlock.h> /* *lock* */ -# else /* SPINLOCK_23 */ -# include <asm/spinlock.h> /* *lock* */ -# endif /* SPINLOCK_23 */ -#endif /* SPINLOCK */ -#ifdef NET_21 -# include <asm/uaccess.h> -# include <linux/in6.h> -# define ip_chk_addr inet_addr_type -# define IS_MYADDR RTN_LOCAL -#endif -#include <asm/checksum.h> -#include <net/ip.h> -#ifdef NETLINK_SOCK -# include <linux/netlink.h> -#else -# include <net/netlink.h> -#endif - -#include <linux/random.h> /* get_random_bytes() */ - -#include "freeswan/radij.h" -#include "freeswan/ipsec_encap.h" -#include "freeswan/ipsec_sa.h" - -#include "freeswan/ipsec_radij.h" -#include "freeswan/ipsec_xform.h" -#include "freeswan/ipsec_ah.h" -#include "freeswan/ipsec_esp.h" -#include "freeswan/ipsec_tunnel.h" -#include "freeswan/ipsec_rcv.h" -#include "freeswan/ipcomp.h" - -#include <pfkeyv2.h> -#include <pfkey.h> - -#include "freeswan/ipsec_proto.h" -#include "freeswan/ipsec_alg.h" - - -#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) - -struct sklist_t { - struct socket *sk; - struct sklist_t* next; -} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev; - -__u32 pfkey_msg_seq = 0; - -int -pfkey_alloc_eroute(struct eroute** eroute) -{ - int error = 0; - if(*eroute) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_alloc_eroute: " - "eroute struct already allocated\n"); - SENDERR(EEXIST); - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_alloc_eroute: " - "allocating %lu bytes for an eroute.\n", - (unsigned long) sizeof(**eroute)); - if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_alloc_eroute: " - "memory allocation error\n"); - SENDERR(ENOMEM); - } - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_alloc_eroute: " - "allocated eroute struct=0p%p.\n", eroute); - memset((caddr_t)*eroute, 0, sizeof(**eroute)); - (*eroute)->er_eaddr.sen_len = - (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap); - (*eroute)->er_eaddr.sen_family = - (*eroute)->er_emask.sen_family = AF_ENCAP; - (*eroute)->er_eaddr.sen_type = SENT_IP4; - (*eroute)->er_emask.sen_type = 255; - (*eroute)->er_pid = 0; - (*eroute)->er_count = 0; - (*eroute)->er_lasttime = jiffies/HZ; - - errlab: - return(error); -} - -DEBUG_NO_STATIC int -pfkey_x_protocol_process(struct sadb_ext *pfkey_ext, - struct pfkey_extracted_data *extr) -{ - int error = 0; - struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext; - - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr); - - if (extr == 0) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_protocol_process:" - "extr is NULL, fatal\n"); - SENDERR(EINVAL); - } - if (extr->eroute == 0) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_protocol_process:" - "extr->eroute is NULL, fatal\n"); - SENDERR(EINVAL); - } - extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto; - extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0; - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_protocol_process: protocol = %d.\n", - p->sadb_protocol_proto); - errlab: - return error; -} - -DEBUG_NO_STATIC int -pfkey_ipsec_sa_init(struct ipsec_sa *ipsp, struct sadb_ext **extensions) -{ - int error = 0; - char sa[SATOA_BUF]; - size_t sa_len; - char ipaddr_txt[ADDRTOA_BUF]; - char ipaddr2_txt[ADDRTOA_BUF]; -#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) - int i; - unsigned char kb[AHMD596_BLKLEN]; -#endif -#ifdef CONFIG_IPSEC_ALG - struct ipsec_alg_enc *ixt_e = NULL; - struct ipsec_alg_auth *ixt_a = NULL; -#endif /* CONFIG_IPSEC_ALG */ - - if(ipsp == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "ipsp is NULL, fatal\n"); - SENDERR(EINVAL); - } - - sa_len = satoa(ipsp->ips_said, 0, sa, SATOA_BUF); - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "(pfkey defined) called for SA:%s\n", - sa_len ? sa : " (error)"); - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "calling init routine of %s%s%s\n", - IPS_XFORM_NAME(ipsp)); - - switch(ipsp->ips_said.proto) { - -#ifdef CONFIG_IPSEC_IPIP - case IPPROTO_IPIP: { - addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr, - 0, - ipaddr_txt, sizeof(ipaddr_txt)); - addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, - 0, - ipaddr2_txt, sizeof(ipaddr_txt)); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n", - ipaddr_txt, - ipaddr2_txt); - } - break; -#endif /* !CONFIG_IPSEC_IPIP */ -#ifdef CONFIG_IPSEC_AH - case IPPROTO_AH: - switch(ipsp->ips_authalg) { -# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 - case AH_MD5: { - unsigned char *akp; - unsigned int aks; - MD5_CTX *ictx; - MD5_CTX *octx; - - if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, - ipsp->ips_key_bits_a, AHMD596_KLEN * 8); - SENDERR(EINVAL); - } - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "hmac md5-96 key is 0x%08x %08x %08x %08x\n", - ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - - ipsp->ips_auth_bits = AHMD596_ALEN * 8; - - /* save the pointer to the key material */ - akp = ipsp->ips_key_a; - aks = ipsp->ips_key_a_size; - - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "allocating %lu bytes for md5_ctx.\n", - (unsigned long) sizeof(struct md5_ctx)); - if((ipsp->ips_key_a = (caddr_t) - kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { - ipsp->ips_key_a = akp; - SENDERR(ENOMEM); - } - ipsp->ips_key_a_size = sizeof(struct md5_ctx); - - for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { - kb[i] = akp[i] ^ HMAC_IPAD; - } - for (; i < AHMD596_BLKLEN; i++) { - kb[i] = HMAC_IPAD; - } - - ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); - MD5Init(ictx); - MD5Update(ictx, kb, AHMD596_BLKLEN); - - for (i = 0; i < AHMD596_BLKLEN; i++) { - kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); - } - - octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); - MD5Init(octx); - MD5Update(octx, kb, AHMD596_BLKLEN); - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", - ((__u32*)ictx)[0], - ((__u32*)ictx)[1], - ((__u32*)ictx)[2], - ((__u32*)ictx)[3], - ((__u32*)octx)[0], - ((__u32*)octx)[1], - ((__u32*)octx)[2], - ((__u32*)octx)[3] ); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - - /* zero key buffer -- paranoid */ - memset(akp, 0, aks); - kfree(akp); - } - break; -# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 - case AH_SHA: { - unsigned char *akp; - unsigned int aks; - SHA1_CTX *ictx; - SHA1_CTX *octx; - - if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, - ipsp->ips_key_bits_a, AHSHA196_KLEN * 8); - SENDERR(EINVAL); - } - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", - ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - - ipsp->ips_auth_bits = AHSHA196_ALEN * 8; - - /* save the pointer to the key material */ - akp = ipsp->ips_key_a; - aks = ipsp->ips_key_a_size; - - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "allocating %lu bytes for sha1_ctx.\n", - (unsigned long) sizeof(struct sha1_ctx)); - if((ipsp->ips_key_a = (caddr_t) - kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { - ipsp->ips_key_a = akp; - SENDERR(ENOMEM); - } - ipsp->ips_key_a_size = sizeof(struct sha1_ctx); - - for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { - kb[i] = akp[i] ^ HMAC_IPAD; - } - for (; i < AHMD596_BLKLEN; i++) { - kb[i] = HMAC_IPAD; - } - - ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); - SHA1Init(ictx); - SHA1Update(ictx, kb, AHSHA196_BLKLEN); - - for (i = 0; i < AHSHA196_BLKLEN; i++) { - kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); - } - - octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx); - SHA1Init(octx); - SHA1Update(octx, kb, AHSHA196_BLKLEN); - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", - ((__u32*)ictx)[0], - ((__u32*)ictx)[1], - ((__u32*)ictx)[2], - ((__u32*)ictx)[3], - ((__u32*)octx)[0], - ((__u32*)octx)[1], - ((__u32*)octx)[2], - ((__u32*)octx)[3] ); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - /* zero key buffer -- paranoid */ - memset(akp, 0, aks); - kfree(akp); - } - break; -# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ - default: - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "authalg=%d support not available in the kernel", - ipsp->ips_authalg); - SENDERR(EINVAL); - } - break; -#endif /* CONFIG_IPSEC_AH */ -#ifdef CONFIG_IPSEC_ESP - case IPPROTO_ESP: { -#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) - unsigned char *akp; - unsigned int aks; -#endif -#if defined (CONFIG_IPSEC_ENC_3DES) - unsigned char *ekp; - unsigned int eks; -#endif - - ipsp->ips_iv_size = 0; -#ifdef CONFIG_IPSEC_ALG - if ((ixt_e=ipsp->ips_alg_enc)) { - ipsp->ips_iv_size = ixt_e->ixt_ivlen/8; - } else -#endif /* CONFIG_IPSEC_ALG */ - switch(ipsp->ips_encalg) { -# ifdef CONFIG_IPSEC_ENC_3DES - case ESP_3DES: -# endif /* CONFIG_IPSEC_ENC_3DES */ -# if defined(CONFIG_IPSEC_ENC_3DES) - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "allocating %u bytes for iv.\n", - EMT_ESPDES_IV_SZ); - if((ipsp->ips_iv = (caddr_t) - kmalloc((ipsp->ips_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) { - SENDERR(ENOMEM); - } - prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ); - ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; - ipsp->ips_iv_size = EMT_ESPDES_IV_SZ; - break; -# endif /* defined(CONFIG_IPSEC_ENC_3DES) */ - case ESP_NONE: - break; - default: - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "encalg=%d support not available in the kernel", - ipsp->ips_encalg); - SENDERR(EINVAL); - } - - /* Create IV */ - if (ipsp->ips_iv_size) { - if((ipsp->ips_iv = (caddr_t) - kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) { - SENDERR(ENOMEM); - } - prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, ipsp->ips_iv_size); - ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; - } - -#ifdef CONFIG_IPSEC_ALG - if (ixt_e) { - if ((error=ipsec_alg_enc_key_create(ipsp)) < 0) - SENDERR(-error); - } else -#endif /* CONFIG_IPSEC_ALG */ - switch(ipsp->ips_encalg) { -# ifdef CONFIG_IPSEC_ENC_3DES - case ESP_3DES: - if(ipsp->ips_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, - ipsp->ips_key_bits_e, EMT_ESP3DES_KEY_SZ * 8); - SENDERR(EINVAL); - } - - /* save encryption key pointer */ - ekp = ipsp->ips_key_e; - eks = ipsp->ips_key_e_size; - - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "allocating %lu bytes for 3des.\n", - (unsigned long) (3 * sizeof(struct des_eks))); - if((ipsp->ips_key_e = (caddr_t) - kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) { - ipsp->ips_key_e = ekp; - SENDERR(ENOMEM); - } - ipsp->ips_key_e_size = 3 * sizeof(struct des_eks); - - for(i = 0; i < 3; i++) { -#if KLIPS_DIVULGE_CYPHER_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "3des key %d/3 is 0x%08x%08x\n", - i + 1, - ntohl(*((__u32 *)ekp + i * 2)), - ntohl(*((__u32 *)ekp + i * 2 + 1))); -# endif -#if KLIPS_FIXES_DES_PARITY - /* force parity */ - des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i)); -#endif - error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i), - ((struct des_eks *)(ipsp->ips_key_e))[i].ks); - if (error == -1) - printk("klips_debug:pfkey_ipsec_sa_init: " - "parity error in des key %d/3\n", - i + 1); - else if (error == -2) - printk("klips_debug:pfkey_ipsec_sa_init: " - "illegal weak des key %d/3\n", i + 1); - if (error) { - memset(ekp, 0, eks); - kfree(ekp); - SENDERR(EINVAL); - } - } - - /* paranoid */ - memset(ekp, 0, eks); - kfree(ekp); - break; -# endif /* CONFIG_IPSEC_ENC_3DES */ - case ESP_NONE: - break; - default: - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "encalg=%d support not available in the kernel", - ipsp->ips_encalg); - SENDERR(EINVAL); - } - -#ifdef CONFIG_IPSEC_ALG - if ((ixt_a=ipsp->ips_alg_auth)) { - if ((error=ipsec_alg_auth_key_create(ipsp)) < 0) - SENDERR(-error); - } else -#endif /* CONFIG_IPSEC_ALG */ - - switch(ipsp->ips_authalg) { -# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 - case AH_MD5: { - MD5_CTX *ictx; - MD5_CTX *octx; - - if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, - ipsp->ips_key_bits_a, - AHMD596_KLEN * 8); - SENDERR(EINVAL); - } - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "hmac md5-96 key is 0x%08x %08x %08x %08x\n", - ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)), - ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)), - ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)), - ntohl(*(((__u32 *)(ipsp->ips_key_a))+3))); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - ipsp->ips_auth_bits = AHMD596_ALEN * 8; - - /* save the pointer to the key material */ - akp = ipsp->ips_key_a; - aks = ipsp->ips_key_a_size; - - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "allocating %lu bytes for md5_ctx.\n", - (unsigned long) sizeof(struct md5_ctx)); - if((ipsp->ips_key_a = (caddr_t) - kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { - ipsp->ips_key_a = akp; - SENDERR(ENOMEM); - } - ipsp->ips_key_a_size = sizeof(struct md5_ctx); - - for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { - kb[i] = akp[i] ^ HMAC_IPAD; - } - for (; i < AHMD596_BLKLEN; i++) { - kb[i] = HMAC_IPAD; - } - - ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); - MD5Init(ictx); - MD5Update(ictx, kb, AHMD596_BLKLEN); - - for (i = 0; i < AHMD596_BLKLEN; i++) { - kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); - } - - octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); - MD5Init(octx); - MD5Update(octx, kb, AHMD596_BLKLEN); - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", - ((__u32*)ictx)[0], - ((__u32*)ictx)[1], - ((__u32*)ictx)[2], - ((__u32*)ictx)[3], - ((__u32*)octx)[0], - ((__u32*)octx)[1], - ((__u32*)octx)[2], - ((__u32*)octx)[3] ); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - /* paranoid */ - memset(akp, 0, aks); - kfree(akp); - break; - } -# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 - case AH_SHA: { - SHA1_CTX *ictx; - SHA1_CTX *octx; - - if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, - ipsp->ips_key_bits_a, - AHSHA196_KLEN * 8); - SENDERR(EINVAL); - } - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", - ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), - ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - ipsp->ips_auth_bits = AHSHA196_ALEN * 8; - - /* save the pointer to the key material */ - akp = ipsp->ips_key_a; - aks = ipsp->ips_key_a_size; - - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "allocating %lu bytes for sha1_ctx.\n", - (unsigned long) sizeof(struct sha1_ctx)); - if((ipsp->ips_key_a = (caddr_t) - kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { - ipsp->ips_key_a = akp; - SENDERR(ENOMEM); - } - ipsp->ips_key_a_size = sizeof(struct sha1_ctx); - - for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { - kb[i] = akp[i] ^ HMAC_IPAD; - } - for (; i < AHMD596_BLKLEN; i++) { - kb[i] = HMAC_IPAD; - } - - ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); - SHA1Init(ictx); - SHA1Update(ictx, kb, AHSHA196_BLKLEN); - - for (i = 0; i < AHSHA196_BLKLEN; i++) { - kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); - } - - octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx; - SHA1Init(octx); - SHA1Update(octx, kb, AHSHA196_BLKLEN); - -# if KLIPS_DIVULGE_HMAC_KEY - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_ipsec_sa_init: " - "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", - ((__u32*)ictx)[0], - ((__u32*)ictx)[1], - ((__u32*)ictx)[2], - ((__u32*)ictx)[3], - ((__u32*)octx)[0], - ((__u32*)octx)[1], - ((__u32*)octx)[2], - ((__u32*)octx)[3] ); -# endif /* KLIPS_DIVULGE_HMAC_KEY */ - memset(akp, 0, aks); - kfree(akp); - break; - } -# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ - case AH_NONE: - break; - default: - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "authalg=%d support not available in the kernel.\n", - ipsp->ips_authalg); - SENDERR(EINVAL); - } - } - break; -#endif /* !CONFIG_IPSEC_ESP */ -#ifdef CONFIG_IPSEC_IPCOMP - case IPPROTO_COMP: - ipsp->ips_comp_adapt_tries = 0; - ipsp->ips_comp_adapt_skip = 0; - ipsp->ips_comp_ratio_cbytes = 0; - ipsp->ips_comp_ratio_dbytes = 0; - break; -#endif /* CONFIG_IPSEC_IPCOMP */ - default: - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_ipsec_sa_init: " - "proto=%d unknown.\n", - ipsp->ips_said.proto); - SENDERR(EINVAL); - } - - errlab: - return(error); -} - - -int -pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1]) -{ - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: " - "error=%d\n", - error); - if (!error) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" - "success.\n"); - return 1; - } else { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" - "caught error %d\n", - error); - pfkey_extensions_free(extensions); - return 0; - } -} - - -DEBUG_NO_STATIC int -pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L); - int found_avail = 0; - struct ipsec_sa *ipsq; - char sa[SATOA_BUF]; - size_t sa_len; - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_getspi_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - if(extr == NULL || extr->ips == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_getspi_parse: " - "error, extr or extr->ipsec_sa pointer NULL\n"); - SENDERR(EINVAL); - } - - if(extensions[SADB_EXT_SPIRANGE]) { - minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min; - maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max; - } - - if(maxspi == minspi) { - extr->ips->ips_said.spi = maxspi; - ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if(ipsq != NULL) { - sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); - ipsec_sa_put(ipsq); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_getspi_parse: " - "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n", - sa_len ? sa : " (error)"); - SENDERR(EEXIST); - } else { - found_avail = 1; - } - } else { - int i = 0; - __u32 rand_val; - __u32 spi_diff; - while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) { - prng_bytes(&ipsec_prng, (char *) &(rand_val), - ( (spi_diff < (2^8)) ? 1 : - ( (spi_diff < (2^16)) ? 2 : - ( (spi_diff < (2^24)) ? 3 : - 4 ) ) ) ); - extr->ips->ips_said.spi = htonl(ntohl(minspi) + - (rand_val % - (spi_diff + 1))); - i++; - ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if(ipsq == NULL) { - found_avail = 1; - } else { - ipsec_sa_put(ipsq); - } - } - } - - sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); - - if (!found_avail) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_getspi_parse: " - "found an old ipsec_sa for SA: %s, delete it first.\n", - sa_len ? sa : " (error)"); - SENDERR(EEXIST); - } - - if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) { - extr->ips->ips_flags |= EMT_INBOUND; - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_getspi_parse: " - "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n", - sa_len ? sa : " (error)", - extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); - - /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ - extr->ips->ips_rcvif = NULL; - extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ; - - extr->ips->ips_state = SADB_SASTATE_LARVAL; - - if(!extr->ips->ips_life.ipl_allocations.ipl_count) { - extr->ips->ips_life.ipl_allocations.ipl_count += 1; - } - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_GETSPI, - satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - 0, - SADB_SASTATE_LARVAL, - 0, - 0, - 0, - extr->ips->ips_ref), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_s), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_d), - extensions_reply) )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " - "failed to build the getspi reply message extensions\n"); - goto errlab; - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " - "failed to build the getspi reply message\n"); - SENDERR(-error); - } - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " - "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " - "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - if((error = ipsec_sa_add(extr->ips))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " - "failed to add the larval SA=%s with error=%d.\n", - sa_len ? sa : " (error)", - error); - SENDERR(-error); - } - extr->ips = NULL; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_getspi_parse: " - "successful for SA: %s\n", - sa_len ? sa : " (error)"); - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - struct ipsec_sa* ipsq; - char sa[SATOA_BUF]; - size_t sa_len; - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -#ifdef CONFIG_IPSEC_NAT_TRAVERSAL - struct ipsec_sa *nat_t_ips_saved = NULL; -#endif - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: " - "error, sa_state=%d must be MATURE=%d\n", - ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, - SADB_SASTATE_MATURE); - SENDERR(EINVAL); - } - - if(extr == NULL || extr->ips == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: " - "error, extr or extr->ips pointer NULL\n"); - SENDERR(EINVAL); - } - - sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); - - spin_lock_bh(&tdb_lock); - - ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if (ipsq == NULL) { - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: " - "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n", - sa_len ? sa : " (error)"); - SENDERR(ENOENT); - } - - if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) { - extr->ips->ips_flags |= EMT_INBOUND; - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: " - "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n", - sa_len ? sa : " (error)", - extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); - -#ifdef CONFIG_IPSEC_NAT_TRAVERSAL - if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: only updating NAT-T ports " - "(%u:%u -> %u:%u)\n", - ipsq->ips_natt_sport, ipsq->ips_natt_dport, - extr->ips->ips_natt_sport, extr->ips->ips_natt_dport); - - if (extr->ips->ips_natt_sport) { - ipsq->ips_natt_sport = extr->ips->ips_natt_sport; - if (ipsq->ips_addr_s->sa_family == AF_INET) { - ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport); - } - } - - if (extr->ips->ips_natt_dport) { - ipsq->ips_natt_dport = extr->ips->ips_natt_dport; - if (ipsq->ips_addr_d->sa_family == AF_INET) { - ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport); - } - } - - nat_t_ips_saved = extr->ips; - extr->ips = ipsq; - } - else { -#endif - - /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ - extr->ips->ips_rcvif = NULL; - if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { - ipsec_sa_put(ipsq); - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: " - "not successful for SA: %s, deleting.\n", - sa_len ? sa : " (error)"); - SENDERR(-error); - } - - extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count; - ipsec_sa_put(ipsq); - if((error = ipsec_sa_delchain(ipsq))) { - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: " - "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n", - error, - sa_len ? sa : " (error)"); - SENDERR(-error); - } -#ifdef CONFIG_IPSEC_NAT_TRAVERSAL - } -#endif - - spin_unlock_bh(&tdb_lock); - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_UPDATE, - satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - extr->ips->ips_replaywin, - extr->ips->ips_state, - extr->ips->ips_authalg, - extr->ips->ips_encalg, - extr->ips->ips_flags, - extr->ips->ips_ref), - extensions_reply) - /* The 3 lifetime extentions should only be sent if non-zero. */ - && (extensions[SADB_EXT_LIFETIME_HARD] - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], - SADB_EXT_LIFETIME_HARD, - extr->ips->ips_life.ipl_allocations.ipl_hard, - extr->ips->ips_life.ipl_bytes.ipl_hard, - extr->ips->ips_life.ipl_addtime.ipl_hard, - extr->ips->ips_life.ipl_usetime.ipl_hard, - extr->ips->ips_life.ipl_packets.ipl_hard), - extensions_reply) : 1) - && (extensions[SADB_EXT_LIFETIME_SOFT] - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], - SADB_EXT_LIFETIME_SOFT, - extr->ips->ips_life.ipl_allocations.ipl_count, - extr->ips->ips_life.ipl_bytes.ipl_count, - extr->ips->ips_life.ipl_addtime.ipl_count, - extr->ips->ips_life.ipl_usetime.ipl_count, - extr->ips->ips_life.ipl_packets.ipl_count), - extensions_reply) : 1) - && (extr->ips->ips_life.ipl_allocations.ipl_count - || extr->ips->ips_life.ipl_bytes.ipl_count - || extr->ips->ips_life.ipl_addtime.ipl_count - || extr->ips->ips_life.ipl_usetime.ipl_count - || extr->ips->ips_life.ipl_packets.ipl_count - - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], - SADB_EXT_LIFETIME_CURRENT, - extr->ips->ips_life.ipl_allocations.ipl_count, - extr->ips->ips_life.ipl_bytes.ipl_count, - extr->ips->ips_life.ipl_addtime.ipl_count, - extr->ips->ips_life.ipl_usetime.ipl_count, - extr->ips->ips_life.ipl_packets.ipl_count), - extensions_reply) : 1) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_s), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_d), - extensions_reply) - && (extr->ips->ips_ident_s.data - ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], - SADB_EXT_IDENTITY_SRC, - extr->ips->ips_ident_s.type, - extr->ips->ips_ident_s.id, - extr->ips->ips_ident_s.len, - extr->ips->ips_ident_s.data), - extensions_reply) : 1) - && (extr->ips->ips_ident_d.data - ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], - SADB_EXT_IDENTITY_DST, - extr->ips->ips_ident_d.type, - extr->ips->ips_ident_d.id, - extr->ips->ips_ident_d.len, - extr->ips->ips_ident_d.data), - extensions_reply) : 1) -#if 0 - /* FIXME: This won't work yet because I have not finished - it. */ - && (extr->ips->ips_sens_ - ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], - extr->ips->ips_sens_dpd, - extr->ips->ips_sens_sens_level, - extr->ips->ips_sens_sens_len, - extr->ips->ips_sens_sens_bitmap, - extr->ips->ips_sens_integ_level, - extr->ips->ips_sens_integ_len, - extr->ips->ips_sens_integ_bitmap), - extensions_reply) : 1) -#endif - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " - "failed to build the update reply message extensions\n"); - SENDERR(-error); - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " - "failed to build the update reply message\n"); - SENDERR(-error); - } - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " - "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " - "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - -#ifdef CONFIG_IPSEC_NAT_TRAVERSAL - if (nat_t_ips_saved) { - /** - * As we _really_ update existing SA, we keep tdbq and need to delete - * parsed ips (nat_t_ips_saved, was extr->ips). - * - * goto errlab with extr->ips = nat_t_ips_saved will free it. - */ - - extr->ips = nat_t_ips_saved; - - error = 0; - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse (NAT-T ports): " - "successful for SA: %s\n", - sa_len ? sa : " (error)"); - - goto errlab; - } -#endif - - if((error = ipsec_sa_add(extr->ips))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " - "failed to update the mature SA=%s with error=%d.\n", - sa_len ? sa : " (error)", - error); - SENDERR(-error); - } - extr->ips = NULL; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_update_parse: " - "successful for SA: %s\n", - sa_len ? sa : " (error)"); - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - struct ipsec_sa* ipsq; - char sa[SATOA_BUF]; - size_t sa_len; - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_add_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_add_parse: " - "error, sa_state=%d must be MATURE=%d\n", - ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, - SADB_SASTATE_MATURE); - SENDERR(EINVAL); - } - - if(!extr || !extr->ips) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_add_parse: " - "extr or extr->ips pointer NULL\n"); - SENDERR(EINVAL); - } - - sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); - - ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if(ipsq != NULL) { - ipsec_sa_put(ipsq); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_add_parse: " - "found an old ipsec_sa for SA%s, delete it first.\n", - sa_len ? sa : " (error)"); - SENDERR(EEXIST); - } - - if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) { - extr->ips->ips_flags |= EMT_INBOUND; - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_add_parse: " - "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n", - sa_len ? sa : " (error)", - extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); - - /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ - extr->ips->ips_rcvif = NULL; - - if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_add_parse: " - "not successful for SA: %s, deleting.\n", - sa_len ? sa : " (error)"); - SENDERR(-error); - } - - extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ; - if(!extr->ips->ips_life.ipl_allocations.ipl_count) { - extr->ips->ips_life.ipl_allocations.ipl_count += 1; - } - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_ADD, - satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - extr->ips->ips_replaywin, - extr->ips->ips_state, - extr->ips->ips_authalg, - extr->ips->ips_encalg, - extr->ips->ips_flags, - extr->ips->ips_ref), - extensions_reply) - /* The 3 lifetime extentions should only be sent if non-zero. */ - && (extensions[SADB_EXT_LIFETIME_HARD] - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], - SADB_EXT_LIFETIME_HARD, - extr->ips->ips_life.ipl_allocations.ipl_hard, - extr->ips->ips_life.ipl_bytes.ipl_hard, - extr->ips->ips_life.ipl_addtime.ipl_hard, - extr->ips->ips_life.ipl_usetime.ipl_hard, - extr->ips->ips_life.ipl_packets.ipl_hard), - extensions_reply) : 1) - && (extensions[SADB_EXT_LIFETIME_SOFT] - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], - SADB_EXT_LIFETIME_SOFT, - extr->ips->ips_life.ipl_allocations.ipl_soft, - extr->ips->ips_life.ipl_bytes.ipl_soft, - extr->ips->ips_life.ipl_addtime.ipl_soft, - extr->ips->ips_life.ipl_usetime.ipl_soft, - extr->ips->ips_life.ipl_packets.ipl_soft), - extensions_reply) : 1) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_s), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_d), - extensions_reply) - && (extr->ips->ips_ident_s.data - ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], - SADB_EXT_IDENTITY_SRC, - extr->ips->ips_ident_s.type, - extr->ips->ips_ident_s.id, - extr->ips->ips_ident_s.len, - extr->ips->ips_ident_s.data), - extensions_reply) : 1) - && (extr->ips->ips_ident_d.data - ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], - SADB_EXT_IDENTITY_DST, - extr->ips->ips_ident_d.type, - extr->ips->ips_ident_d.id, - extr->ips->ips_ident_d.len, - extr->ips->ips_ident_d.data), - extensions_reply) : 1) -#if 0 - /* FIXME: This won't work yet because I have not finished - it. */ - && (extr->ips->ips_sens_ - ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], - extr->ips->ips_sens_dpd, - extr->ips->ips_sens_sens_level, - extr->ips->ips_sens_sens_len, - extr->ips->ips_sens_sens_bitmap, - extr->ips->ips_sens_integ_level, - extr->ips->ips_sens_integ_len, - extr->ips->ips_sens_integ_bitmap), - extensions_reply) : 1) -#endif - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " - "failed to build the add reply message extensions\n"); - SENDERR(-error); - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " - "failed to build the add reply message\n"); - SENDERR(-error); - } - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " - "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " - "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - if((error = ipsec_sa_add(extr->ips))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " - "failed to add the mature SA=%s with error=%d.\n", - sa_len ? sa : " (error)", - error); - SENDERR(-error); - } - extr->ips = NULL; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_add_parse: " - "successful for SA: %s\n", - sa_len ? sa : " (error)"); - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - struct ipsec_sa *ipsp; - char sa[SATOA_BUF]; - size_t sa_len; - int error = 0; - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_delete_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - if(!extr || !extr->ips) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_delete_parse: " - "extr or extr->ips pointer NULL, fatal\n"); - SENDERR(EINVAL); - } - - sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); - - spin_lock_bh(&tdb_lock); - - ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if (ipsp == NULL) { - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_delete_parse: " - "ipsec_sa not found for SA:%s, could not delete.\n", - sa_len ? sa : " (error)"); - SENDERR(ESRCH); - } - - ipsec_sa_put(ipsp); - if((error = ipsec_sa_delchain(ipsp))) { - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_delete_parse: " - "error=%d returned trying to delete ipsec_sa for SA:%s.\n", - error, - sa_len ? sa : " (error)"); - SENDERR(-error); - } - spin_unlock_bh(&tdb_lock); - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_DELETE, - satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - 0, - 0, - 0, - 0, - 0, - extr->ips->ips_ref), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_s), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_d), - extensions_reply) - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " - "failed to build the delete reply message extensions\n"); - SENDERR(-error); - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " - "failed to build the delete reply message\n"); - SENDERR(-error); - } - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " - "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " - "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - struct ipsec_sa *ipsp; - char sa[SATOA_BUF]; - size_t sa_len; - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_get_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - if(!extr || !extr->ips) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_get_parse: " - "extr or extr->ips pointer NULL, fatal\n"); - SENDERR(EINVAL); - } - - sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); - - spin_lock_bh(&tdb_lock); - - ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if (ipsp == NULL) { - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " - "ipsec_sa not found for SA=%s, could not get.\n", - sa_len ? sa : " (error)"); - SENDERR(ESRCH); - } - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_GET, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - extr->ips->ips_replaywin, - extr->ips->ips_state, - extr->ips->ips_authalg, - extr->ips->ips_encalg, - extr->ips->ips_flags, - extr->ips->ips_ref), - extensions_reply) - /* The 3 lifetime extentions should only be sent if non-zero. */ - && (ipsp->ips_life.ipl_allocations.ipl_count - || ipsp->ips_life.ipl_bytes.ipl_count - || ipsp->ips_life.ipl_addtime.ipl_count - || ipsp->ips_life.ipl_usetime.ipl_count - || ipsp->ips_life.ipl_packets.ipl_count - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], - SADB_EXT_LIFETIME_CURRENT, - ipsp->ips_life.ipl_allocations.ipl_count, - ipsp->ips_life.ipl_bytes.ipl_count, - ipsp->ips_life.ipl_addtime.ipl_count, - ipsp->ips_life.ipl_usetime.ipl_count, - ipsp->ips_life.ipl_packets.ipl_count), - extensions_reply) : 1) - && (ipsp->ips_life.ipl_allocations.ipl_hard - || ipsp->ips_life.ipl_bytes.ipl_hard - || ipsp->ips_life.ipl_addtime.ipl_hard - || ipsp->ips_life.ipl_usetime.ipl_hard - || ipsp->ips_life.ipl_packets.ipl_hard - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], - SADB_EXT_LIFETIME_HARD, - ipsp->ips_life.ipl_allocations.ipl_hard, - ipsp->ips_life.ipl_bytes.ipl_hard, - ipsp->ips_life.ipl_addtime.ipl_hard, - ipsp->ips_life.ipl_usetime.ipl_hard, - ipsp->ips_life.ipl_packets.ipl_hard), - extensions_reply) : 1) - && (ipsp->ips_life.ipl_allocations.ipl_soft - || ipsp->ips_life.ipl_bytes.ipl_soft - || ipsp->ips_life.ipl_addtime.ipl_soft - || ipsp->ips_life.ipl_usetime.ipl_soft - || ipsp->ips_life.ipl_packets.ipl_soft - ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], - SADB_EXT_LIFETIME_SOFT, - ipsp->ips_life.ipl_allocations.ipl_soft, - ipsp->ips_life.ipl_bytes.ipl_soft, - ipsp->ips_life.ipl_addtime.ipl_soft, - ipsp->ips_life.ipl_usetime.ipl_soft, - ipsp->ips_life.ipl_packets.ipl_soft), - extensions_reply) : 1) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_s), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_d), - extensions_reply) - && (extr->ips->ips_addr_p - ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY], - SADB_EXT_ADDRESS_PROXY, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_p), - extensions_reply) : 1) -#if 0 - /* FIXME: This won't work yet because the keys are not - stored directly in the ipsec_sa. They are stored as - contexts. */ - && (extr->ips->ips_key_a_size - ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH], - SADB_EXT_KEY_AUTH, - extr->ips->ips_key_a_size * 8, - extr->ips->ips_key_a), - extensions_reply) : 1) - /* FIXME: This won't work yet because the keys are not - stored directly in the ipsec_sa. They are stored as - key schedules. */ - && (extr->ips->ips_key_e_size - ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT], - SADB_EXT_KEY_ENCRYPT, - extr->ips->ips_key_e_size * 8, - extr->ips->ips_key_e), - extensions_reply) : 1) -#endif - && (extr->ips->ips_ident_s.data - ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], - SADB_EXT_IDENTITY_SRC, - extr->ips->ips_ident_s.type, - extr->ips->ips_ident_s.id, - extr->ips->ips_ident_s.len, - extr->ips->ips_ident_s.data), - extensions_reply) : 1) - && (extr->ips->ips_ident_d.data - ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], - SADB_EXT_IDENTITY_DST, - extr->ips->ips_ident_d.type, - extr->ips->ips_ident_d.id, - extr->ips->ips_ident_d.len, - extr->ips->ips_ident_d.data), - extensions_reply) : 1) -#if 0 - /* FIXME: This won't work yet because I have not finished - it. */ - && (extr->ips->ips_sens_ - ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], - extr->ips->ips_sens_dpd, - extr->ips->ips_sens_sens_level, - extr->ips->ips_sens_sens_len, - extr->ips->ips_sens_sens_bitmap, - extr->ips->ips_sens_integ_level, - extr->ips->ips_sens_integ_len, - extr->ips->ips_sens_integ_bitmap), - extensions_reply) : 1) -#endif - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " - "failed to build the get reply message extensions\n"); - ipsec_sa_put(ipsp); - spin_unlock_bh(&tdb_lock); - SENDERR(-error); - } - - ipsec_sa_put(ipsp); - spin_unlock_bh(&tdb_lock); - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " - "failed to build the get reply message\n"); - SENDERR(-error); - } - - if((error = pfkey_upmsg(sk->socket, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " - "failed to send the get reply message\n"); - SENDERR(-error); - } - - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " - "succeeded in sending get reply message.\n"); - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_acquire_parse: .\n"); - - /* XXX I don't know if we want an upper bound, since userspace may - want to register itself for an satype > SADB_SATYPE_MAX. */ - if((satype == 0) || (satype > SADB_SATYPE_MAX)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_acquire_parse: " - "SATYPE=%d invalid.\n", - satype); - SENDERR(EINVAL); - } - - if(!(pfkey_registered_sockets[satype])) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " - "no sockets registered for SAtype=%d(%s).\n", - satype, - satype2name(satype)); - SENDERR(EPROTONOSUPPORT); - } - - for(pfkey_socketsp = pfkey_registered_sockets[satype]; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " - "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " - "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - errlab: - return error; -} - -DEBUG_NO_STATIC int -pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_parse: .\n"); - - /* XXX I don't know if we want an upper bound, since userspace may - want to register itself for an satype > SADB_SATYPE_MAX. */ - if((satype == 0) || (satype > SADB_SATYPE_MAX)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_parse: " - "SATYPE=%d invalid.\n", - satype); - SENDERR(EINVAL); - } - - if(!pfkey_list_insert_socket(sk->socket, - &(pfkey_registered_sockets[satype]))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_parse: " - "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n", - satype, - satype2name(satype), - key_pid(sk)); - }; - - /* send up register msg with supported SATYPE algos */ - - error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]); - errlab: - return error; -} -int -pfkey_register_reply(int satype, struct sadb_msg *sadb_msg) -{ - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - struct supported_list *pfkey_supported_listp; - unsigned int alg_num_a = 0, alg_num_e = 0; - struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL; - int error = 0; - - pfkey_extensions_init(extensions_reply); - - if((satype == 0) || (satype > SADB_SATYPE_MAX)) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " - "SAtype=%d unspecified or unknown.\n", - satype); - SENDERR(EINVAL); - } - if(!(pfkey_registered_sockets[satype])) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " - "no sockets registered for SAtype=%d(%s).\n", - satype, - satype2name(satype)); - SENDERR(EPROTONOSUPPORT); - } - /* send up register msg with supported SATYPE algos */ - pfkey_supported_listp = pfkey_supported_list[satype]; - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "pfkey_supported_list[%d]=0p%p\n", - satype, - pfkey_supported_list[satype]); - while(pfkey_supported_listp) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "checking supported=0p%p\n", - pfkey_supported_listp); - if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "adding auth alg.\n"); - alg_num_a++; - } - if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "adding encrypt alg.\n"); - alg_num_e++; - } - pfkey_supported_listp = pfkey_supported_listp->next; - } - - if(alg_num_a) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "allocating %lu bytes for auth algs.\n", - (unsigned long) (alg_num_a * sizeof(struct sadb_alg))); - if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "auth alg memory allocation error\n"); - SENDERR(ENOMEM); - } - alg_ap = alg_a; - } - - if(alg_num_e) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "allocating %lu bytes for enc algs.\n", - (unsigned long) (alg_num_e * sizeof(struct sadb_alg))); - if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "enc alg memory allocation error\n"); - SENDERR(ENOMEM); - } - alg_ep = alg_e; - } - - pfkey_supported_listp = pfkey_supported_list[satype]; - while(pfkey_supported_listp) { - if(alg_num_a) { - if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { - alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; - alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; - alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; - alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; - alg_ap->sadb_alg_reserved = 0; - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_register_reply: " - "adding auth=0p%p\n", - alg_ap); - alg_ap++; - } - } - if(alg_num_e) { - if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { - alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; - alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; - alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; - alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; - alg_ep->sadb_alg_reserved = 0; - KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, - "klips_debug:pfkey_register_reply: " - "adding encrypt=0p%p\n", - alg_ep); - alg_ep++; - } - } - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_register_reply: " - "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", - satype, - satype2name(satype), - pfkey_supported_listp->supportedp->supported_alg_exttype, - pfkey_supported_listp->supportedp->supported_alg_id, - pfkey_supported_listp->supportedp->supported_alg_ivlen, - pfkey_supported_listp->supportedp->supported_alg_minbits, - pfkey_supported_listp->supportedp->supported_alg_maxbits); - pfkey_supported_listp = pfkey_supported_listp->next; - } - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_REGISTER, - satype, - 0, - sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq, - sadb_msg? sadb_msg->sadb_msg_pid: current->pid), - extensions_reply) && - (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH], - SADB_EXT_SUPPORTED_AUTH, - alg_num_a, - alg_a), - extensions_reply) : 1) && - (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT], - SADB_EXT_SUPPORTED_ENCRYPT, - alg_num_e, - alg_e), - extensions_reply) : 1))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " - "failed to build the register message extensions_reply\n"); - SENDERR(-error); - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " - "failed to build the register message\n"); - SENDERR(-error); - } - /* this should go to all registered sockets for that satype only */ - for(pfkey_socketsp = pfkey_registered_sockets[satype]; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " - "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " - "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - errlab: - if(alg_a) { - kfree(alg_a); - } - if(alg_e) { - kfree(alg_e); - } - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - struct socket_list *pfkey_socketsp; -#ifdef CONFIG_IPSEC_DEBUG - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -#endif /* CONFIG_IPSEC_DEBUG */ - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_expire_parse: .\n"); - - if(pfkey_open_sockets) { - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " - "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " - "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - } - - errlab: - return error; -} - -DEBUG_NO_STATIC int -pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - uint8_t proto = 0; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_flush_parse: " - "flushing type %d SAs\n", - satype); - - if(satype && !(proto = satype2proto(satype))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_flush_parse: " - "satype %d lookup failed.\n", - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); - SENDERR(EINVAL); - } - - if ((error = ipsec_sadb_cleanup(proto))) { - SENDERR(-error); - } - - if(pfkey_open_sockets) { - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " - "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - proto, - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " - "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - } - - errlab: - return error; -} - -DEBUG_NO_STATIC int -pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_dump_parse: .\n"); - - SENDERR(ENOSYS); - errlab: - return error; -} - -DEBUG_NO_STATIC int -pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_promisc_parse: .\n"); - - SENDERR(ENOSYS); - errlab: - return error; -} - -DEBUG_NO_STATIC int -pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_pchange_parse: .\n"); - - SENDERR(ENOSYS); - errlab: - return error; -} - -DEBUG_NO_STATIC int -pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - struct ipsec_sa *ips1p, *ips2p, *ipsp; - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - char sa1[SATOA_BUF], sa2[SATOA_BUF]; - size_t sa_len1, sa_len2 = 0; - int error = 0; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - if(extr == NULL || extr->ips == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "extr or extr->ips is NULL, fatal.\n"); - SENDERR(EINVAL); - } - - sa_len1 = satoa(extr->ips->ips_said, 0, sa1, SATOA_BUF); - if(extr->ips2 != NULL) { - sa_len2 = satoa(extr->ips2->ips_said, 0, sa2, SATOA_BUF); - } - - spin_lock_bh(&tdb_lock); - - ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if(ips1p == NULL) { - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n", - sa_len1 ? sa1 : " (error)"); - SENDERR(ENOENT); - } - if(extr->ips2) { /* GRPSA */ - ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said)); - if(ips2p == NULL) { - ipsec_sa_put(ips1p); - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n", - sa_len2 ? sa2 : " (error)"); - SENDERR(ENOENT); - } - - /* Is either one already linked? */ - if(ips1p->ips_onext) { - ipsec_sa_put(ips1p); - ipsec_sa_put(ips2p); - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "ipsec_sa for SA: %s is already linked.\n", - sa_len1 ? sa1 : " (error)"); - SENDERR(EEXIST); - } - if(ips2p->ips_inext) { - ipsec_sa_put(ips1p); - ipsec_sa_put(ips2p); - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "ipsec_sa for SA: %s is already linked.\n", - sa_len2 ? sa2 : " (error)"); - SENDERR(EEXIST); - } - - /* Is extr->ips already linked to extr->ips2? */ - ipsp = ips2p; - while(ipsp) { - if(ipsp == ips1p) { - ipsec_sa_put(ips1p); - ipsec_sa_put(ips2p); - spin_unlock_bh(&tdb_lock); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "ipsec_sa for SA: %s is already linked to %s.\n", - sa_len1 ? sa1 : " (error)", - sa_len2 ? sa2 : " (error)"); - SENDERR(EEXIST); - } - ipsp = ipsp->ips_onext; - } - - /* link 'em */ - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "linking ipsec_sa SA: %s with %s.\n", - sa_len1 ? sa1 : " (error)", - sa_len2 ? sa2 : " (error)"); - ips1p->ips_onext = ips2p; - ips2p->ips_inext = ips1p; - } else { /* UNGRPSA */ - ipsec_sa_put(ips1p); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_grpsa_parse: " - "unlinking ipsec_sa SA: %s.\n", - sa_len1 ? sa1 : " (error)"); - while(ips1p->ips_onext) { - ips1p = ips1p->ips_onext; - } - while(ips1p->ips_inext) { - ipsp = ips1p; - ips1p = ips1p->ips_inext; - ipsec_sa_put(ips1p); - ipsp->ips_inext = NULL; - ipsec_sa_put(ipsp); - ips1p->ips_onext = NULL; - } - } - - spin_unlock_bh(&tdb_lock); - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_X_GRPSA, - satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - extr->ips->ips_replaywin, - extr->ips->ips_state, - extr->ips->ips_authalg, - extr->ips->ips_encalg, - extr->ips->ips_flags, - extr->ips->ips_ref), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_d), - extensions_reply) - && (extr->ips2 - ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2], - ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype - /* proto2satype(extr->ips2->ips_said.proto) */), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2], - SADB_X_EXT_SA2, - extr->ips2->ips_said.spi, - extr->ips2->ips_replaywin, - extr->ips2->ips_state, - extr->ips2->ips_authalg, - extr->ips2->ips_encalg, - extr->ips2->ips_flags, - extr->ips2->ips_ref), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2], - SADB_X_EXT_ADDRESS_DST2, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips2->ips_addr_d), - extensions_reply) ) : 1 ) - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " - "failed to build the x_grpsa reply message extensions\n"); - SENDERR(-error); - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " - "failed to build the x_grpsa reply message\n"); - SENDERR(-error); - } - - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " - "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " - "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " - "succeeded in sending x_grpsa reply message.\n"); - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; -#ifdef CONFIG_IPSEC_DEBUG - char buf1[64], buf2[64]; -#endif /* CONFIG_IPSEC_DEBUG */ - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - ip_address srcflow, dstflow, srcmask, dstmask; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - memset((caddr_t)&srcflow, 0, sizeof(srcflow)); - memset((caddr_t)&dstflow, 0, sizeof(dstflow)); - memset((caddr_t)&srcmask, 0, sizeof(srcmask)); - memset((caddr_t)&dstmask, 0, sizeof(dstmask)); - - if(!extr || !(extr->ips) || !(extr->eroute)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "missing extr, ipsec_sa or eroute data.\n"); - SENDERR(EINVAL); - } - - srcflow.u.v4.sin_family = AF_INET; - dstflow.u.v4.sin_family = AF_INET; - srcmask.u.v4.sin_family = AF_INET; - dstmask.u.v4.sin_family = AF_INET; - srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; - dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; - srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; - dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; - -#ifdef CONFIG_IPSEC_DEBUG - if (debug_pfkey) { - subnettoa(extr->eroute->er_eaddr.sen_ip_src, - extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); - subnettoa(extr->eroute->er_eaddr.sen_ip_dst, - extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "calling breakeroute and/or makeroute for %s->%s\n", - buf1, buf2); - } -#endif /* CONFIG_IPSEC_DEBUG */ - if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) { -/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) */ - struct ipsec_sa *ipsp, *ipsq; - char sa[SATOA_BUF]; - size_t sa_len; - - ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); - if(ipsq == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "ipsec_sa not found, cannot set incoming policy.\n"); - SENDERR(ENOENT); - } - - ipsp = ipsq; - while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) { - ipsp = ipsp->ips_inext; - } - - if(ipsp == NULL) { - ipsec_sa_put(ipsq); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "SA chain does not have an IPIP SA, cannot set incoming policy.\n"); - SENDERR(ENOENT); - } - - sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); - - ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW; - ipsp->ips_flow_s = srcflow; - ipsp->ips_flow_d = dstflow; - ipsp->ips_mask_s = srcmask; - ipsp->ips_mask_d = dstmask; - - ipsec_sa_put(ipsq); - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n", - sa_len ? sa : " (error)"); - } else { - struct sk_buff *first = NULL, *last = NULL; - - if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "REPLACEFLOW flag set, calling breakeroute.\n"); - if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr), - &(extr->eroute->er_emask), - &first, &last))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "breakeroute returned %d. first=0p%p, last=0p%p\n", - error, - first, - last); - if(first != NULL) { - ipsec_kfree_skb(first); - } - if(last != NULL) { - ipsec_kfree_skb(last); - } - SENDERR(-error); - } - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "calling makeroute.\n"); - - if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr), - &(extr->eroute->er_emask), - extr->ips->ips_said, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid, - NULL, - &(extr->ips->ips_ident_s), - &(extr->ips->ips_ident_d)))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "makeroute returned %d.\n", error); - SENDERR(-error); - } - if(first != NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "first=0p%p HOLD packet re-injected.\n", - first); - DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL); - } - if(last != NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "last=0p%p HOLD packet re-injected.\n", - last); - DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL); - } - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "makeroute call successful.\n"); - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_X_ADDFLOW, - satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - extr->ips->ips_replaywin, - extr->ips->ips_state, - extr->ips->ips_authalg, - extr->ips->ips_encalg, - extr->ips->ips_flags, - extr->ips->ips_ref), - extensions_reply) - && (extensions[SADB_EXT_ADDRESS_SRC] - ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_s), - extensions_reply) : 1) - && (extensions[SADB_EXT_ADDRESS_DST] - ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /*extr->ips->ips_said.proto,*/ - 0, - extr->ips->ips_addr_d), - extensions_reply) : 1) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], - SADB_X_EXT_ADDRESS_SRC_FLOW, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&srcflow), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], - SADB_X_EXT_ADDRESS_DST_FLOW, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&dstflow), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], - SADB_X_EXT_ADDRESS_SRC_MASK, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&srcmask), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], - SADB_X_EXT_ADDRESS_DST_MASK, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&dstmask), - extensions_reply) - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " - "failed to build the x_addflow reply message extensions\n"); - SENDERR(-error); - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " - "failed to build the x_addflow reply message\n"); - SENDERR(-error); - } - - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " - "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " - "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - extr->ips->ips_said.proto, - pfkey_socketsp->socketp); - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_addflow_parse: " - "extr->ips cleaned up and freed.\n"); - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; -#ifdef CONFIG_IPSEC_DEBUG - char buf1[64], buf2[64]; -#endif /* CONFIG_IPSEC_DEBUG */ - struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_reply = NULL; - struct socket_list *pfkey_socketsp; - uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; - ip_address srcflow, dstflow, srcmask, dstmask; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: .\n"); - - pfkey_extensions_init(extensions_reply); - - memset((caddr_t)&srcflow, 0, sizeof(srcflow)); - memset((caddr_t)&dstflow, 0, sizeof(dstflow)); - memset((caddr_t)&srcmask, 0, sizeof(srcmask)); - memset((caddr_t)&dstmask, 0, sizeof(dstmask)); - - if(!extr || !(extr->ips)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: " - "extr, or extr->ips is NULL, fatal\n"); - SENDERR(EINVAL); - } - - if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: " - "CLEARFLOW flag set, calling cleareroutes.\n"); - if ((error = ipsec_cleareroutes())) - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: " - "cleareroutes returned %d.\n", error); - SENDERR(-error); - } else { - struct sk_buff *first = NULL, *last = NULL; - - if(!(extr->eroute)) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: " - "extr->eroute is NULL, fatal.\n"); - SENDERR(EINVAL); - } - - srcflow.u.v4.sin_family = AF_INET; - dstflow.u.v4.sin_family = AF_INET; - srcmask.u.v4.sin_family = AF_INET; - dstmask.u.v4.sin_family = AF_INET; - srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; - dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; - srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; - dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; - -#ifdef CONFIG_IPSEC_DEBUG - if (debug_pfkey) { - subnettoa(extr->eroute->er_eaddr.sen_ip_src, - extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); - subnettoa(extr->eroute->er_eaddr.sen_ip_dst, - extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: " - "calling breakeroute for %s->%s\n", - buf1, buf2); - } -#endif /* CONFIG_IPSEC_DEBUG */ - error = ipsec_breakroute(&(extr->eroute->er_eaddr), - &(extr->eroute->er_emask), - &first, &last); - if(error) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: " - "breakeroute returned %d. first=0p%p, last=0p%p\n", - error, - first, - last); - } - if(first != NULL) { - ipsec_kfree_skb(first); - } - if(last != NULL) { - ipsec_kfree_skb(last); - } - if(error) { - SENDERR(-error); - } - } - - if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], - SADB_X_DELFLOW, - satype, - 0, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, - ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), - extensions_reply) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - extr->ips->ips_replaywin, - extr->ips->ips_state, - extr->ips->ips_authalg, - extr->ips->ips_encalg, - extr->ips->ips_flags, - extr->ips->ips_ref), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], - SADB_X_EXT_ADDRESS_SRC_FLOW, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&srcflow), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], - SADB_X_EXT_ADDRESS_DST_FLOW, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&dstflow), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], - SADB_X_EXT_ADDRESS_SRC_MASK, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&srcmask), - extensions_reply) - && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], - SADB_X_EXT_ADDRESS_DST_MASK, - 0, /*extr->ips->ips_said.proto,*/ - 0, - (struct sockaddr*)&dstmask), - extensions_reply) - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " - "failed to build the x_delflow reply message extensions\n"); - SENDERR(-error); - } - - if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " - "failed to build the x_delflow reply message\n"); - SENDERR(-error); - } - - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " - "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " - "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_delflow_parse: " - "extr->ips cleaned up and freed.\n"); - - errlab: - if (pfkey_reply) { - pfkey_msg_free(&pfkey_reply); - } - pfkey_extensions_free(extensions_reply); - return error; -} - -DEBUG_NO_STATIC int -pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - int error = 0; - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_x_msg_debug_parse: .\n"); - -/* errlab:*/ - return error; -} - -/* pfkey_expire expects the ipsec_sa table to be locked before being called. */ -int -pfkey_expire(struct ipsec_sa *ipsp, int hard) -{ - struct sadb_ext *extensions[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_msg = NULL; - struct socket_list *pfkey_socketsp; - int error = 0; - uint8_t satype; - - pfkey_extensions_init(extensions); - - if(!(satype = proto2satype(ipsp->ips_said.proto))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_expire: " - "satype lookup for protocol %d lookup failed.\n", - ipsp->ips_said.proto); - SENDERR(EINVAL); - } - - if(!pfkey_open_sockets) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " - "no sockets listening.\n"); - SENDERR(EPROTONOSUPPORT); - } - - if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], - SADB_EXPIRE, - satype, - 0, - ++pfkey_msg_seq, - 0), - extensions) - && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA], - SADB_EXT_SA, - ipsp->ips_said.spi, - ipsp->ips_replaywin, - ipsp->ips_state, - ipsp->ips_authalg, - ipsp->ips_encalg, - ipsp->ips_flags, - ipsp->ips_ref), - extensions) - && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT], - SADB_EXT_LIFETIME_CURRENT, - ipsp->ips_life.ipl_allocations.ipl_count, - ipsp->ips_life.ipl_bytes.ipl_count, - ipsp->ips_life.ipl_addtime.ipl_count, - ipsp->ips_life.ipl_usetime.ipl_count, - ipsp->ips_life.ipl_packets.ipl_count), - extensions) - && (hard ? - pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD], - SADB_EXT_LIFETIME_HARD, - ipsp->ips_life.ipl_allocations.ipl_hard, - ipsp->ips_life.ipl_bytes.ipl_hard, - ipsp->ips_life.ipl_addtime.ipl_hard, - ipsp->ips_life.ipl_usetime.ipl_hard, - ipsp->ips_life.ipl_packets.ipl_hard), - extensions) - : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT], - SADB_EXT_LIFETIME_SOFT, - ipsp->ips_life.ipl_allocations.ipl_soft, - ipsp->ips_life.ipl_bytes.ipl_soft, - ipsp->ips_life.ipl_addtime.ipl_soft, - ipsp->ips_life.ipl_usetime.ipl_soft, - ipsp->ips_life.ipl_packets.ipl_soft), - extensions)) - && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - 0, /* ipsp->ips_said.proto, */ - 0, - ipsp->ips_addr_s), - extensions) - && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - 0, /* ipsp->ips_said.proto, */ - 0, - ipsp->ips_addr_d), - extensions))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " - "failed to build the expire message extensions\n"); - spin_unlock(&tdb_lock); - goto errlab; - } - - if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " - "failed to build the expire message\n"); - SENDERR(-error); - } - - for(pfkey_socketsp = pfkey_open_sockets; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " - "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " - "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - ipsp->ips_said.proto, - pfkey_socketsp->socketp); - } - - errlab: - if (pfkey_msg) { - pfkey_msg_free(&pfkey_msg); - } - pfkey_extensions_free(extensions); - return error; -} - -int -pfkey_acquire(struct ipsec_sa *ipsp) -{ - struct sadb_ext *extensions[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_msg = NULL; - struct socket_list *pfkey_socketsp; - int error = 0; - struct sadb_comb comb[] = { - /* auth; encrypt; flags; */ - /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */ - /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */ - /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */ - /* soft_packets; hard_packets; */ - { SADB_AALG_MD5_HMAC, SADB_EALG_3DES_CBC, SADB_SAFLAGS_PFS, - 128, 128, 168, 168, - 0, 0, 0, 0, 0, - 57600, 86400, 57600, 86400, - 0, 0 }, - { SADB_AALG_SHA1_HMAC, SADB_EALG_3DES_CBC, SADB_SAFLAGS_PFS, - 160, 160, 168, 168, - 0, 0, 0, 0, 0, - 57600, 86400, 57600, 86400, - 0, 0 } - }; - - /* XXX This should not be hard-coded. It should be taken from the spdb */ - uint8_t satype = SADB_SATYPE_ESP; - - pfkey_extensions_init(extensions); - - if((satype == 0) || (satype > SADB_SATYPE_MAX)) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " - "SAtype=%d unspecified or unknown.\n", - satype); - SENDERR(EINVAL); - } - - if(!(pfkey_registered_sockets[satype])) { - KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " - "no sockets registered for SAtype=%d(%s).\n", - satype, - satype2name(satype)); - SENDERR(EPROTONOSUPPORT); - } - - if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], - SADB_ACQUIRE, - satype, - 0, - ++pfkey_msg_seq, - 0), - extensions) - && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - ipsp->ips_said.proto, - 0, - ipsp->ips_addr_s), - extensions) - && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - ipsp->ips_said.proto, - 0, - ipsp->ips_addr_d), - extensions) -#if 0 - && (ipsp->ips_addr_p - ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY], - SADB_EXT_ADDRESS_PROXY, - ipsp->ips_said.proto, - 0, - ipsp->ips_addr_p), - extensions) : 1) -#endif - && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED - ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC], - SADB_EXT_IDENTITY_SRC, - ipsp->ips_ident_s.type, - ipsp->ips_ident_s.id, - ipsp->ips_ident_s.len, - ipsp->ips_ident_s.data), - extensions) : 1) - - && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED - ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST], - SADB_EXT_IDENTITY_DST, - ipsp->ips_ident_d.type, - ipsp->ips_ident_d.id, - ipsp->ips_ident_d.len, - ipsp->ips_ident_d.data), - extensions) : 1) -#if 0 - /* FIXME: This won't work yet because I have not finished - it. */ - && (ipsp->ips_sens_ - ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY], - ipsp->ips_sens_dpd, - ipsp->ips_sens_sens_level, - ipsp->ips_sens_sens_len, - ipsp->ips_sens_sens_bitmap, - ipsp->ips_sens_integ_level, - ipsp->ips_sens_integ_len, - ipsp->ips_sens_integ_bitmap), - extensions) : 1) -#endif - && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL], - 64, /* replay */ - sizeof(comb)/sizeof(struct sadb_comb), - &(comb[0])), - extensions) - )) { - KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " - "failed to build the acquire message extensions\n"); - SENDERR(-error); - } - - if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { - KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " - "failed to build the acquire message\n"); - SENDERR(-error); - } - -#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0 - if(sysctl_ipsec_regress_pfkey_lossage) { - return(0); - } -#endif - - /* this should go to all registered sockets for that satype only */ - for(pfkey_socketsp = pfkey_registered_sockets[satype]; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { - KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " - "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " - "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - errlab: - if (pfkey_msg) { - pfkey_msg_free(&pfkey_msg); - } - pfkey_extensions_free(extensions); - return error; -} - -#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -int -pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr, - __u16 sport) -{ - struct sadb_ext *extensions[SADB_EXT_MAX+1]; - struct sadb_msg *pfkey_msg = NULL; - struct socket_list *pfkey_socketsp; - int error = 0; - uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0; - - /* Construct SADB_X_NAT_T_NEW_MAPPING message */ - - pfkey_extensions_init(extensions); - - if((satype == 0) || (satype > SADB_SATYPE_MAX)) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " - "SAtype=%d unspecified or unknown.\n", - satype); - SENDERR(EINVAL); - } - - if(!(pfkey_registered_sockets[satype])) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " - "no sockets registered for SAtype=%d(%s).\n", - satype, - satype2name(satype)); - SENDERR(EPROTONOSUPPORT); - } - - if (!(pfkey_safe_build - (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING, - satype, 0, ++pfkey_msg_seq, 0), extensions) - /* SA */ - && pfkey_safe_build - (error = pfkey_sa_build(&extensions[SADB_EXT_SA], - SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions) - /* ADDRESS_SRC = old addr */ - && pfkey_safe_build - (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s), - extensions) - /* NAT_T_SPORT = old port */ - && pfkey_safe_build - (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT], - SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions) - /* ADDRESS_DST = new addr */ - && pfkey_safe_build - (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions) - /* NAT_T_DPORT = new port */ - && pfkey_safe_build - (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT], - SADB_X_EXT_NAT_T_DPORT, sport), extensions) - )) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " - "failed to build the nat_t_new_mapping message extensions\n"); - SENDERR(-error); - } - - if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " - "failed to build the nat_t_new_mapping message\n"); - SENDERR(-error); - } - - /* this should go to all registered sockets for that satype only */ - for(pfkey_socketsp = pfkey_registered_sockets[satype]; - pfkey_socketsp; - pfkey_socketsp = pfkey_socketsp->next) { - if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " - "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp, - error); - SENDERR(-error); - } - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " - "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n", - satype, - satype2name(satype), - pfkey_socketsp->socketp); - } - - errlab: - if (pfkey_msg) { - pfkey_msg_free(&pfkey_msg); - } - pfkey_extensions_free(extensions); - return error; -} - -DEBUG_NO_STATIC int -pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -{ - /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */ - return -EINVAL; -} -#endif - -DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) = -{ - NULL, /* pfkey_msg_process, */ - pfkey_sa_process, - pfkey_lifetime_process, - pfkey_lifetime_process, - pfkey_lifetime_process, - pfkey_address_process, - pfkey_address_process, - pfkey_address_process, - pfkey_key_process, - pfkey_key_process, - pfkey_ident_process, - pfkey_ident_process, - pfkey_sens_process, - pfkey_prop_process, - pfkey_supported_process, - pfkey_supported_process, - pfkey_spirange_process, - pfkey_x_kmprivate_process, - pfkey_x_satype_process, - pfkey_sa_process, - pfkey_address_process, - pfkey_address_process, - pfkey_address_process, - pfkey_address_process, - pfkey_address_process, - pfkey_x_debug_process, - pfkey_x_protocol_process -#ifdef CONFIG_IPSEC_NAT_TRAVERSAL - , - pfkey_x_nat_t_type_process, - pfkey_x_nat_t_port_process, - pfkey_x_nat_t_port_process, - pfkey_address_process -#endif -}; - - -DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr) - = -{ - NULL, /* RESERVED */ - pfkey_getspi_parse, - pfkey_update_parse, - pfkey_add_parse, - pfkey_delete_parse, - pfkey_get_parse, - pfkey_acquire_parse, - pfkey_register_parse, - pfkey_expire_parse, - pfkey_flush_parse, - pfkey_dump_parse, - pfkey_x_promisc_parse, - pfkey_x_pchange_parse, - pfkey_x_grpsa_parse, - pfkey_x_addflow_parse, - pfkey_x_delflow_parse, - pfkey_x_msg_debug_parse -#ifdef CONFIG_IPSEC_NAT_TRAVERSAL - , pfkey_x_nat_t_new_mapping_parse -#endif -}; - -int -pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr, - struct sadb_msg **pfkey_reply) -{ - struct sadb_ext *extensions[SADB_EXT_MAX+1]; - int error = 0; - int msg_type = pfkey_msg->sadb_msg_type; - int seq = pfkey_msg->sadb_msg_seq; - - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " - "building reply with type: %d\n", - msg_type); - pfkey_extensions_init(extensions); - if (!extr || !extr->ips) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " - "bad ipsec_sa passed\n"); - return EINVAL; - } - error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0], - msg_type, - proto2satype(extr->ips->ips_said.proto), - 0, - seq, - pfkey_msg->sadb_msg_pid), - extensions) && - (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & - 1 << SADB_EXT_SA) - || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA], - SADB_EXT_SA, - extr->ips->ips_said.spi, - extr->ips->ips_replaywin, - extr->ips->ips_state, - extr->ips->ips_authalg, - extr->ips->ips_encalg, - extr->ips->ips_flags, - extr->ips->ips_ref), - extensions)) && - (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & - 1 << SADB_EXT_LIFETIME_CURRENT) - || pfkey_safe_build(pfkey_lifetime_build(&extensions - [SADB_EXT_LIFETIME_CURRENT], - SADB_EXT_LIFETIME_CURRENT, - extr->ips->ips_life.ipl_allocations.ipl_count, - extr->ips->ips_life.ipl_bytes.ipl_count, - extr->ips->ips_life.ipl_addtime.ipl_count, - extr->ips->ips_life.ipl_usetime.ipl_count, - extr->ips->ips_life.ipl_packets.ipl_count), - extensions)) && - (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & - 1 << SADB_EXT_ADDRESS_SRC) - || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], - SADB_EXT_ADDRESS_SRC, - extr->ips->ips_said.proto, - 0, - extr->ips->ips_addr_s), - extensions)) && - (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & - 1 << SADB_EXT_ADDRESS_DST) - || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], - SADB_EXT_ADDRESS_DST, - extr->ips->ips_said.proto, - 0, - extr->ips->ips_addr_d), - extensions)); - - if (error == 0) { - KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " - "building extensions failed\n"); - return EINVAL; - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_build_reply: " - "built extensions, proceed to build the message\n"); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_build_reply: " - "extensions[1]=0p%p\n", - extensions[1]); - error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT); - pfkey_extensions_free(extensions); - - return error; -} - -int -pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg, - struct sadb_msg **pfkey_reply) -{ - int error = 0; - int i; - struct sadb_ext *extensions[SADB_EXT_MAX+1]; - struct pfkey_extracted_data extr = {NULL, NULL, NULL}; - - pfkey_extensions_init(extensions); - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", - pfkey_msg->sadb_msg_version, - pfkey_msg->sadb_msg_type, - pfkey_msg->sadb_msg_errno, - pfkey_msg->sadb_msg_satype, - satype2name(pfkey_msg->sadb_msg_satype), - pfkey_msg->sadb_msg_len, - pfkey_msg->sadb_msg_reserved, - pfkey_msg->sadb_msg_seq, - pfkey_msg->sadb_msg_pid); - - extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */ - if(extr.ips == NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "memory allocation error.\n"); - SENDERR(-error); - } - - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "allocated extr->ips=0p%p.\n", - extr.ips); - - if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "satype %d > max %d\n", - pfkey_msg->sadb_msg_satype, - SADB_SATYPE_MAX); - SENDERR(EINVAL); - } - - switch(pfkey_msg->sadb_msg_type) { - case SADB_GETSPI: - case SADB_UPDATE: - case SADB_ADD: - case SADB_DELETE: - case SADB_X_GRPSA: - case SADB_X_ADDFLOW: - if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "satype %d lookup failed.\n", - pfkey_msg->sadb_msg_satype); - SENDERR(EINVAL); - } else { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "satype %d lookups to proto=%d.\n", - pfkey_msg->sadb_msg_satype, - extr.ips->ips_said.proto); - } - break; - default: - break; - } - - /* The NULL below causes the default extension parsers to be used */ - /* Parse the extensions */ - if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN))) - { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "message parsing failed with error %d.\n", - error); - SENDERR(-error); - } - - /* Process the extensions */ - for(i=1; i <= SADB_EXT_MAX;i++) { - if(extensions[i] != NULL) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "processing ext %d 0p%p with processor 0p%p.\n", - i, extensions[i], ext_processors[i]); - if((error = ext_processors[i](extensions[i], &extr))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "extension processing for type %d failed with error %d.\n", - i, - error); - SENDERR(-error); - } - - } - - } - - /* Parse the message types */ - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "parsing message type %d(%s) with msg_parser 0p%p.\n", - pfkey_msg->sadb_msg_type, - pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), - msg_parsers[pfkey_msg->sadb_msg_type]); - if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) { - KLIPS_PRINT(debug_pfkey, - "klips_debug:pfkey_msg_interp: " - "message parsing failed with error %d.\n", - error); - SENDERR(-error); - } - -#if 0 - error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply); - if (error) { - *pfkey_reply = NULL; - } -#endif - errlab: - if(extr.ips != NULL) { - ipsec_sa_wipe(extr.ips); - } - if(extr.ips2 != NULL) { - ipsec_sa_wipe(extr.ips2); - } - if (extr.eroute != NULL) { - kfree(extr.eroute); - } - return(error); -} - |