📄 pfkey_v2_parser.c
字号:
} else #endif /* CONFIG_IPSEC_ALG */ switch(tdbp->tdb_authalg) {# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 case AH_MD5: { MD5_CTX *ictx; MD5_CTX *octx; if(tdbp->tdb_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"*/, tdbp->tdb_key_bits_a, AHMD596_KLEN * 8); SENDERR(EINVAL); } # if 0 /* we don't really want to print these unless there are really big problems */ 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 *)(tdbp->tdb_key_a))+0)), ntohl(*(((__u32 *)(tdbp->tdb_key_a))+1)), ntohl(*(((__u32 *)(tdbp->tdb_key_a))+2)), ntohl(*(((__u32 *)(tdbp->tdb_key_a))+3)));# endif tdbp->tdb_auth_bits = AHMD596_ALEN * 8; /* save the pointer to the key material */ akp = tdbp->tdb_key_a; aks = tdbp->tdb_key_a_size; if((tdbp->tdb_key_a = (caddr_t) kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { tdbp->tdb_key_a = akp; SENDERR(ENOMEM); } tdbp->tdb_key_a_size = sizeof(struct md5_ctx); for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) { kb[i] = akp[i] ^ HMAC_IPAD; } for (; i < AHMD596_BLKLEN; i++) { kb[i] = HMAC_IPAD; } ictx = &(((struct md5_ctx*)(tdbp->tdb_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*)(tdbp->tdb_key_a))->octx); MD5Init(octx); MD5Update(octx, kb, AHMD596_BLKLEN); # if 0 /* we don't really want to print these unless there are really big problems */ 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 /* 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(tdbp->tdb_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"*/, tdbp->tdb_key_bits_a, AHSHA196_KLEN * 8); SENDERR(EINVAL); } # if 0 /* we don't really want to print these unless there are really big problems */ 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 *)tdbp->tdb_key_a)+0)), ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)), ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)), ntohl(*(((__u32 *)tdbp->tdb_key_a)+3)));# endif tdbp->tdb_auth_bits = AHSHA196_ALEN * 8; /* save the pointer to the key material */ akp = tdbp->tdb_key_a; aks = tdbp->tdb_key_a_size; if((tdbp->tdb_key_a = (caddr_t) kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { tdbp->tdb_key_a = akp; SENDERR(ENOMEM); } tdbp->tdb_key_a_size = sizeof(struct sha1_ctx); for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) { kb[i] = akp[i] ^ HMAC_IPAD; } for (; i < AHMD596_BLKLEN; i++) { kb[i] = HMAC_IPAD; } ictx = &(((struct sha1_ctx*)(tdbp->tdb_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*)(tdbp->tdb_key_a))->octx; SHA1Init(octx); SHA1Update(octx, kb, AHSHA196_BLKLEN); # if 0 /* we don't really want to print these unless there are really big problems */ 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 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", tdbp->tdb_authalg); SENDERR(EINVAL); } } break;#endif /* !CONFIG_IPSEC_ESP */#ifdef CONFIG_IPSEC_IPCOMP case IPPROTO_COMP: tdbp->tdb_comp_adapt_tries = 0; tdbp->tdb_comp_adapt_skip = 0; tdbp->tdb_comp_ratio_cbytes = 0; tdbp->tdb_comp_ratio_dbytes = 0; break;#endif /* CONFIG_IPSEC_IPCOMP */ default: KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_ipsec_sa_init: " "proto=%d unknown.\n", tdbp->tdb_said.proto); SENDERR(EINVAL); } errlab: return(error);}intpfkey_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 intpfkey_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 *tdbq; 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 || !extr->tdb) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " "error, extr or extr->tdb 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->tdb->tdb_said.spi = maxspi; if((tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said)))) { sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " "EMT_GETSPI found an old Tunnel Descriptor Block 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 ) { get_random_bytes((void*) &(rand_val), /* sizeof(extr->tdb->tdb_said.spi) */ ( (spi_diff < (2^8)) ? 1 : ( (spi_diff < (2^16)) ? 2 : ( (spi_diff < (2^24)) ? 3 : 4 ) ) ) ); extr->tdb->tdb_said.spi = htonl(ntohl(minspi) + (rand_val % (spi_diff + 1))); i++; tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said)); if(!tdbq) { found_avail = 1; } } } sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); if (!found_avail) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " "found an old Tunnel Descriptor Block for SA: %s, delete it first.\n", sa_len ? sa : " (error)"); SENDERR(EEXIST); } if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) { extr->tdb->tdb_flags |= EMT_INBOUND; } KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " "existing Tunnel Descriptor Block not found (this is good) for SA: %s, %s-bound, allocating.\n", sa_len ? sa : " (error)", extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out"); /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/ extr->tdb->tdb_rcvif = NULL; extr->tdb->ips_life.ipl_addtime.ipl_count = jiffies/HZ; extr->tdb->tdb_state = SADB_SASTATE_LARVAL; if(!extr->tdb->ips_life.ipl_allocations.ipl_count) { extr->tdb->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_build(&extensions_reply[SADB_EXT_SA], SADB_EXT_SA, extr->tdb->tdb_said.spi, 0, SADB_SASTATE_LARVAL, 0, 0, 0), extensions_reply) && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], SADB_EXT_ADDRESS_SRC, 0, /*extr->tdb->tdb_said.proto,*/ 0, extr->tdb->tdb_addr_s), extensions_reply) && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], SADB_EXT_ADDRESS_DST, 0, /*extr->tdb->tdb_said.proto,*/ 0, extr->tdb->tdb_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=%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=%p succeeded.\n", satype, satype2name(satype), pfkey_socketsp->socketp); } if((error = ipsec_sa_put(extr->tdb))) { 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->tdb = 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 intpfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr){ int error = 0; struct ipsec_sa* tdbq; 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_tdb_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 || !extr->tdb) { KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " "error, extr or extr->tdb pointer NULL\n"); SENDERR(EINVAL); } sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); spin_lock_bh(&tdb_lock);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -