1/* 2 * RFC2367 PF_KEYv2 Key management API message parser 3 * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * for more details. 14 * 15 * RCSID $Id: pfkey_v2_parse.c,v 1.53 2003/01/30 02:32:09 rgb Exp $ 16 */ 17 18/* 19 * Template from klips/net/ipsec/ipsec/ipsec_parser.c. 20 */ 21 22char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.53 2003/01/30 02:32:09 rgb Exp $"; 23 24/* 25 * Some ugly stuff to allow consistent debugging code for use in the 26 * kernel and in user space 27*/ 28 29#ifdef __KERNEL__ 30 31# include <linux/kernel.h> /* for printk */ 32 33#include "freeswan/ipsec_kversion.h" /* for malloc switch */ 34 35# ifdef MALLOC_SLAB 36# include <linux/slab.h> /* kmalloc() */ 37# else /* MALLOC_SLAB */ 38# include <linux/malloc.h> /* kmalloc() */ 39# endif /* MALLOC_SLAB */ 40# include <linux/errno.h> /* error codes */ 41# include <linux/types.h> /* size_t */ 42# include <linux/interrupt.h> /* mark_bh */ 43 44# include <linux/netdevice.h> /* struct device, and other headers */ 45# include <linux/etherdevice.h> /* eth_type_trans */ 46# include <linux/ip.h> /* struct iphdr */ 47# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 48# include <linux/ipv6.h> /* struct ipv6hdr */ 49# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ 50extern int debug_pfkey; 51 52# include <freeswan.h> 53 54#include "freeswan/ipsec_encap.h" 55 56#else /* __KERNEL__ */ 57 58# include <sys/types.h> 59# include <linux/types.h> 60# include <linux/errno.h> 61 62# include <freeswan.h> 63# include "programs/pluto/constants.h" 64# include "programs/pluto/defs.h" /* for PRINTF_LIKE */ 65# include "programs/pluto/log.h" /* for debugging and DBG_log */ 66 67/* #define PLUTO */ 68 69# ifdef PLUTO 70# define DEBUGGING(level, args...) { DBG_log("pfkey_lib_debug:" args); } 71# else 72# define DEBUGGING(level, args...) if(pfkey_lib_debug & level) { printf("pfkey_lib_debug:" args); } else { ; } 73# endif 74 75#endif /* __KERNEL__ */ 76 77 78#include <pfkeyv2.h> 79#include <pfkey.h> 80 81#ifdef __KERNEL__ 82# include "freeswan/ipsec_netlink.h" /* KLIPS_PRINT */ 83extern int sysctl_ipsec_debug_verbose; 84# define DEBUGGING(level, args...) \ 85 KLIPS_PRINT( \ 86 ((debug_pfkey & level & (PF_KEY_DEBUG_PARSE_STRUCT | PF_KEY_DEBUG_PARSE_PROBLEM)) \ 87 || (sysctl_ipsec_debug_verbose && (debug_pfkey & level & PF_KEY_DEBUG_PARSE_FLOW))) \ 88 , "klips_debug:" args) 89#endif /* __KERNEL__ */ 90#include "freeswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */ 91 92 93#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) 94 95struct satype_tbl { 96 uint8_t proto; 97 uint8_t satype; 98 char* name; 99} static satype_tbl[] = { 100#ifdef __KERNEL__ 101 { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" }, 102 { IPPROTO_AH, SADB_SATYPE_AH, "AH" }, 103 { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, 104#ifdef CONFIG_IPSEC_IPCOMP 105 { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" }, 106#endif /* CONFIG_IPSEC_IPCOMP */ 107 { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" }, 108#else /* __KERNEL__ */ 109 { SA_ESP, SADB_SATYPE_ESP, "ESP" }, 110 { SA_AH, SADB_SATYPE_AH, "AH" }, 111 { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, 112 { SA_COMP, SADB_X_SATYPE_COMP, "COMP" }, 113 { SA_INT, SADB_X_SATYPE_INT, "INT" }, 114#endif /* __KERNEL__ */ 115 { 0, 0, "UNKNOWN" } 116}; 117 118uint8_t 119satype2proto(uint8_t satype) 120{ 121 int i =0; 122 123 while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { 124 i++; 125 } 126 return satype_tbl[i].proto; 127} 128 129uint8_t 130proto2satype(uint8_t proto) 131{ 132 int i = 0; 133 134 while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { 135 i++; 136 } 137 return satype_tbl[i].satype; 138} 139 140char* 141satype2name(uint8_t satype) 142{ 143 int i = 0; 144 145 while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { 146 i++; 147 } 148 return satype_tbl[i].name; 149} 150 151char* 152proto2name(uint8_t proto) 153{ 154 int i = 0; 155 156 while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { 157 i++; 158 } 159 return satype_tbl[i].name; 160} 161 162/* Default extension parsers taken from the KLIPS code */ 163 164DEBUG_NO_STATIC int 165pfkey_sa_parse(struct sadb_ext *pfkey_ext) 166{ 167 int error = 0; 168 struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; 169#if 0 170 struct sadb_sa sav2; 171#endif 172 173 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 174 "pfkey_sa_parse: entry\n"); 175 /* sanity checks... */ 176 if(!pfkey_sa) { 177 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 178 "pfkey_sa_parse: " 179 "NULL pointer passed in.\n"); 180 SENDERR(EINVAL); 181 } 182 183#if 0 184 /* check if this structure is short, and if so, fix it up. 185 * XXX this is NOT the way to do things. 186 */ 187 if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) { 188 189 /* yes, so clear out a temporary structure, and copy first */ 190 memset(&sav2, 0, sizeof(sav2)); 191 memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1)); 192 sav2.sadb_x_sa_ref=-1; 193 sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN; 194 195 pfkey_sa = &sav2; 196 } 197#endif 198 199 200 if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) { 201 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 202 "pfkey_sa_parse: " 203 "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n", 204 pfkey_sa->sadb_sa_len, 205 (int)sizeof(struct sadb_sa)); 206 SENDERR(EINVAL); 207 } 208 209 if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) { 210 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 211 "pfkey_sa_parse: " 212 "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n", 213 pfkey_sa->sadb_sa_encrypt, 214 SADB_EALG_MAX); 215 SENDERR(EINVAL); 216 } 217 218 if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) { 219 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 220 "pfkey_sa_parse: " 221 "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n", 222 pfkey_sa->sadb_sa_auth, 223 SADB_AALG_MAX); 224 SENDERR(EINVAL); 225 } 226 227 if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) { 228 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 229 "pfkey_sa_parse: " 230 "state=%d exceeds MAX=%d.\n", 231 pfkey_sa->sadb_sa_state, 232 SADB_SASTATE_MAX); 233 SENDERR(EINVAL); 234 } 235 236 if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) { 237 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 238 "pfkey_sa_parse: " 239 "state=%d is DEAD=%d.\n", 240 pfkey_sa->sadb_sa_state, 241 SADB_SASTATE_DEAD); 242 SENDERR(EINVAL); 243 } 244 245 if(pfkey_sa->sadb_sa_replay > 64) { 246 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 247 "pfkey_sa_parse: " 248 "replay window size: %d -- must be 0 <= size <= 64\n", 249 pfkey_sa->sadb_sa_replay); 250 SENDERR(EINVAL); 251 } 252 253 if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) || 254 (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2))) 255 { 256 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 257 "pfkey_sa_parse: " 258 "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n", 259 pfkey_sa->sadb_sa_exttype, 260 SADB_EXT_SA, 261 SADB_X_EXT_SA2); 262 SENDERR(EINVAL); 263 } 264 265 if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) { 266 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 267 "pfkey_sa_parse: " 268 "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n", 269 pfkey_sa->sadb_x_sa_ref, 270 IPSEC_SAREF_NULL, 271 IPSEC_SA_REF_TABLE_NUM_ENTRIES); 272 SENDERR(EINVAL); 273 } 274 275 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 276 "pfkey_sa_parse: " 277 "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n", 278 pfkey_sa->sadb_sa_len, 279 pfkey_sa->sadb_sa_exttype, 280 pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype), 281 (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi), 282 pfkey_sa->sadb_sa_replay, 283 pfkey_sa->sadb_sa_state, 284 pfkey_sa->sadb_sa_auth, 285 pfkey_sa->sadb_sa_encrypt, 286 pfkey_sa->sadb_sa_flags, 287 pfkey_sa->sadb_x_sa_ref); 288 289 errlab: 290 return error; 291} 292 293DEBUG_NO_STATIC int 294pfkey_lifetime_parse(struct sadb_ext *pfkey_ext) 295{ 296 int error = 0; 297 struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; 298 299 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 300 "pfkey_lifetime_parse:enter\n"); 301 /* sanity checks... */ 302 if(!pfkey_lifetime) { 303 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 304 "pfkey_lifetime_parse: " 305 "NULL pointer passed in.\n"); 306 SENDERR(EINVAL); 307 } 308 309 if(pfkey_lifetime->sadb_lifetime_len != 310 sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) { 311 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 312 "pfkey_lifetime_parse: " 313 "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n", 314 pfkey_lifetime->sadb_lifetime_len, 315 (int)sizeof(struct sadb_lifetime)); 316 SENDERR(EINVAL); 317 } 318 319 if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) && 320 (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) && 321 (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) { 322 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 323 "pfkey_lifetime_parse: " 324 "unexpected ext_type=%d.\n", 325 pfkey_lifetime->sadb_lifetime_exttype); 326 SENDERR(EINVAL); 327 } 328 329 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 330 "pfkey_lifetime_parse: " 331 "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n", 332 pfkey_lifetime->sadb_lifetime_exttype, 333 pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype), 334 pfkey_lifetime->sadb_lifetime_allocations, 335 (unsigned)pfkey_lifetime->sadb_lifetime_bytes, 336 (unsigned)pfkey_lifetime->sadb_lifetime_addtime, 337 (unsigned)pfkey_lifetime->sadb_lifetime_usetime, 338 pfkey_lifetime->sadb_x_lifetime_packets); 339errlab: 340 return error; 341} 342 343DEBUG_NO_STATIC int 344pfkey_address_parse(struct sadb_ext *pfkey_ext) 345{ 346 int error = 0; 347 int saddr_len = 0; 348 struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; 349 struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); 350 char ipaddr_txt[ADDRTOT_BUF]; 351 352 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 353 "pfkey_address_parse:enter\n"); 354 /* sanity checks... */ 355 if(!pfkey_address) { 356 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 357 "pfkey_address_parse: " 358 "NULL pointer passed in.\n"); 359 SENDERR(EINVAL); 360 } 361 362 if(pfkey_address->sadb_address_len < 363 (sizeof(struct sadb_address) + sizeof(struct sockaddr))/ 364 IPSEC_PFKEYv2_ALIGN) { 365 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 366 "pfkey_address_parse: " 367 "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", 368 pfkey_address->sadb_address_len, 369 (int)sizeof(struct sadb_address), 370 (int)sizeof(struct sockaddr)); 371 SENDERR(EINVAL); 372 } 373 374 if(pfkey_address->sadb_address_reserved) { 375 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 376 "pfkey_address_parse: " 377 "res=%d, must be zero.\n", 378 pfkey_address->sadb_address_reserved); 379 SENDERR(EINVAL); 380 } 381 382 switch(pfkey_address->sadb_address_exttype) { 383 case SADB_EXT_ADDRESS_SRC: 384 case SADB_EXT_ADDRESS_DST: 385 case SADB_EXT_ADDRESS_PROXY: 386 case SADB_X_EXT_ADDRESS_DST2: 387 case SADB_X_EXT_ADDRESS_SRC_FLOW: 388 case SADB_X_EXT_ADDRESS_DST_FLOW: 389 case SADB_X_EXT_ADDRESS_SRC_MASK: 390 case SADB_X_EXT_ADDRESS_DST_MASK: 391#ifdef NAT_TRAVERSAL 392 case SADB_X_EXT_NAT_T_OA: 393#endif 394 break; 395 default: 396 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 397 "pfkey_address_parse: " 398 "unexpected ext_type=%d.\n", 399 pfkey_address->sadb_address_exttype); 400 SENDERR(EINVAL); 401 } 402 403 switch(s->sa_family) { 404 case AF_INET: 405 saddr_len = sizeof(struct sockaddr_in); 406 sprintf(ipaddr_txt, "%d.%d.%d.%d" 407 , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF 408 , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF 409 , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF 410 , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF); 411 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 412 "pfkey_address_parse: " 413 "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n", 414 pfkey_address->sadb_address_exttype, 415 pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), 416 s->sa_family, 417 ipaddr_txt, 418 pfkey_address->sadb_address_proto, 419 ((struct sockaddr_in*)s)->sin_port); 420 break; 421 case AF_INET6: 422 saddr_len = sizeof(struct sockaddr_in6); 423 sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x" 424 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0]) 425 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1]) 426 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2]) 427 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3]) 428 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4]) 429 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5]) 430 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6]) 431 , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7])); 432 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 433 "pfkey_address_parse: " 434 "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n", 435 pfkey_address->sadb_address_exttype, 436 pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), 437 s->sa_family, 438 ipaddr_txt, 439 pfkey_address->sadb_address_proto, 440 ((struct sockaddr_in6*)s)->sin6_port); 441 break; 442 default: 443 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 444 "pfkey_address_parse: " 445 "s->sa_family=%d not supported.\n", 446 s->sa_family); 447 SENDERR(EPFNOSUPPORT); 448 } 449 450 if(pfkey_address->sadb_address_len != 451 DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) { 452 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 453 "pfkey_address_parse: " 454 "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", 455 pfkey_address->sadb_address_len, 456 (int)sizeof(struct sadb_address), 457 saddr_len); 458 SENDERR(EINVAL); 459 } 460 461 if(pfkey_address->sadb_address_prefixlen != 0) { 462 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 463 "pfkey_address_parse: " 464 "address prefixes not supported yet.\n"); 465 SENDERR(EAFNOSUPPORT); /* not supported yet */ 466 } 467 468 /* XXX check if port!=0 */ 469 470 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 471 "pfkey_address_parse: successful.\n"); 472 errlab: 473 return error; 474} 475 476DEBUG_NO_STATIC int 477pfkey_key_parse(struct sadb_ext *pfkey_ext) 478{ 479 int error = 0; 480 struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; 481 482 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 483 "pfkey_key_parse:enter\n"); 484 /* sanity checks... */ 485 486 if(!pfkey_key) { 487 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 488 "pfkey_key_parse: " 489 "NULL pointer passed in.\n"); 490 SENDERR(EINVAL); 491 } 492 493 if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) { 494 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 495 "pfkey_key_parse: " 496 "size wrong ext_len=%d, key_ext_len=%d.\n", 497 pfkey_key->sadb_key_len, 498 (int)sizeof(struct sadb_key)); 499 SENDERR(EINVAL); 500 } 501 502 if(!pfkey_key->sadb_key_bits) { 503 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 504 "pfkey_key_parse: " 505 "key length set to zero, must be non-zero.\n"); 506 SENDERR(EINVAL); 507 } 508 509 if(pfkey_key->sadb_key_len != 510 DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits, 511 PFKEYBITS)) { 512 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 513 "pfkey_key_parse: " 514 "key length=%d does not agree with extension length=%d.\n", 515 pfkey_key->sadb_key_bits, 516 pfkey_key->sadb_key_len); 517 SENDERR(EINVAL); 518 } 519 520 if(pfkey_key->sadb_key_reserved) { 521 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 522 "pfkey_key_parse: " 523 "res=%d, must be zero.\n", 524 pfkey_key->sadb_key_reserved); 525 SENDERR(EINVAL); 526 } 527 528 if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) || 529 (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) { 530 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 531 "pfkey_key_parse: " 532 "expecting extension type AUTH or ENCRYPT, got %d.\n", 533 pfkey_key->sadb_key_exttype); 534 SENDERR(EINVAL); 535 } 536 537 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 538 "pfkey_key_parse: " 539 "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n", 540 pfkey_key->sadb_key_len, 541 pfkey_key->sadb_key_exttype, 542 pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype), 543 pfkey_key->sadb_key_bits, 544 pfkey_key->sadb_key_reserved); 545 546errlab: 547 return error; 548} 549 550DEBUG_NO_STATIC int 551pfkey_ident_parse(struct sadb_ext *pfkey_ext) 552{ 553 int error = 0; 554 struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; 555 556 /* sanity checks... */ 557 if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { 558 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 559 "pfkey_ident_parse: " 560 "size wrong ext_len=%d, key_ext_len=%d.\n", 561 pfkey_ident->sadb_ident_len, 562 (int)sizeof(struct sadb_ident)); 563 SENDERR(EINVAL); 564 } 565 566 if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) { 567 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 568 "pfkey_ident_parse: " 569 "ident_type=%d out of range, must be less than %d.\n", 570 pfkey_ident->sadb_ident_type, 571 SADB_IDENTTYPE_MAX); 572 SENDERR(EINVAL); 573 } 574 575 if(pfkey_ident->sadb_ident_reserved) { 576 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 577 "pfkey_ident_parse: " 578 "res=%d, must be zero.\n", 579 pfkey_ident->sadb_ident_reserved); 580 SENDERR(EINVAL); 581 } 582 583 /* string terminator/padding must be zero */ 584 if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { 585 if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) { 586 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 587 "pfkey_ident_parse: " 588 "string padding must be zero, last is 0x%02x.\n", 589 *((char*)pfkey_ident + 590 pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)); 591 SENDERR(EINVAL); 592 } 593 } 594 595 if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) || 596 (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) { 597 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 598 "pfkey_key_parse: " 599 "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n", 600 pfkey_ident->sadb_ident_exttype); 601 SENDERR(EINVAL); 602 } 603 604errlab: 605 return error; 606} 607 608DEBUG_NO_STATIC int 609pfkey_sens_parse(struct sadb_ext *pfkey_ext) 610{ 611 int error = 0; 612 struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext; 613 614 /* sanity checks... */ 615 if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) { 616 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 617 "pfkey_sens_parse: " 618 "size wrong ext_len=%d, key_ext_len=%d.\n", 619 pfkey_sens->sadb_sens_len, 620 (int)sizeof(struct sadb_sens)); 621 SENDERR(EINVAL); 622 } 623 624 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 625 "pfkey_sens_parse: " 626 "Sorry, I can't parse exttype=%d yet.\n", 627 pfkey_ext->sadb_ext_type); 628#if 0 629 SENDERR(EINVAL); /* don't process these yet */ 630#endif 631 632errlab: 633 return error; 634} 635 636DEBUG_NO_STATIC int 637pfkey_prop_parse(struct sadb_ext *pfkey_ext) 638{ 639 int error = 0; 640 int i, num_comb; 641 struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext; 642 struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop)); 643 644 /* sanity checks... */ 645 if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) || 646 (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) { 647 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 648 "pfkey_prop_parse: " 649 "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n", 650 pfkey_prop->sadb_prop_len, 651 (int)sizeof(struct sadb_prop), 652 (int)sizeof(struct sadb_comb)); 653 SENDERR(EINVAL); 654 } 655 656 if(pfkey_prop->sadb_prop_replay > 64) { 657 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 658 "pfkey_prop_parse: " 659 "replay window size: %d -- must be 0 <= size <= 64\n", 660 pfkey_prop->sadb_prop_replay); 661 SENDERR(EINVAL); 662 } 663 664 for(i=0; i<3; i++) { 665 if(pfkey_prop->sadb_prop_reserved[i]) { 666 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 667 "pfkey_prop_parse: " 668 "res[%d]=%d, must be zero.\n", 669 i, pfkey_prop->sadb_prop_reserved[i]); 670 SENDERR(EINVAL); 671 } 672 } 673 674 num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb); 675 676 for(i = 0; i < num_comb; i++) { 677 if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) { 678 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 679 "pfkey_prop_parse: " 680 "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n", 681 i, 682 pfkey_comb->sadb_comb_auth, 683 SADB_AALG_MAX); 684 SENDERR(EINVAL); 685 } 686 687 if(pfkey_comb->sadb_comb_auth) { 688 if(!pfkey_comb->sadb_comb_auth_minbits) { 689 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 690 "pfkey_prop_parse: " 691 "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n", 692 i); 693 SENDERR(EINVAL); 694 } 695 if(!pfkey_comb->sadb_comb_auth_maxbits) { 696 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 697 "pfkey_prop_parse: " 698 "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n", 699 i); 700 SENDERR(EINVAL); 701 } 702 if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) { 703 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 704 "pfkey_prop_parse: " 705 "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n", 706 i, 707 pfkey_comb->sadb_comb_auth_minbits, 708 pfkey_comb->sadb_comb_auth_maxbits); 709 SENDERR(EINVAL); 710 } 711 } else { 712 if(pfkey_comb->sadb_comb_auth_minbits) { 713 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 714 "pfkey_prop_parse: " 715 "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n", 716 i, 717 pfkey_comb->sadb_comb_auth_minbits); 718 SENDERR(EINVAL); 719 } 720 if(pfkey_comb->sadb_comb_auth_maxbits) { 721 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 722 "pfkey_prop_parse: " 723 "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n", 724 i, 725 pfkey_comb->sadb_comb_auth_maxbits); 726 SENDERR(EINVAL); 727 } 728 } 729 730 if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) { 731 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 732 "pfkey_comb_parse: " 733 "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n", 734 i, 735 pfkey_comb->sadb_comb_encrypt, 736 SADB_EALG_MAX); 737 SENDERR(EINVAL); 738 } 739 740 if(pfkey_comb->sadb_comb_encrypt) { 741 if(!pfkey_comb->sadb_comb_encrypt_minbits) { 742 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 743 "pfkey_prop_parse: " 744 "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n", 745 i); 746 SENDERR(EINVAL); 747 } 748 if(!pfkey_comb->sadb_comb_encrypt_maxbits) { 749 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 750 "pfkey_prop_parse: " 751 "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n", 752 i); 753 SENDERR(EINVAL); 754 } 755 if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) { 756 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 757 "pfkey_prop_parse: " 758 "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n", 759 i, 760 pfkey_comb->sadb_comb_encrypt_minbits, 761 pfkey_comb->sadb_comb_encrypt_maxbits); 762 SENDERR(EINVAL); 763 } 764 } else { 765 if(pfkey_comb->sadb_comb_encrypt_minbits) { 766 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 767 "pfkey_prop_parse: " 768 "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n", 769 i, 770 pfkey_comb->sadb_comb_encrypt_minbits); 771 SENDERR(EINVAL); 772 } 773 if(pfkey_comb->sadb_comb_encrypt_maxbits) { 774 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 775 "pfkey_prop_parse: " 776 "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n", 777 i, 778 pfkey_comb->sadb_comb_encrypt_maxbits); 779 SENDERR(EINVAL); 780 } 781 } 782 783 /* XXX do sanity check on flags */ 784 785 if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) { 786 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 787 "pfkey_prop_parse: " 788 "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n", 789 i, 790 pfkey_comb->sadb_comb_soft_allocations, 791 pfkey_comb->sadb_comb_hard_allocations); 792 SENDERR(EINVAL); 793 } 794 795 if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) { 796 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 797 "pfkey_prop_parse: " 798 "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n", 799 i, 800 (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes, 801 (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes); 802 SENDERR(EINVAL); 803 } 804 805 if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) { 806 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 807 "pfkey_prop_parse: " 808 "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n", 809 i, 810 (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime, 811 (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime); 812 SENDERR(EINVAL); 813 } 814 815 if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) { 816 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 817 "pfkey_prop_parse: " 818 "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n", 819 i, 820 (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime, 821 (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime); 822 SENDERR(EINVAL); 823 } 824 825 if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) { 826 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 827 "pfkey_prop_parse: " 828 "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n", 829 i, 830 pfkey_comb->sadb_x_comb_soft_packets, 831 pfkey_comb->sadb_x_comb_hard_packets); 832 SENDERR(EINVAL); 833 } 834 835 if(pfkey_comb->sadb_comb_reserved) { 836 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 837 "pfkey_prop_parse: " 838 "comb[%d].res=%d, must be zero.\n", 839 i, 840 pfkey_comb->sadb_comb_reserved); 841 SENDERR(EINVAL); 842 } 843 pfkey_comb++; 844 } 845 846errlab: 847 return error; 848} 849 850DEBUG_NO_STATIC int 851pfkey_supported_parse(struct sadb_ext *pfkey_ext) 852{ 853 int error = 0; 854 unsigned int i, num_alg; 855 struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext; 856 struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported)); 857 858 /* sanity checks... */ 859 if((pfkey_supported->sadb_supported_len < 860 sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) || 861 (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - 862 sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) { 863 864 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 865 "pfkey_supported_parse: " 866 "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n", 867 pfkey_supported->sadb_supported_len, 868 (int)sizeof(struct sadb_supported), 869 (int)sizeof(struct sadb_alg)); 870 SENDERR(EINVAL); 871 } 872 873 if(pfkey_supported->sadb_supported_reserved) { 874 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 875 "pfkey_supported_parse: " 876 "res=%d, must be zero.\n", 877 pfkey_supported->sadb_supported_reserved); 878 SENDERR(EINVAL); 879 } 880 881 num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg); 882 883 for(i = 0; i < num_alg; i++) { 884 /* process algo description */ 885 if(pfkey_alg->sadb_alg_reserved) { 886 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 887 "pfkey_supported_parse: " 888 "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n", 889 i, 890 pfkey_alg->sadb_alg_id, 891 pfkey_alg->sadb_alg_ivlen, 892 pfkey_alg->sadb_alg_minbits, 893 pfkey_alg->sadb_alg_maxbits, 894 pfkey_alg->sadb_alg_reserved); 895 SENDERR(EINVAL); 896 } 897 898 /* XXX can alg_id auth/enc be determined from info given? 899 Yes, but OpenBSD's method does not iteroperate with rfc2367. 900 rgb, 2000-04-06 */ 901 902 switch(pfkey_supported->sadb_supported_exttype) { 903 case SADB_EXT_SUPPORTED_AUTH: 904 if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) { 905 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 906 "pfkey_supported_parse: " 907 "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n", 908 i, 909 pfkey_alg->sadb_alg_id, 910 SADB_AALG_MAX); 911 SENDERR(EINVAL); 912 } 913 break; 914 case SADB_EXT_SUPPORTED_ENCRYPT: 915 if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) { 916 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 917 "pfkey_supported_parse: " 918 "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", 919 i, 920 pfkey_alg->sadb_alg_id, 921 SADB_EALG_MAX); 922 SENDERR(EINVAL); 923 } 924 break; 925 default: 926 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 927 "pfkey_supported_parse: " 928 "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", 929 i, 930 pfkey_alg->sadb_alg_id, 931 SADB_EALG_MAX); 932 SENDERR(EINVAL); 933 } 934 pfkey_alg++; 935 } 936 937 errlab: 938 return error; 939} 940 941DEBUG_NO_STATIC int 942pfkey_spirange_parse(struct sadb_ext *pfkey_ext) 943{ 944 int error = 0; 945 struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext; 946 947 /* sanity checks... */ 948 if(pfkey_spirange->sadb_spirange_len != 949 sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) { 950 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 951 "pfkey_spirange_parse: " 952 "size wrong ext_len=%d, key_ext_len=%d.\n", 953 pfkey_spirange->sadb_spirange_len, 954 (int)sizeof(struct sadb_spirange)); 955 SENDERR(EINVAL); 956 } 957 958 if(pfkey_spirange->sadb_spirange_reserved) { 959 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 960 "pfkey_spirange_parse: " 961 "reserved=%d must be set to zero.\n", 962 pfkey_spirange->sadb_spirange_reserved); 963 SENDERR(EINVAL); 964 } 965 966 if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) { 967 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 968 "pfkey_spirange_parse: " 969 "minspi=%08x must be < maxspi=%08x.\n", 970 ntohl(pfkey_spirange->sadb_spirange_min), 971 ntohl(pfkey_spirange->sadb_spirange_max)); 972 SENDERR(EINVAL); 973 } 974 975 if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) { 976 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 977 "pfkey_spirange_parse: " 978 "minspi=%08x must be > 255.\n", 979 ntohl(pfkey_spirange->sadb_spirange_min)); 980 SENDERR(EEXIST); 981 } 982 983 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 984 "pfkey_spirange_parse: " 985 "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n", 986 pfkey_spirange->sadb_spirange_len, 987 pfkey_spirange->sadb_spirange_exttype, 988 pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype), 989 pfkey_spirange->sadb_spirange_min, 990 pfkey_spirange->sadb_spirange_max, 991 pfkey_spirange->sadb_spirange_reserved); 992 errlab: 993 return error; 994} 995 996DEBUG_NO_STATIC int 997pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext) 998{ 999 int error = 0; 1000 struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext; 1001 1002 /* sanity checks... */ 1003 if(pfkey_x_kmprivate->sadb_x_kmprivate_len < 1004 sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) { 1005 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1006 "pfkey_x_kmprivate_parse: " 1007 "size wrong ext_len=%d, key_ext_len=%d.\n", 1008 pfkey_x_kmprivate->sadb_x_kmprivate_len, 1009 (int)sizeof(struct sadb_x_kmprivate)); 1010 SENDERR(EINVAL); 1011 } 1012 1013 if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) { 1014 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1015 "pfkey_x_kmprivate_parse: " 1016 "reserved=%d must be set to zero.\n", 1017 pfkey_x_kmprivate->sadb_x_kmprivate_reserved); 1018 SENDERR(EINVAL); 1019 } 1020 1021 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1022 "pfkey_x_kmprivate_parse: " 1023 "Sorry, I can't parse exttype=%d yet.\n", 1024 pfkey_ext->sadb_ext_type); 1025 SENDERR(EINVAL); /* don't process these yet */ 1026 1027errlab: 1028 return error; 1029} 1030 1031DEBUG_NO_STATIC int 1032pfkey_x_satype_parse(struct sadb_ext *pfkey_ext) 1033{ 1034 int error = 0; 1035 int i; 1036 struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; 1037 1038 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 1039 "pfkey_x_satype_parse: enter\n"); 1040 /* sanity checks... */ 1041 if(pfkey_x_satype->sadb_x_satype_len != 1042 sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) { 1043 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1044 "pfkey_x_satype_parse: " 1045 "size wrong ext_len=%d, key_ext_len=%d.\n", 1046 pfkey_x_satype->sadb_x_satype_len, 1047 (int)sizeof(struct sadb_x_satype)); 1048 SENDERR(EINVAL); 1049 } 1050 1051 if(!pfkey_x_satype->sadb_x_satype_satype) { 1052 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1053 "pfkey_x_satype_parse: " 1054 "satype is zero, must be non-zero.\n"); 1055 SENDERR(EINVAL); 1056 } 1057 1058 if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) { 1059 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1060 "pfkey_x_satype_parse: " 1061 "satype %d > max %d, invalid.\n", 1062 pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX); 1063 SENDERR(EINVAL); 1064 } 1065 1066 if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { 1067 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1068 "pfkey_x_satype_parse: " 1069 "proto lookup from satype=%d failed.\n", 1070 pfkey_x_satype->sadb_x_satype_satype); 1071 SENDERR(EINVAL); 1072 } 1073 1074 for(i = 0; i < 3; i++) { 1075 if(pfkey_x_satype->sadb_x_satype_reserved[i]) { 1076 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1077 "pfkey_x_satype_parse: " 1078 "reserved[%d]=%d must be set to zero.\n", 1079 i, pfkey_x_satype->sadb_x_satype_reserved[i]); 1080 SENDERR(EINVAL); 1081 } 1082 } 1083 1084 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 1085 "pfkey_x_satype_parse: " 1086 "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n", 1087 pfkey_x_satype->sadb_x_satype_len, 1088 pfkey_x_satype->sadb_x_satype_exttype, 1089 pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype), 1090 pfkey_x_satype->sadb_x_satype_satype, 1091 satype2name(pfkey_x_satype->sadb_x_satype_satype), 1092 pfkey_x_satype->sadb_x_satype_reserved[0], 1093 pfkey_x_satype->sadb_x_satype_reserved[1], 1094 pfkey_x_satype->sadb_x_satype_reserved[2]); 1095errlab: 1096 return error; 1097} 1098 1099DEBUG_NO_STATIC int 1100pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext) 1101{ 1102 int error = 0; 1103 int i; 1104 struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; 1105 1106 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 1107 "pfkey_x_debug_parse: enter\n"); 1108 /* sanity checks... */ 1109 if(pfkey_x_debug->sadb_x_debug_len != 1110 sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) { 1111 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1112 "pfkey_x_debug_parse: " 1113 "size wrong ext_len=%d, key_ext_len=%d.\n", 1114 pfkey_x_debug->sadb_x_debug_len, 1115 (int)sizeof(struct sadb_x_debug)); 1116 SENDERR(EINVAL); 1117 } 1118 1119 for(i = 0; i < 4; i++) { 1120 if(pfkey_x_debug->sadb_x_debug_reserved[i]) { 1121 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1122 "pfkey_x_debug_parse: " 1123 "reserved[%d]=%d must be set to zero.\n", 1124 i, pfkey_x_debug->sadb_x_debug_reserved[i]); 1125 SENDERR(EINVAL); 1126 } 1127 } 1128 1129errlab: 1130 return error; 1131} 1132 1133#ifdef NAT_TRAVERSAL 1134DEBUG_NO_STATIC int 1135pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext) 1136{ 1137 return 0; 1138} 1139DEBUG_NO_STATIC int 1140pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext) 1141{ 1142 return 0; 1143} 1144#endif 1145 1146#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME}; 1147 1148DEFINEPARSER(pfkey_sa_parse); 1149DEFINEPARSER(pfkey_lifetime_parse); 1150DEFINEPARSER(pfkey_address_parse); 1151DEFINEPARSER(pfkey_key_parse); 1152DEFINEPARSER(pfkey_ident_parse); 1153DEFINEPARSER(pfkey_sens_parse); 1154DEFINEPARSER(pfkey_prop_parse); 1155DEFINEPARSER(pfkey_supported_parse); 1156DEFINEPARSER(pfkey_spirange_parse); 1157DEFINEPARSER(pfkey_x_kmprivate_parse); 1158DEFINEPARSER(pfkey_x_satype_parse); 1159DEFINEPARSER(pfkey_x_ext_debug_parse); 1160#ifdef NAT_TRAVERSAL 1161DEFINEPARSER(pfkey_x_ext_nat_t_type_parse); 1162DEFINEPARSER(pfkey_x_ext_nat_t_port_parse); 1163#endif 1164 1165struct pf_key_ext_parsers_def *ext_default_parsers[]= 1166{ 1167 NULL, /* pfkey_msg_parse, */ 1168 &pfkey_sa_parse_def, 1169 &pfkey_lifetime_parse_def, 1170 &pfkey_lifetime_parse_def, 1171 &pfkey_lifetime_parse_def, 1172 &pfkey_address_parse_def, 1173 &pfkey_address_parse_def, 1174 &pfkey_address_parse_def, 1175 &pfkey_key_parse_def, 1176 &pfkey_key_parse_def, 1177 &pfkey_ident_parse_def, 1178 &pfkey_ident_parse_def, 1179 &pfkey_sens_parse_def, 1180 &pfkey_prop_parse_def, 1181 &pfkey_supported_parse_def, 1182 &pfkey_supported_parse_def, 1183 &pfkey_spirange_parse_def, 1184 &pfkey_x_kmprivate_parse_def, 1185 &pfkey_x_satype_parse_def, 1186 &pfkey_sa_parse_def, 1187 &pfkey_address_parse_def, 1188 &pfkey_address_parse_def, 1189 &pfkey_address_parse_def, 1190 &pfkey_address_parse_def, 1191 &pfkey_address_parse_def, 1192 &pfkey_x_ext_debug_parse_def 1193#ifdef NAT_TRAVERSAL 1194 , 1195 &pfkey_x_ext_nat_t_type_parse_def, 1196 &pfkey_x_ext_nat_t_port_parse_def, 1197 &pfkey_x_ext_nat_t_port_parse_def, 1198 &pfkey_address_parse_def 1199#endif 1200}; 1201 1202int 1203pfkey_msg_parse(struct sadb_msg *pfkey_msg, 1204 struct pf_key_ext_parsers_def *ext_parsers[], 1205 struct sadb_ext *extensions[], 1206 int dir) 1207{ 1208 int error = 0; 1209 int remain; 1210 struct sadb_ext *pfkey_ext; 1211 int extensions_seen = 0; 1212 1213 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 1214 "pfkey_msg_parse: " 1215 "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", 1216 pfkey_msg->sadb_msg_version, 1217 pfkey_msg->sadb_msg_type, 1218 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), 1219 pfkey_msg->sadb_msg_errno, 1220 pfkey_msg->sadb_msg_satype, 1221 satype2name(pfkey_msg->sadb_msg_satype), 1222 pfkey_msg->sadb_msg_len, 1223 pfkey_msg->sadb_msg_reserved, 1224 pfkey_msg->sadb_msg_seq, 1225 pfkey_msg->sadb_msg_pid); 1226 1227 if(ext_parsers == NULL) ext_parsers = ext_default_parsers; 1228 1229 pfkey_extensions_init(extensions); 1230 1231 remain = pfkey_msg->sadb_msg_len; 1232 remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; 1233 1234 pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg + 1235 sizeof(struct sadb_msg)); 1236 1237 extensions[0] = (struct sadb_ext *) pfkey_msg; 1238 1239 1240 if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { 1241 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1242 "pfkey_msg_parse: " 1243 "not PF_KEY_V2 msg, found %d, should be %d.\n", 1244 pfkey_msg->sadb_msg_version, 1245 PF_KEY_V2); 1246 SENDERR(EINVAL); 1247 } 1248 1249 if(!pfkey_msg->sadb_msg_type) { 1250 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1251 "pfkey_msg_parse: " 1252 "msg type not set, must be non-zero..\n"); 1253 SENDERR(EINVAL); 1254 } 1255 1256 if(pfkey_msg->sadb_msg_type > SADB_MAX) { 1257 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1258 "pfkey_msg_parse: " 1259 "msg type=%d > max=%d.\n", 1260 pfkey_msg->sadb_msg_type, 1261 SADB_MAX); 1262 SENDERR(EINVAL); 1263 } 1264 1265 switch(pfkey_msg->sadb_msg_type) { 1266 case SADB_GETSPI: 1267 case SADB_UPDATE: 1268 case SADB_ADD: 1269 case SADB_DELETE: 1270 case SADB_GET: 1271 case SADB_X_GRPSA: 1272 case SADB_X_ADDFLOW: 1273 if(!satype2proto(pfkey_msg->sadb_msg_satype)) { 1274 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1275 "pfkey_msg_parse: " 1276 "satype %d conversion to proto failed for msg_type %d (%s).\n", 1277 pfkey_msg->sadb_msg_satype, 1278 pfkey_msg->sadb_msg_type, 1279 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); 1280 SENDERR(EINVAL); 1281 } else { 1282 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1283 "pfkey_msg_parse: " 1284 "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n", 1285 pfkey_msg->sadb_msg_satype, 1286 satype2name(pfkey_msg->sadb_msg_satype), 1287 satype2proto(pfkey_msg->sadb_msg_satype), 1288 pfkey_msg->sadb_msg_type, 1289 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); 1290 } 1291 case SADB_ACQUIRE: 1292 case SADB_REGISTER: 1293 case SADB_EXPIRE: 1294 if(!pfkey_msg->sadb_msg_satype) { 1295 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1296 "pfkey_msg_parse: " 1297 "satype is zero, must be non-zero for msg_type %d(%s).\n", 1298 pfkey_msg->sadb_msg_type, 1299 pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); 1300 SENDERR(EINVAL); 1301 } 1302 default: 1303 break; 1304 } 1305 1306 /* errno must not be set in downward messages */ 1307 /* this is not entirely true... a response to an ACQUIRE could return an error */ 1308 if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) { 1309 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1310 "pfkey_msg_parse: " 1311 "errno set to %d.\n", 1312 pfkey_msg->sadb_msg_errno); 1313 SENDERR(EINVAL); 1314 } 1315 1316 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 1317 "pfkey_msg_parse: " 1318 "remain=%d, ext_type=%d(%s), ext_len=%d.\n", 1319 remain, 1320 pfkey_ext->sadb_ext_type, 1321 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), 1322 pfkey_ext->sadb_ext_len); 1323 1324 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 1325 "pfkey_msg_parse: " 1326 "extensions permitted=%08x, required=%08x.\n", 1327 extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], 1328 extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); 1329 1330 extensions_seen = 1; 1331 1332 while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) { 1333 /* Is there enough message left to support another extension header? */ 1334 if(remain < pfkey_ext->sadb_ext_len) { 1335 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1336 "pfkey_msg_parse: " 1337 "remain %d less than ext len %d.\n", 1338 remain, pfkey_ext->sadb_ext_len); 1339 SENDERR(EINVAL); 1340 } 1341 1342 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 1343 "pfkey_msg_parse: " 1344 "parsing ext type=%d(%s) remain=%d.\n", 1345 pfkey_ext->sadb_ext_type, 1346 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), 1347 remain); 1348 1349 /* Is the extension header type valid? */ 1350 if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) { 1351 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1352 "pfkey_msg_parse: " 1353 "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n", 1354 pfkey_ext->sadb_ext_type, 1355 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), 1356 SADB_EXT_MAX); 1357 SENDERR(EINVAL); 1358 } 1359 1360 /* Have we already seen this type of extension? */ 1361 if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0) 1362 { 1363 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1364 "pfkey_msg_parse: " 1365 "ext type %d(%s) already seen.\n", 1366 pfkey_ext->sadb_ext_type, 1367 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); 1368 SENDERR(EINVAL); 1369 } 1370 1371 /* Do I even know about this type of extension? */ 1372 if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) { 1373 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1374 "pfkey_msg_parse: " 1375 "ext type %d(%s) unknown, ignoring.\n", 1376 pfkey_ext->sadb_ext_type, 1377 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); 1378 goto next_ext; 1379 } 1380 1381 /* Is this type of extension permitted for this type of message? */ 1382 if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] & 1383 1<<pfkey_ext->sadb_ext_type)) { 1384 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1385 "pfkey_msg_parse: " 1386 "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n", 1387 pfkey_ext->sadb_ext_type, 1388 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), 1389 extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], 1390 1<<pfkey_ext->sadb_ext_type); 1391 SENDERR(EINVAL); 1392 } 1393 1394 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 1395 "pfkey_msg_parse: " 1396 "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n", 1397 remain, 1398 pfkey_ext->sadb_ext_type, 1399 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), 1400 pfkey_ext->sadb_ext_len, 1401 pfkey_ext, 1402 ext_parsers[pfkey_ext->sadb_ext_type]->parser_name); 1403 1404 /* Parse the extension */ 1405 if((error = 1406 (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) { 1407 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1408 "pfkey_msg_parse: " 1409 "extension parsing for type %d(%s) failed with error %d.\n", 1410 pfkey_ext->sadb_ext_type, 1411 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), 1412 error); 1413 SENDERR(-error); 1414 } 1415 DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, 1416 "pfkey_msg_parse: " 1417 "Extension %d(%s) parsed.\n", 1418 pfkey_ext->sadb_ext_type, 1419 pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); 1420 1421 /* Mark that we have seen this extension and remember the header location */ 1422 extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type ); 1423 extensions[pfkey_ext->sadb_ext_type] = pfkey_ext; 1424 1425 next_ext: 1426 /* Calculate how much message remains */ 1427 remain -= pfkey_ext->sadb_ext_len; 1428 1429 if(!remain) { 1430 break; 1431 } 1432 /* Find the next extension header */ 1433 pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext + 1434 pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); 1435 } 1436 1437 if(remain) { 1438 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1439 "pfkey_msg_parse: " 1440 "unexpected remainder of %d.\n", 1441 remain); 1442 /* why is there still something remaining? */ 1443 SENDERR(EINVAL); 1444 } 1445 1446 /* check required extensions */ 1447 DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, 1448 "pfkey_msg_parse: " 1449 "extensions permitted=%08x, seen=%08x, required=%08x.\n", 1450 extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], 1451 extensions_seen, 1452 extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); 1453 1454 /* don't check further if it is an error return message since it 1455 may not have a body */ 1456 if(pfkey_msg->sadb_msg_errno) { 1457 SENDERR(-error); 1458 } 1459 1460 if((extensions_seen & 1461 extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) != 1462 extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) { 1463 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1464 "pfkey_msg_parse: " 1465 "required extensions missing:%08x.\n", 1466 extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] - 1467 (extensions_seen & 1468 extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type])); 1469 SENDERR(EINVAL); 1470 } 1471 1472 if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW) 1473 && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW) 1474 != SADB_X_EXT_ADDRESS_DELFLOW) 1475 && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA)) 1476 || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags 1477 & SADB_X_SAFLAGS_CLEARFLOW) 1478 != SADB_X_SAFLAGS_CLEARFLOW))) { 1479 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1480 "pfkey_msg_parse: " 1481 "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n", 1482 SADB_X_EXT_ADDRESS_DELFLOW 1483 - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW), 1484 (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA))); 1485 SENDERR(EINVAL); 1486 } 1487 1488 switch(pfkey_msg->sadb_msg_type) { 1489 case SADB_ADD: 1490 case SADB_UPDATE: 1491 /* check maturity */ 1492 if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != 1493 SADB_SASTATE_MATURE) { 1494 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1495 "pfkey_msg_parse: " 1496 "state=%d for add or update should be MATURE=%d.\n", 1497 ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, 1498 SADB_SASTATE_MATURE); 1499 SENDERR(EINVAL); 1500 } 1501 1502 /* check AH and ESP */ 1503 switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) { 1504 case SADB_SATYPE_AH: 1505 if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && 1506 ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth != 1507 SADB_AALG_NONE)) { 1508 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1509 "pfkey_msg_parse: " 1510 "auth alg is zero, must be non-zero for AH SAs.\n"); 1511 SENDERR(EINVAL); 1512 } 1513 if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt != 1514 SADB_EALG_NONE) { 1515 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1516 "pfkey_msg_parse: " 1517 "AH handed encalg=%d, must be zero.\n", 1518 ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt); 1519 SENDERR(EINVAL); 1520 } 1521 break; 1522 case SADB_SATYPE_ESP: 1523 if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && 1524 ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != 1525 SADB_EALG_NONE)) { 1526 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1527 "pfkey_msg_parse: " 1528 "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n", 1529 ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, 1530 ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); 1531 SENDERR(EINVAL); 1532 } 1533 if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt == 1534 SADB_EALG_NULL) && 1535 (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth == 1536 SADB_AALG_NONE) ) { 1537 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1538 "pfkey_msg_parse: " 1539 "ESP handed encNULL+authNONE, illegal combination.\n"); 1540 SENDERR(EINVAL); 1541 } 1542 break; 1543 case SADB_X_SATYPE_COMP: 1544 if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && 1545 ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != 1546 SADB_EALG_NONE)) { 1547 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1548 "pfkey_msg_parse: " 1549 "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n", 1550 ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, 1551 ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); 1552 SENDERR(EINVAL); 1553 } 1554 if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth != 1555 SADB_AALG_NONE) { 1556 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1557 "pfkey_msg_parse: " 1558 "COMP handed auth=%d, must be zero.\n", 1559 ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth); 1560 SENDERR(EINVAL); 1561 } 1562 break; 1563 default: 1564 break; 1565 } 1566 if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) { 1567 DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 1568 "pfkey_msg_parse: " 1569 "spi=%08x must be > 255.\n", 1570 ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi)); 1571 SENDERR(EINVAL); 1572 } 1573 default: 1574 break; 1575 } 1576errlab: 1577 1578 return error; 1579} 1580 1581/* 1582 * $Log: pfkey_v2_parse.c,v $ 1583 * Revision 1.53 2003/01/30 02:32:09 rgb 1584 * 1585 * Rename SAref table macro names for clarity. 1586 * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. 1587 * 1588 * Revision 1.52 2002/12/30 06:53:07 mcr 1589 * deal with short SA structures... #if 0 out for now. Probably 1590 * not quite the right way. 1591 * 1592 * Revision 1.51 2002/12/13 18:16:02 mcr 1593 * restored sa_ref code 1594 * 1595 * Revision 1.50 2002/12/13 18:06:52 mcr 1596 * temporarily removed sadb_x_sa_ref reference for 2.xx 1597 * 1598 * Revision 1.49 2002/10/05 05:02:58 dhr 1599 * 1600 * C labels go on statements 1601 * 1602 * Revision 1.48 2002/09/20 15:40:45 rgb 1603 * Added sadb_x_sa_ref to struct sadb_sa. 1604 * 1605 * Revision 1.47 2002/09/20 05:01:31 rgb 1606 * Fixed usage of pfkey_lib_debug. 1607 * Format for function declaration style consistency. 1608 * Added text labels to elucidate numeric values presented. 1609 * Re-organised debug output to reduce noise in output. 1610 * 1611 * Revision 1.46 2002/07/24 18:44:54 rgb 1612 * Type fiddling to tame ia64 compiler. 1613 * 1614 * Revision 1.45 2002/05/23 07:14:11 rgb 1615 * Cleaned up %p variants to 0p%p for test suite cleanup. 1616 * 1617 * Revision 1.44 2002/04/24 07:55:32 mcr 1618 * #include patches and Makefiles for post-reorg compilation. 1619 * 1620 * Revision 1.43 2002/04/24 07:36:40 mcr 1621 * Moved from ./lib/pfkey_v2_parse.c,v 1622 * 1623 * Revision 1.42 2002/01/29 22:25:36 rgb 1624 * Re-add ipsec_kversion.h to keep MALLOC happy. 1625 * 1626 * Revision 1.41 2002/01/29 01:59:10 mcr 1627 * removal of kversions.h - sources that needed it now use ipsec_param.h. 1628 * updating of IPv6 structures to match latest in6.h version. 1629 * removed dead code from freeswan.h that also duplicated kversions.h 1630 * code. 1631 * 1632 * Revision 1.40 2002/01/20 20:34:50 mcr 1633 * added pfkey_v2_sadb_type_string to decode sadb_type to string. 1634 * 1635 * Revision 1.39 2001/11/27 05:29:22 mcr 1636 * pfkey parses are now maintained by a structure 1637 * that includes their name for debug purposes. 1638 * DEBUGGING() macro changed so that it takes a debug 1639 * level so that pf_key() can use this to decode the 1640 * structures without innundanting humans. 1641 * Also uses pfkey_v2_sadb_ext_string() in messages. 1642 * 1643 * Revision 1.38 2001/11/06 19:47:47 rgb 1644 * Added packet parameter to lifetime and comb structures. 1645 * 1646 * Revision 1.37 2001/10/18 04:45:24 rgb 1647 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, 1648 * lib/freeswan.h version macros moved to lib/kversions.h. 1649 * Other compiler directive cleanups. 1650 * 1651 * Revision 1.36 2001/06/14 19:35:16 rgb 1652 * Update copyright date. 1653 * 1654 * Revision 1.35 2001/05/03 19:44:51 rgb 1655 * Standardise on SENDERR() macro. 1656 * 1657 * Revision 1.34 2001/03/16 07:41:51 rgb 1658 * Put freeswan.h include before pluto includes. 1659 * 1660 * Revision 1.33 2001/02/27 07:13:51 rgb 1661 * Added satype2name() function. 1662 * Added text to default satype_tbl entry. 1663 * Added satype2name() conversions for most satype debug output. 1664 * 1665 * Revision 1.32 2001/02/26 20:01:09 rgb 1666 * Added internal IP protocol 61 for magic SAs. 1667 * Ditch unused sadb_satype2proto[], replaced by satype2proto(). 1668 * Re-formatted debug output (split lines, consistent spacing). 1669 * Removed acquire, register and expire requirements for a known satype. 1670 * Changed message type checking to a switch structure. 1671 * Verify expected NULL auth for IPCOMP. 1672 * Enforced spi > 0x100 requirement, now that pass uses a magic SA for 1673 * appropriate message types. 1674 * 1675 * Revision 1.31 2000/12/01 07:09:00 rgb 1676 * Added ipcomp sanity check to require encalgo is set. 1677 * 1678 * Revision 1.30 2000/11/17 18:10:30 rgb 1679 * Fixed bugs mostly relating to spirange, to treat all spi variables as 1680 * network byte order since this is the way PF_KEYv2 stored spis. 1681 * 1682 * Revision 1.29 2000/10/12 00:02:39 rgb 1683 * Removed 'format, ##' nonsense from debug macros for RH7.0. 1684 * 1685 * Revision 1.28 2000/09/20 16:23:04 rgb 1686 * Remove over-paranoid extension check in the presence of sadb_msg_errno. 1687 * 1688 * Revision 1.27 2000/09/20 04:04:21 rgb 1689 * Changed static functions to DEBUG_NO_STATIC to reveal function names in 1690 * oopsen. 1691 * 1692 * Revision 1.26 2000/09/15 11:37:02 rgb 1693 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> 1694 * IPCOMP zlib deflate code. 1695 * 1696 * Revision 1.25 2000/09/12 22:35:37 rgb 1697 * Restructured to remove unused extensions from CLEARFLOW messages. 1698 * 1699 * Revision 1.24 2000/09/12 18:59:54 rgb 1700 * Added Gerhard's IPv6 support to pfkey parts of libfreeswan. 1701 * 1702 * Revision 1.23 2000/09/12 03:27:00 rgb 1703 * Moved DEBUGGING definition to compile kernel with debug off. 1704 * 1705 * Revision 1.22 2000/09/09 06:39:27 rgb 1706 * Restrict pfkey errno check to downward messages only. 1707 * 1708 * Revision 1.21 2000/09/08 19:22:34 rgb 1709 * Enabled pfkey_sens_parse(). 1710 * Added check for errno on downward acquire messages only. 1711 * 1712 * Revision 1.20 2000/09/01 18:48:23 rgb 1713 * Fixed reserved check bug and added debug output in 1714 * pfkey_supported_parse(). 1715 * Fixed debug output label bug in pfkey_ident_parse(). 1716 * 1717 * Revision 1.19 2000/08/27 01:55:26 rgb 1718 * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. 1719 * 1720 * Revision 1.18 2000/08/24 17:00:36 rgb 1721 * Ignore unknown extensions instead of failing. 1722 * 1723 * Revision 1.17 2000/06/02 22:54:14 rgb 1724 * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. 1725 * 1726 * Revision 1.16 2000/05/10 19:25:11 rgb 1727 * Fleshed out proposal and supported extensions. 1728 * 1729 * Revision 1.15 2000/01/24 21:15:31 rgb 1730 * Added disabled pluto pfkey lib debug flag. 1731 * Added algo debugging reporting. 1732 * 1733 * Revision 1.14 2000/01/22 23:24:29 rgb 1734 * Added new functions proto2satype() and satype2proto() and lookup 1735 * table satype_tbl. Also added proto2name() since it was easy. 1736 * 1737 * Revision 1.13 2000/01/21 09:43:59 rgb 1738 * Cast ntohl(spi) as (unsigned long int) to shut up compiler. 1739 * 1740 * Revision 1.12 2000/01/21 06:28:19 rgb 1741 * Added address cases for eroute flows. 1742 * Indented compiler directives for readability. 1743 * Added klipsdebug switching capability. 1744 * 1745 * Revision 1.11 1999/12/29 21:14:59 rgb 1746 * Fixed debug text cut and paste typo. 1747 * 1748 * Revision 1.10 1999/12/10 17:45:24 rgb 1749 * Added address debugging. 1750 * 1751 * Revision 1.9 1999/12/09 23:11:42 rgb 1752 * Ditched <string.h> include since we no longer use memset(). 1753 * Use new pfkey_extensions_init() instead of memset(). 1754 * Added check for SATYPE in pfkey_msg_build(). 1755 * Tidy up comments and debugging comments. 1756 * 1757 * Revision 1.8 1999/12/07 19:55:26 rgb 1758 * Removed unused first argument from extension parsers. 1759 * Removed static pluto debug flag. 1760 * Moved message type and state checking to pfkey_msg_parse(). 1761 * Changed print[fk] type from lx to x to quiet compiler. 1762 * Removed redundant remain check. 1763 * Changed __u* types to uint* to avoid use of asm/types.h and 1764 * sys/types.h in userspace code. 1765 * 1766 * Revision 1.7 1999/12/01 22:20:51 rgb 1767 * Moved pfkey_lib_debug variable into the library. 1768 * Added pfkey version check into header parsing. 1769 * Added check for SATYPE only for those extensions that require a 1770 * non-zero value. 1771 * 1772 * Revision 1.6 1999/11/27 11:58:05 rgb 1773 * Added ipv6 headers. 1774 * Moved sadb_satype2proto protocol lookup table from 1775 * klips/net/ipsec/pfkey_v2_parser.c. 1776 * Enable lifetime_current checking. 1777 * Debugging error messages added. 1778 * Add argument to pfkey_msg_parse() for direction. 1779 * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. 1780 * Add CVS log entry to bottom of file. 1781 * Moved auth and enc alg check to pfkey_msg_parse(). 1782 * Enable accidentally disabled spirange parsing. 1783 * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c 1784 * 1785 * Local variables: 1786 * c-file-style: "linux" 1787 * End: 1788 * 1789 */ 1790