1 /* $NetBSD: ipsec_doi.c,v 1.23.4.10 2009/06/19 07:32:52 tteras Exp $ */ 2 3 /* Id: ipsec_doi.c,v 1.55 2006/08/17 09:20:41 vanhu Exp */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 40 #include <netinet/in.h> 41 42 #include PATH_IPSEC_H 43 44 #include <stdlib.h> 45 #include <stdio.h> 46 #include <string.h> 47 #include <errno.h> 48 #include <netdb.h> 49 #if TIME_WITH_SYS_TIME 50 # include <sys/time.h> 51 # include <time.h> 52 #else 53 # if HAVE_SYS_TIME_H 54 # include <sys/time.h> 55 # else 56 # include <time.h> 57 # endif 58 #endif 59 60 #include "var.h" 61 #include "vmbuf.h" 62 #include "misc.h" 63 #include "plog.h" 64 #include "debug.h" 65 66 #include "cfparse_proto.h" 67 #include "isakmp_var.h" 68 #include "isakmp.h" 69 #include "ipsec_doi.h" 70 #include "oakley.h" 71 #include "remoteconf.h" 72 #include "localconf.h" 73 #include "sockmisc.h" 74 #include "handler.h" 75 #include "policy.h" 76 #include "algorithm.h" 77 #include "sainfo.h" 78 #include "proposal.h" 79 #include "crypto_openssl.h" 80 #include "strnames.h" 81 #include "gcmalloc.h" 82 83 #ifdef ENABLE_NATT 84 #include "nattraversal.h" 85 #endif 86 #ifdef ENABLE_HYBRID 87 static int switch_authmethod(int); 88 #endif 89 90 #ifdef HAVE_GSSAPI 91 #include <iconv.h> 92 #include "gssapi.h" 93 #ifdef HAVE_ICONV_2ND_CONST 94 #define __iconv_const const 95 #else 96 #define __iconv_const 97 #endif 98 #endif 99 100 int verbose_proposal_check = 1; 101 102 static vchar_t *get_ph1approval __P((struct ph1handle *, struct prop_pair **)); 103 static struct isakmpsa *get_ph1approvalx __P((struct prop_pair *, 104 struct isakmpsa *, struct isakmpsa *, int)); 105 static void print_ph1mismatched __P((struct prop_pair *, struct isakmpsa *)); 106 static int t2isakmpsa __P((struct isakmp_pl_t *, struct isakmpsa *)); 107 static int cmp_aproppair_i __P((struct prop_pair *, struct prop_pair *)); 108 static struct prop_pair *get_ph2approval __P((struct ph2handle *, 109 struct prop_pair **)); 110 static struct prop_pair *get_ph2approvalx __P((struct ph2handle *, 111 struct prop_pair *)); 112 static void free_proppair0 __P((struct prop_pair *)); 113 114 static int get_transform 115 __P((struct isakmp_pl_p *, struct prop_pair **, int *)); 116 static u_int32_t ipsecdoi_set_ld __P((vchar_t *)); 117 118 static int check_doi __P((u_int32_t)); 119 static int check_situation __P((u_int32_t)); 120 121 static int check_prot_main __P((int)); 122 static int check_prot_quick __P((int)); 123 static int (*check_protocol[]) __P((int)) = { 124 check_prot_main, /* IPSECDOI_TYPE_PH1 */ 125 check_prot_quick, /* IPSECDOI_TYPE_PH2 */ 126 }; 127 128 static int check_spi_size __P((int, int)); 129 130 static int check_trns_isakmp __P((int)); 131 static int check_trns_ah __P((int)); 132 static int check_trns_esp __P((int)); 133 static int check_trns_ipcomp __P((int)); 134 static int (*check_transform[]) __P((int)) = { 135 0, 136 check_trns_isakmp, /* IPSECDOI_PROTO_ISAKMP */ 137 check_trns_ah, /* IPSECDOI_PROTO_IPSEC_AH */ 138 check_trns_esp, /* IPSECDOI_PROTO_IPSEC_ESP */ 139 check_trns_ipcomp, /* IPSECDOI_PROTO_IPCOMP */ 140 }; 141 142 static int check_attr_isakmp __P((struct isakmp_pl_t *)); 143 static int check_attr_ah __P((struct isakmp_pl_t *)); 144 static int check_attr_esp __P((struct isakmp_pl_t *)); 145 static int check_attr_ipsec __P((int, struct isakmp_pl_t *)); 146 static int check_attr_ipcomp __P((struct isakmp_pl_t *)); 147 static int (*check_attributes[]) __P((struct isakmp_pl_t *)) = { 148 0, 149 check_attr_isakmp, /* IPSECDOI_PROTO_ISAKMP */ 150 check_attr_ah, /* IPSECDOI_PROTO_IPSEC_AH */ 151 check_attr_esp, /* IPSECDOI_PROTO_IPSEC_ESP */ 152 check_attr_ipcomp, /* IPSECDOI_PROTO_IPCOMP */ 153 }; 154 155 static int setph1prop __P((struct isakmpsa *, caddr_t)); 156 static int setph1trns __P((struct isakmpsa *, caddr_t)); 157 static int setph1attr __P((struct isakmpsa *, caddr_t)); 158 static vchar_t *setph2proposal0 __P((const struct ph2handle *, 159 const struct saprop *, const struct saproto *)); 160 161 static vchar_t *getidval __P((int, vchar_t *)); 162 163 #ifdef HAVE_GSSAPI 164 static struct isakmpsa *fixup_initiator_sa __P((struct isakmpsa *, 165 struct isakmpsa *)); 166 #endif 167 168 /*%%%*/ 169 /* 170 * check phase 1 SA payload. 171 * make new SA payload to be replyed not including general header. 172 * the pointer to one of isakmpsa in proposal is set into iph1->approval. 173 * OUT: 174 * positive: the pointer to new buffer of SA payload. 175 * network byte order. 176 * NULL : error occurd. 177 */ 178 int 179 ipsecdoi_checkph1proposal(sa, iph1) 180 vchar_t *sa; 181 struct ph1handle *iph1; 182 { 183 vchar_t *newsa; /* new SA payload approved. */ 184 struct prop_pair **pair; 185 186 /* get proposal pair */ 187 pair = get_proppair(sa, IPSECDOI_TYPE_PH1); 188 if (pair == NULL) 189 return -1; 190 191 /* check and get one SA for use */ 192 newsa = get_ph1approval(iph1, pair); 193 194 free_proppair(pair); 195 196 if (newsa == NULL) 197 return -1; 198 199 iph1->sa_ret = newsa; 200 201 return 0; 202 } 203 204 /* 205 * acceptable check for remote configuration. 206 * return a new SA payload to be reply to peer. 207 */ 208 static vchar_t * 209 get_ph1approval(iph1, pair) 210 struct ph1handle *iph1; 211 struct prop_pair **pair; 212 { 213 vchar_t *newsa; 214 struct isakmpsa *sa, tsa; 215 struct prop_pair *s, *p; 216 int prophlen; 217 int i; 218 219 if (iph1->approval) { 220 delisakmpsa(iph1->approval); 221 iph1->approval = NULL; 222 } 223 224 for (i = 0; i < MAXPROPPAIRLEN; i++) { 225 if (pair[i] == NULL) 226 continue; 227 for (s = pair[i]; s; s = s->next) { 228 prophlen = 229 sizeof(struct isakmp_pl_p) + s->prop->spi_size; 230 231 /* compare proposal and select one */ 232 for (p = s; p; p = p->tnext) { 233 if ((sa = get_ph1approvalx(p, 234 iph1->rmconf->proposal, &tsa, 235 iph1->rmconf->pcheck_level)) != NULL) 236 goto found; 237 } 238 } 239 } 240 241 /* 242 * if there is no suitable proposal, racoon complains about all of 243 * mismatched items in those proposal. 244 */ 245 if (verbose_proposal_check) { 246 for (i = 0; i < MAXPROPPAIRLEN; i++) { 247 if (pair[i] == NULL) 248 continue; 249 for (s = pair[i]; s; s = s->next) { 250 prophlen = sizeof(struct isakmp_pl_p) 251 + s->prop->spi_size; 252 for (p = s; p; p = p->tnext) { 253 print_ph1mismatched(p, 254 iph1->rmconf->proposal); 255 } 256 } 257 } 258 } 259 plog(LLV_ERROR, LOCATION, NULL, "no suitable proposal found.\n"); 260 261 return NULL; 262 263 found: 264 plog(LLV_DEBUG, LOCATION, NULL, "an acceptable proposal found.\n"); 265 266 /* check DH group settings */ 267 if (sa->dhgrp) { 268 if (sa->dhgrp->prime && sa->dhgrp->gen1) { 269 /* it's ok */ 270 goto saok; 271 } 272 plog(LLV_WARNING, LOCATION, NULL, 273 "invalid DH parameter found, use default.\n"); 274 oakley_dhgrp_free(sa->dhgrp); 275 sa->dhgrp=NULL; 276 } 277 278 if (oakley_setdhgroup(sa->dh_group, &sa->dhgrp) == -1) { 279 sa->dhgrp = NULL; 280 racoon_free(sa); 281 return NULL; 282 } 283 284 saok: 285 #ifdef HAVE_GSSAPI 286 if (sa->gssid != NULL) 287 plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n", 288 (int)sa->gssid->l, sa->gssid->v); 289 if (iph1-> side == INITIATOR) { 290 if (iph1->rmconf->proposal->gssid != NULL) 291 iph1->gi_i = vdup(iph1->rmconf->proposal->gssid); 292 if (tsa.gssid != NULL) 293 iph1->gi_r = vdup(tsa.gssid); 294 iph1->approval = fixup_initiator_sa(sa, &tsa); 295 } else { 296 if (tsa.gssid != NULL) { 297 iph1->gi_r = vdup(tsa.gssid); 298 iph1->gi_i = gssapi_get_id(iph1); 299 if (sa->gssid == NULL && iph1->gi_i != NULL) 300 sa->gssid = vdup(iph1->gi_i); 301 } 302 iph1->approval = sa; 303 } 304 if (iph1->gi_i != NULL) 305 plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n", 306 (int)iph1->gi_i->l, iph1->gi_i->v); 307 if (iph1->gi_r != NULL) 308 plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n", 309 (int)iph1->gi_r->l, iph1->gi_r->v); 310 #else 311 iph1->approval = sa; 312 #endif 313 if(iph1->approval) { 314 plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n", 315 s_oakley_attr_method(iph1->approval->authmethod)); 316 } 317 318 newsa = get_sabyproppair(p, iph1); 319 if (newsa == NULL){ 320 delisakmpsa(iph1->approval); 321 iph1->approval = NULL; 322 } 323 324 return newsa; 325 } 326 327 /* 328 * compare peer's single proposal and all of my proposal. 329 * and select one if suiatable. 330 * p : one of peer's proposal. 331 * proposal: my proposals. 332 */ 333 static struct isakmpsa * 334 get_ph1approvalx(p, proposal, sap, check_level) 335 struct prop_pair *p; 336 struct isakmpsa *proposal, *sap; 337 int check_level; 338 { 339 struct isakmp_pl_p *prop = p->prop; 340 struct isakmp_pl_t *trns = p->trns; 341 struct isakmpsa sa, *s, *tsap; 342 int authmethod; 343 344 plog(LLV_DEBUG, LOCATION, NULL, 345 "prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n", 346 prop->p_no, s_ipsecdoi_proto(prop->proto_id), 347 prop->spi_size, prop->num_t); 348 349 plog(LLV_DEBUG, LOCATION, NULL, 350 "trns#=%d, trns-id=%s\n", 351 trns->t_no, 352 s_ipsecdoi_trns(prop->proto_id, trns->t_id)); 353 354 tsap = sap != NULL ? sap : &sa; 355 356 memset(tsap, 0, sizeof(*tsap)); 357 if (t2isakmpsa(trns, tsap) < 0) 358 return NULL; 359 for (s = proposal; s != NULL; s = s->next) { 360 #ifdef ENABLE_HYBRID 361 authmethod = switch_authmethod(s->authmethod); 362 #else 363 authmethod = s->authmethod; 364 #endif 365 plog(LLV_DEBUG, LOCATION, NULL, "Compared: DB:Peer\n"); 366 plog(LLV_DEBUG, LOCATION, NULL, "(lifetime = %ld:%ld)\n", 367 (long)s->lifetime, (long)tsap->lifetime); 368 plog(LLV_DEBUG, LOCATION, NULL, "(lifebyte = %zu:%zu)\n", 369 s->lifebyte, tsap->lifebyte); 370 plog(LLV_DEBUG, LOCATION, NULL, "enctype = %s:%s\n", 371 s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG, 372 s->enctype), 373 s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG, 374 tsap->enctype)); 375 plog(LLV_DEBUG, LOCATION, NULL, "(encklen = %d:%d)\n", 376 s->encklen, tsap->encklen); 377 plog(LLV_DEBUG, LOCATION, NULL, "hashtype = %s:%s\n", 378 s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG, 379 s->hashtype), 380 s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG, 381 tsap->hashtype)); 382 plog(LLV_DEBUG, LOCATION, NULL, "authmethod = %s:%s\n", 383 s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, 384 s->authmethod), 385 s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, 386 tsap->authmethod)); 387 plog(LLV_DEBUG, LOCATION, NULL, "dh_group = %s:%s\n", 388 s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC, 389 s->dh_group), 390 s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC, 391 tsap->dh_group)); 392 #if 0 393 /* XXX to be considered ? */ 394 if (tsap->lifebyte > s->lifebyte) ; 395 #endif 396 /* 397 * if responder side and peer's key length in proposal 398 * is bigger than mine, it might be accepted. 399 */ 400 if(tsap->enctype == s->enctype && 401 tsap->authmethod == authmethod && 402 tsap->hashtype == s->hashtype && 403 tsap->dh_group == s->dh_group && 404 tsap->encklen == s->encklen) { 405 switch(check_level) { 406 case PROP_CHECK_OBEY: 407 goto found; 408 break; 409 410 case PROP_CHECK_STRICT: 411 if ((tsap->lifetime > s->lifetime) || 412 (tsap->lifebyte > s->lifebyte)) 413 continue; 414 goto found; 415 break; 416 417 case PROP_CHECK_CLAIM: 418 if (tsap->lifetime < s->lifetime) 419 s->lifetime = tsap->lifetime; 420 if (tsap->lifebyte < s->lifebyte) 421 s->lifebyte = tsap->lifebyte; 422 goto found; 423 break; 424 425 case PROP_CHECK_EXACT: 426 if ((tsap->lifetime != s->lifetime) || 427 (tsap->lifebyte != s->lifebyte)) 428 continue; 429 goto found; 430 break; 431 432 default: 433 plog(LLV_ERROR, LOCATION, NULL, 434 "Unexpected proposal_check value\n"); 435 continue; 436 break; 437 } 438 } 439 } 440 441 found: 442 if (tsap->dhgrp != NULL){ 443 oakley_dhgrp_free(tsap->dhgrp); 444 tsap->dhgrp = NULL; 445 } 446 447 if ((s = dupisakmpsa(s)) != NULL) { 448 switch(check_level) { 449 case PROP_CHECK_OBEY: 450 s->lifetime = tsap->lifetime; 451 s->lifebyte = tsap->lifebyte; 452 break; 453 454 case PROP_CHECK_STRICT: 455 s->lifetime = tsap->lifetime; 456 s->lifebyte = tsap->lifebyte; 457 break; 458 459 case PROP_CHECK_CLAIM: 460 if (tsap->lifetime < s->lifetime) 461 s->lifetime = tsap->lifetime; 462 if (tsap->lifebyte < s->lifebyte) 463 s->lifebyte = tsap->lifebyte; 464 break; 465 466 default: 467 break; 468 } 469 } 470 return s; 471 } 472 473 /* 474 * print all of items in peer's proposal which are mismatched to my proposal. 475 * p : one of peer's proposal. 476 * proposal: my proposals. 477 */ 478 static void 479 print_ph1mismatched(p, proposal) 480 struct prop_pair *p; 481 struct isakmpsa *proposal; 482 { 483 struct isakmpsa sa, *s; 484 485 memset(&sa, 0, sizeof(sa)); 486 if (t2isakmpsa(p->trns, &sa) < 0) 487 return; 488 for (s = proposal; s ; s = s->next) { 489 if (sa.enctype != s->enctype) { 490 plog(LLV_ERROR, LOCATION, NULL, 491 "rejected enctype: " 492 "DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = " 493 "%s:%s\n", 494 s->prop_no, s->trns_no, 495 p->prop->p_no, p->trns->t_no, 496 s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG, 497 s->enctype), 498 s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG, 499 sa.enctype)); 500 } 501 if (sa.authmethod != s->authmethod) { 502 plog(LLV_ERROR, LOCATION, NULL, 503 "rejected authmethod: " 504 "DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = " 505 "%s:%s\n", 506 s->prop_no, s->trns_no, 507 p->prop->p_no, p->trns->t_no, 508 s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, 509 s->authmethod), 510 s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, 511 sa.authmethod)); 512 } 513 if (sa.hashtype != s->hashtype) { 514 plog(LLV_ERROR, LOCATION, NULL, 515 "rejected hashtype: " 516 "DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = " 517 "%s:%s\n", 518 s->prop_no, s->trns_no, 519 p->prop->p_no, p->trns->t_no, 520 s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG, 521 s->hashtype), 522 s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG, 523 sa.hashtype)); 524 } 525 if (sa.dh_group != s->dh_group) { 526 plog(LLV_ERROR, LOCATION, NULL, 527 "rejected dh_group: " 528 "DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = " 529 "%s:%s\n", 530 s->prop_no, s->trns_no, 531 p->prop->p_no, p->trns->t_no, 532 s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC, 533 s->dh_group), 534 s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC, 535 sa.dh_group)); 536 } 537 } 538 539 if (sa.dhgrp != NULL){ 540 oakley_dhgrp_free(sa.dhgrp); 541 sa.dhgrp=NULL; 542 } 543 } 544 545 /* 546 * get ISAKMP data attributes 547 */ 548 static int 549 t2isakmpsa(trns, sa) 550 struct isakmp_pl_t *trns; 551 struct isakmpsa *sa; 552 { 553 struct isakmp_data *d, *prev; 554 int flag, type; 555 int error = -1; 556 int life_t; 557 int keylen = 0; 558 vchar_t *val = NULL; 559 int len, tlen; 560 u_char *p; 561 562 tlen = ntohs(trns->h.len) - sizeof(*trns); 563 prev = (struct isakmp_data *)NULL; 564 d = (struct isakmp_data *)(trns + 1); 565 566 /* default */ 567 life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT; 568 sa->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT; 569 sa->lifebyte = 0; 570 sa->dhgrp = racoon_calloc(1, sizeof(struct dhgroup)); 571 if (!sa->dhgrp) 572 goto err; 573 574 while (tlen > 0) { 575 576 type = ntohs(d->type) & ~ISAKMP_GEN_MASK; 577 flag = ntohs(d->type) & ISAKMP_GEN_MASK; 578 579 plog(LLV_DEBUG, LOCATION, NULL, 580 "type=%s, flag=0x%04x, lorv=%s\n", 581 s_oakley_attr(type), flag, 582 s_oakley_attr_v(type, ntohs(d->lorv))); 583 584 /* get variable-sized item */ 585 switch (type) { 586 case OAKLEY_ATTR_GRP_PI: 587 case OAKLEY_ATTR_GRP_GEN_ONE: 588 case OAKLEY_ATTR_GRP_GEN_TWO: 589 case OAKLEY_ATTR_GRP_CURVE_A: 590 case OAKLEY_ATTR_GRP_CURVE_B: 591 case OAKLEY_ATTR_SA_LD: 592 case OAKLEY_ATTR_GRP_ORDER: 593 if (flag) { /*TV*/ 594 len = 2; 595 p = (u_char *)&d->lorv; 596 } else { /*TLV*/ 597 len = ntohs(d->lorv); 598 p = (u_char *)(d + 1); 599 } 600 val = vmalloc(len); 601 if (!val) 602 return -1; 603 memcpy(val->v, p, len); 604 break; 605 606 default: 607 break; 608 } 609 610 switch (type) { 611 case OAKLEY_ATTR_ENC_ALG: 612 sa->enctype = (u_int16_t)ntohs(d->lorv); 613 break; 614 615 case OAKLEY_ATTR_HASH_ALG: 616 sa->hashtype = (u_int16_t)ntohs(d->lorv); 617 break; 618 619 case OAKLEY_ATTR_AUTH_METHOD: 620 sa->authmethod = ntohs(d->lorv); 621 break; 622 623 case OAKLEY_ATTR_GRP_DESC: 624 sa->dh_group = (u_int16_t)ntohs(d->lorv); 625 break; 626 627 case OAKLEY_ATTR_GRP_TYPE: 628 { 629 int type = (int)ntohs(d->lorv); 630 if (type == OAKLEY_ATTR_GRP_TYPE_MODP) 631 sa->dhgrp->type = type; 632 else 633 return -1; 634 break; 635 } 636 case OAKLEY_ATTR_GRP_PI: 637 sa->dhgrp->prime = val; 638 break; 639 640 case OAKLEY_ATTR_GRP_GEN_ONE: 641 vfree(val); 642 if (!flag) 643 sa->dhgrp->gen1 = ntohs(d->lorv); 644 else { 645 int len = ntohs(d->lorv); 646 sa->dhgrp->gen1 = 0; 647 if (len > 4) 648 return -1; 649 memcpy(&sa->dhgrp->gen1, d + 1, len); 650 sa->dhgrp->gen1 = ntohl(sa->dhgrp->gen1); 651 } 652 break; 653 654 case OAKLEY_ATTR_GRP_GEN_TWO: 655 vfree(val); 656 if (!flag) 657 sa->dhgrp->gen2 = ntohs(d->lorv); 658 else { 659 int len = ntohs(d->lorv); 660 sa->dhgrp->gen2 = 0; 661 if (len > 4) 662 return -1; 663 memcpy(&sa->dhgrp->gen2, d + 1, len); 664 sa->dhgrp->gen2 = ntohl(sa->dhgrp->gen2); 665 } 666 break; 667 668 case OAKLEY_ATTR_GRP_CURVE_A: 669 sa->dhgrp->curve_a = val; 670 break; 671 672 case OAKLEY_ATTR_GRP_CURVE_B: 673 sa->dhgrp->curve_b = val; 674 break; 675 676 case OAKLEY_ATTR_SA_LD_TYPE: 677 { 678 int type = (int)ntohs(d->lorv); 679 switch (type) { 680 case OAKLEY_ATTR_SA_LD_TYPE_SEC: 681 case OAKLEY_ATTR_SA_LD_TYPE_KB: 682 life_t = type; 683 break; 684 default: 685 life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT; 686 break; 687 } 688 break; 689 } 690 case OAKLEY_ATTR_SA_LD: 691 if (!prev 692 || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) != 693 OAKLEY_ATTR_SA_LD_TYPE) { 694 plog(LLV_ERROR, LOCATION, NULL, 695 "life duration must follow ltype\n"); 696 break; 697 } 698 699 switch (life_t) { 700 case IPSECDOI_ATTR_SA_LD_TYPE_SEC: 701 sa->lifetime = ipsecdoi_set_ld(val); 702 vfree(val); 703 if (sa->lifetime == 0) { 704 plog(LLV_ERROR, LOCATION, NULL, 705 "invalid life duration.\n"); 706 goto err; 707 } 708 break; 709 case IPSECDOI_ATTR_SA_LD_TYPE_KB: 710 sa->lifebyte = ipsecdoi_set_ld(val); 711 vfree(val); 712 if (sa->lifebyte == 0) { 713 plog(LLV_ERROR, LOCATION, NULL, 714 "invalid life duration.\n"); 715 goto err; 716 } 717 break; 718 default: 719 vfree(val); 720 plog(LLV_ERROR, LOCATION, NULL, 721 "invalid life type: %d\n", life_t); 722 goto err; 723 } 724 break; 725 726 case OAKLEY_ATTR_KEY_LEN: 727 { 728 int len = ntohs(d->lorv); 729 if (len % 8 != 0) { 730 plog(LLV_ERROR, LOCATION, NULL, 731 "keylen %d: not multiple of 8\n", 732 len); 733 goto err; 734 } 735 sa->encklen = (u_int16_t)len; 736 keylen++; 737 break; 738 } 739 case OAKLEY_ATTR_PRF: 740 case OAKLEY_ATTR_FIELD_SIZE: 741 /* unsupported */ 742 break; 743 744 case OAKLEY_ATTR_GRP_ORDER: 745 sa->dhgrp->order = val; 746 break; 747 #ifdef HAVE_GSSAPI 748 case OAKLEY_ATTR_GSS_ID: 749 { 750 int error = -1; 751 iconv_t cd = (iconv_t) -1; 752 size_t srcleft, dstleft, rv; 753 __iconv_const char *src; 754 char *dst; 755 int len = ntohs(d->lorv); 756 757 /* 758 * Older verions of racoon just placed the 759 * ISO-Latin-1 string on the wire directly. 760 * Check to see if we are configured to be 761 * compatible with this behavior. 762 */ 763 if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) { 764 if ((sa->gssid = vmalloc(len)) == NULL) { 765 plog(LLV_ERROR, LOCATION, NULL, 766 "failed to allocate memory\n"); 767 goto out; 768 } 769 memcpy(sa->gssid->v, d + 1, len); 770 plog(LLV_DEBUG, LOCATION, NULL, 771 "received old-style gss " 772 "id '%.*s' (len %zu)\n", 773 (int)sa->gssid->l, sa->gssid->v, 774 sa->gssid->l); 775 error = 0; 776 goto out; 777 } 778 779 /* 780 * For Windows 2000 compatibility, we expect 781 * the GSS ID attribute on the wire to be 782 * encoded in UTF-16LE. Internally, we work 783 * in ISO-Latin-1. Therefore, we should need 784 * 1/2 the specified length, which should always 785 * be a multiple of 2 octets. 786 */ 787 cd = iconv_open("latin1", "utf-16le"); 788 if (cd == (iconv_t) -1) { 789 plog(LLV_ERROR, LOCATION, NULL, 790 "unable to initialize utf-16le -> latin1 " 791 "conversion descriptor: %s\n", 792 strerror(errno)); 793 goto out; 794 } 795 796 if ((sa->gssid = vmalloc(len / 2)) == NULL) { 797 plog(LLV_ERROR, LOCATION, NULL, 798 "failed to allocate memory\n"); 799 goto out; 800 } 801 802 src = (__iconv_const char *)(d + 1); 803 srcleft = len; 804 805 dst = sa->gssid->v; 806 dstleft = len / 2; 807 808 rv = iconv(cd, (__iconv_const char **)&src, &srcleft, 809 &dst, &dstleft); 810 if (rv != 0) { 811 if (rv == -1) { 812 plog(LLV_ERROR, LOCATION, NULL, 813 "unable to convert GSS ID from " 814 "utf-16le -> latin1: %s\n", 815 strerror(errno)); 816 } else { 817 plog(LLV_ERROR, LOCATION, NULL, 818 "%zd character%s in GSS ID cannot " 819 "be represented in latin1\n", 820 rv, rv == 1 ? "" : "s"); 821 } 822 goto out; 823 } 824 825 /* XXX dstleft should always be 0; assert it? */ 826 sa->gssid->l = (len / 2) - dstleft; 827 828 plog(LLV_DEBUG, LOCATION, NULL, 829 "received gss id '%.*s' (len %zu)\n", 830 (int)sa->gssid->l, sa->gssid->v, sa->gssid->l); 831 832 error = 0; 833 out: 834 if (cd != (iconv_t)-1) 835 (void)iconv_close(cd); 836 837 if ((error != 0) && (sa->gssid != NULL)) { 838 vfree(sa->gssid); 839 sa->gssid = NULL; 840 } 841 break; 842 } 843 #endif /* HAVE_GSSAPI */ 844 845 default: 846 break; 847 } 848 849 prev = d; 850 if (flag) { 851 tlen -= sizeof(*d); 852 d = (struct isakmp_data *)((char *)d + sizeof(*d)); 853 } else { 854 tlen -= (sizeof(*d) + ntohs(d->lorv)); 855 d = (struct isakmp_data *)((char *)d + sizeof(*d) + ntohs(d->lorv)); 856 } 857 } 858 859 /* key length must not be specified on some algorithms */ 860 if (keylen) { 861 if (sa->enctype == OAKLEY_ATTR_ENC_ALG_DES 862 #ifdef HAVE_OPENSSL_IDEA_H 863 || sa->enctype == OAKLEY_ATTR_ENC_ALG_IDEA 864 #endif 865 || sa->enctype == OAKLEY_ATTR_ENC_ALG_3DES) { 866 plog(LLV_ERROR, LOCATION, NULL, 867 "keylen must not be specified " 868 "for encryption algorithm %d\n", 869 sa->enctype); 870 return -1; 871 } 872 } 873 874 return 0; 875 err: 876 return error; 877 } 878 879 /*%%%*/ 880 /* 881 * check phase 2 SA payload and select single proposal. 882 * make new SA payload to be replyed not including general header. 883 * This function is called by responder only. 884 * OUT: 885 * 0: succeed. 886 * -1: error occured. 887 */ 888 int 889 ipsecdoi_selectph2proposal(iph2) 890 struct ph2handle *iph2; 891 { 892 struct prop_pair **pair; 893 struct prop_pair *ret; 894 895 /* get proposal pair */ 896 pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2); 897 if (pair == NULL) 898 return -1; 899 900 /* check and select a proposal. */ 901 ret = get_ph2approval(iph2, pair); 902 free_proppair(pair); 903 if (ret == NULL) 904 return -1; 905 906 /* make a SA to be replayed. */ 907 /* SPI must be updated later. */ 908 iph2->sa_ret = get_sabyproppair(ret, iph2->ph1); 909 free_proppair0(ret); 910 if (iph2->sa_ret == NULL) 911 return -1; 912 913 return 0; 914 } 915 916 /* 917 * check phase 2 SA payload returned from responder. 918 * This function is called by initiator only. 919 * OUT: 920 * 0: valid. 921 * -1: invalid. 922 */ 923 int 924 ipsecdoi_checkph2proposal(iph2) 925 struct ph2handle *iph2; 926 { 927 struct prop_pair **rpair = NULL, **spair = NULL; 928 struct prop_pair *p; 929 int i, n, num; 930 int error = -1; 931 vchar_t *sa_ret = NULL; 932 933 /* get proposal pair of SA sent. */ 934 spair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2); 935 if (spair == NULL) { 936 plog(LLV_ERROR, LOCATION, NULL, 937 "failed to get prop pair.\n"); 938 goto end; 939 } 940 941 /* XXX should check the number of transform */ 942 943 /* get proposal pair of SA replayed */ 944 rpair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2); 945 if (rpair == NULL) { 946 plog(LLV_ERROR, LOCATION, NULL, 947 "failed to get prop pair.\n"); 948 goto end; 949 } 950 951 /* check proposal is only one ? */ 952 n = 0; 953 num = 0; 954 for (i = 0; i < MAXPROPPAIRLEN; i++) { 955 if (rpair[i]) { 956 n = i; 957 num++; 958 } 959 } 960 if (num == 0) { 961 plog(LLV_ERROR, LOCATION, NULL, 962 "no proposal received.\n"); 963 goto end; 964 } 965 if (num != 1) { 966 plog(LLV_ERROR, LOCATION, NULL, 967 "some proposals received.\n"); 968 goto end; 969 } 970 971 if (spair[n] == NULL) { 972 plog(LLV_WARNING, LOCATION, NULL, 973 "invalid proposal number:%d received.\n", i); 974 } 975 976 977 if (rpair[n]->tnext != NULL) { 978 plog(LLV_ERROR, LOCATION, NULL, 979 "multi transforms replyed.\n"); 980 goto end; 981 } 982 983 if (cmp_aproppair_i(rpair[n], spair[n])) { 984 plog(LLV_ERROR, LOCATION, NULL, 985 "proposal mismathed.\n"); 986 goto end; 987 } 988 989 /* 990 * check and select a proposal. 991 * ensure that there is no modification of the proposal by 992 * cmp_aproppair_i() 993 */ 994 p = get_ph2approval(iph2, rpair); 995 if (p == NULL) 996 goto end; 997 998 /* make a SA to be replayed. */ 999 sa_ret = iph2->sa_ret; 1000 iph2->sa_ret = get_sabyproppair(p, iph2->ph1); 1001 free_proppair0(p); 1002 if (iph2->sa_ret == NULL) 1003 goto end; 1004 1005 error = 0; 1006 1007 end: 1008 if (rpair) 1009 free_proppair(rpair); 1010 if (spair) 1011 free_proppair(spair); 1012 if (sa_ret) 1013 vfree(sa_ret); 1014 1015 return error; 1016 } 1017 1018 /* 1019 * compare two prop_pair which is assumed to have same proposal number. 1020 * the case of bundle or single SA, NOT multi transforms. 1021 * a: a proposal that is multi protocols and single transform, usually replyed. 1022 * b: a proposal that is multi protocols and multi transform, usually sent. 1023 * NOTE: this function is for initiator. 1024 * OUT 1025 * 0: equal 1026 * 1: not equal 1027 * XXX cannot understand the comment! 1028 */ 1029 static int 1030 cmp_aproppair_i(a, b) 1031 struct prop_pair *a, *b; 1032 { 1033 struct prop_pair *p, *q, *r; 1034 int len; 1035 1036 for (p = a, q = b; p && q; p = p->next, q = q->next) { 1037 for (r = q; r; r = r->tnext) { 1038 /* compare trns */ 1039 if (p->trns->t_no == r->trns->t_no) 1040 break; 1041 } 1042 if (!r) { 1043 /* no suitable transform found */ 1044 plog(LLV_ERROR, LOCATION, NULL, 1045 "no suitable transform found.\n"); 1046 return -1; 1047 } 1048 1049 /* compare prop */ 1050 if (p->prop->p_no != r->prop->p_no) { 1051 plog(LLV_WARNING, LOCATION, NULL, 1052 "proposal #%d mismatched, " 1053 "expected #%d.\n", 1054 r->prop->p_no, p->prop->p_no); 1055 /*FALLTHROUGH*/ 1056 } 1057 1058 if (p->prop->proto_id != r->prop->proto_id) { 1059 plog(LLV_ERROR, LOCATION, NULL, 1060 "proto_id mismathed: my:%d peer:%d\n", 1061 r->prop->proto_id, p->prop->proto_id); 1062 return -1; 1063 } 1064 1065 if (p->prop->spi_size != r->prop->spi_size) { 1066 plog(LLV_ERROR, LOCATION, NULL, 1067 "invalid spi size: %d.\n", 1068 p->prop->spi_size); 1069 return -1; 1070 } 1071 1072 /* check #of transforms */ 1073 if (p->prop->num_t != 1) { 1074 plog(LLV_WARNING, LOCATION, NULL, 1075 "#of transform is %d, " 1076 "but expected 1.\n", p->prop->num_t); 1077 /*FALLTHROUGH*/ 1078 } 1079 1080 if (p->trns->t_id != r->trns->t_id) { 1081 plog(LLV_WARNING, LOCATION, NULL, 1082 "transform number has been modified.\n"); 1083 /*FALLTHROUGH*/ 1084 } 1085 if (p->trns->reserved != r->trns->reserved) { 1086 plog(LLV_WARNING, LOCATION, NULL, 1087 "reserved field should be zero.\n"); 1088 /*FALLTHROUGH*/ 1089 } 1090 1091 /* compare attribute */ 1092 len = ntohs(r->trns->h.len) - sizeof(*p->trns); 1093 if (memcmp(p->trns + 1, r->trns + 1, len) != 0) { 1094 plog(LLV_WARNING, LOCATION, NULL, 1095 "attribute has been modified.\n"); 1096 /*FALLTHROUGH*/ 1097 } 1098 } 1099 if ((p && !q) || (!p && q)) { 1100 /* # of protocols mismatched */ 1101 plog(LLV_ERROR, LOCATION, NULL, 1102 "#of protocols mismatched.\n"); 1103 return -1; 1104 } 1105 1106 return 0; 1107 } 1108 1109 /* 1110 * acceptable check for policy configuration. 1111 * return a new SA payload to be reply to peer. 1112 */ 1113 static struct prop_pair * 1114 get_ph2approval(iph2, pair) 1115 struct ph2handle *iph2; 1116 struct prop_pair **pair; 1117 { 1118 struct prop_pair *ret; 1119 int i; 1120 1121 iph2->approval = NULL; 1122 1123 plog(LLV_DEBUG, LOCATION, NULL, 1124 "begin compare proposals.\n"); 1125 1126 for (i = 0; i < MAXPROPPAIRLEN; i++) { 1127 if (pair[i] == NULL) 1128 continue; 1129 plog(LLV_DEBUG, LOCATION, NULL, 1130 "pair[%d]: %p\n", i, pair[i]); 1131 print_proppair(LLV_DEBUG, pair[i]);; 1132 1133 /* compare proposal and select one */ 1134 ret = get_ph2approvalx(iph2, pair[i]); 1135 if (ret != NULL) { 1136 /* found */ 1137 return ret; 1138 } 1139 } 1140 1141 plog(LLV_ERROR, LOCATION, NULL, "no suitable policy found.\n"); 1142 1143 return NULL; 1144 } 1145 1146 /* 1147 * compare my proposal and peers just one proposal. 1148 * set a approval. 1149 */ 1150 static struct prop_pair * 1151 get_ph2approvalx(iph2, pp) 1152 struct ph2handle *iph2; 1153 struct prop_pair *pp; 1154 { 1155 struct prop_pair *ret = NULL; 1156 struct saprop *pr0, *pr = NULL; 1157 struct saprop *q1, *q2; 1158 1159 pr0 = aproppair2saprop(pp); 1160 if (pr0 == NULL) 1161 return NULL; 1162 1163 for (q1 = pr0; q1; q1 = q1->next) { 1164 for (q2 = iph2->proposal; q2; q2 = q2->next) { 1165 plog(LLV_DEBUG, LOCATION, NULL, 1166 "peer's single bundle:\n"); 1167 printsaprop0(LLV_DEBUG, q1); 1168 plog(LLV_DEBUG, LOCATION, NULL, 1169 "my single bundle:\n"); 1170 printsaprop0(LLV_DEBUG, q2); 1171 1172 pr = cmpsaprop_alloc(iph2->ph1, q1, q2, iph2->side); 1173 if (pr != NULL) 1174 goto found; 1175 1176 plog(LLV_ERROR, LOCATION, NULL, 1177 "not matched\n"); 1178 } 1179 } 1180 /* no proposal matching */ 1181 err: 1182 flushsaprop(pr0); 1183 return NULL; 1184 1185 found: 1186 flushsaprop(pr0); 1187 plog(LLV_DEBUG, LOCATION, NULL, "matched\n"); 1188 iph2->approval = pr; 1189 1190 { 1191 struct saproto *sp; 1192 struct prop_pair *p, *x; 1193 struct prop_pair *n = NULL; 1194 1195 ret = NULL; 1196 1197 for (p = pp; p; p = p->next) { 1198 /* 1199 * find a proposal with matching proto_id. 1200 * we have analyzed validity already, in cmpsaprop_alloc(). 1201 */ 1202 for (sp = pr->head; sp; sp = sp->next) { 1203 if (sp->proto_id == p->prop->proto_id) 1204 break; 1205 } 1206 if (!sp) 1207 goto err; 1208 if (sp->head->next) 1209 goto err; /* XXX */ 1210 1211 for (x = p; x; x = x->tnext) 1212 if (sp->head->trns_no == x->trns->t_no) 1213 break; 1214 if (!x) 1215 goto err; /* XXX */ 1216 1217 n = racoon_calloc(1, sizeof(struct prop_pair)); 1218 if (n == NULL) { 1219 plog(LLV_ERROR, LOCATION, NULL, 1220 "failed to get buffer.\n"); 1221 goto err; 1222 } 1223 1224 n->prop = x->prop; 1225 n->trns = x->trns; 1226 1227 /* need to preserve the order */ 1228 for (x = ret; x && x->next; x = x->next) 1229 ; 1230 if (x && x->prop == n->prop) { 1231 for (/*nothing*/; x && x->tnext; x = x->tnext) 1232 ; 1233 x->tnext = n; 1234 } else { 1235 if (x) 1236 x->next = n; 1237 else { 1238 ret = n; 1239 } 1240 } 1241 1242 /* #of transforms should be updated ? */ 1243 } 1244 } 1245 1246 return ret; 1247 } 1248 1249 void 1250 free_proppair(pair) 1251 struct prop_pair **pair; 1252 { 1253 int i; 1254 1255 for (i = 0; i < MAXPROPPAIRLEN; i++) { 1256 free_proppair0(pair[i]); 1257 pair[i] = NULL; 1258 } 1259 racoon_free(pair); 1260 } 1261 1262 static void 1263 free_proppair0(pair) 1264 struct prop_pair *pair; 1265 { 1266 struct prop_pair *p, *q, *r, *s; 1267 1268 p = pair; 1269 while (p) { 1270 q = p->next; 1271 r = p; 1272 while (r) { 1273 s = r->tnext; 1274 racoon_free(r); 1275 r = s; 1276 } 1277 p = q; 1278 } 1279 } 1280 1281 /* 1282 * get proposal pairs from SA payload. 1283 * tiny check for proposal payload. 1284 */ 1285 struct prop_pair ** 1286 get_proppair(sa, mode) 1287 vchar_t *sa; 1288 int mode; 1289 { 1290 struct prop_pair **pair = NULL; 1291 int num_p = 0; /* number of proposal for use */ 1292 int tlen; 1293 caddr_t bp; 1294 int i; 1295 struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v; 1296 1297 plog(LLV_DEBUG, LOCATION, NULL, "total SA len=%zu\n", sa->l); 1298 plogdump(LLV_DEBUG, sa->v, sa->l); 1299 1300 /* check SA payload size */ 1301 if (sa->l < sizeof(*sab)) { 1302 plog(LLV_ERROR, LOCATION, NULL, 1303 "Invalid SA length = %zu.\n", sa->l); 1304 goto bad; 1305 } 1306 1307 /* check DOI */ 1308 if (check_doi(ntohl(sab->doi)) < 0) 1309 goto bad; 1310 1311 /* check SITUATION */ 1312 if (check_situation(ntohl(sab->sit)) < 0) 1313 goto bad; 1314 1315 pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair)); 1316 if (pair == NULL) { 1317 plog(LLV_ERROR, LOCATION, NULL, 1318 "failed to get buffer.\n"); 1319 goto bad; 1320 } 1321 memset(pair, 0, sizeof(pair)); 1322 1323 bp = (caddr_t)(sab + 1); 1324 tlen = sa->l - sizeof(*sab); 1325 1326 { 1327 struct isakmp_pl_p *prop; 1328 int proplen; 1329 vchar_t *pbuf = NULL; 1330 struct isakmp_parse_t *pa; 1331 1332 pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, tlen); 1333 if (pbuf == NULL) 1334 goto bad; 1335 1336 for (pa = (struct isakmp_parse_t *)pbuf->v; 1337 pa->type != ISAKMP_NPTYPE_NONE; 1338 pa++) { 1339 /* check the value of next payload */ 1340 if (pa->type != ISAKMP_NPTYPE_P) { 1341 plog(LLV_ERROR, LOCATION, NULL, 1342 "Invalid payload type=%u\n", pa->type); 1343 vfree(pbuf); 1344 goto bad; 1345 } 1346 1347 prop = (struct isakmp_pl_p *)pa->ptr; 1348 proplen = pa->len; 1349 1350 plog(LLV_DEBUG, LOCATION, NULL, 1351 "proposal #%u len=%d\n", prop->p_no, proplen); 1352 1353 if (proplen == 0) { 1354 plog(LLV_ERROR, LOCATION, NULL, 1355 "invalid proposal with length %d\n", proplen); 1356 vfree(pbuf); 1357 goto bad; 1358 } 1359 1360 /* check Protocol ID */ 1361 if (!check_protocol[mode]) { 1362 plog(LLV_ERROR, LOCATION, NULL, 1363 "unsupported mode %d\n", mode); 1364 continue; 1365 } 1366 1367 if (check_protocol[mode](prop->proto_id) < 0) 1368 continue; 1369 1370 /* check SPI length when IKE. */ 1371 if (check_spi_size(prop->proto_id, prop->spi_size) < 0) 1372 continue; 1373 1374 /* get transform */ 1375 if (get_transform(prop, pair, &num_p) < 0) { 1376 vfree(pbuf); 1377 goto bad; 1378 } 1379 } 1380 vfree(pbuf); 1381 pbuf = NULL; 1382 } 1383 1384 { 1385 int notrans, nprop; 1386 struct prop_pair *p, *q; 1387 1388 /* check for proposals with no transforms */ 1389 for (i = 0; i < MAXPROPPAIRLEN; i++) { 1390 if (!pair[i]) 1391 continue; 1392 1393 plog(LLV_DEBUG, LOCATION, NULL, "pair %d:\n", i); 1394 print_proppair(LLV_DEBUG, pair[i]); 1395 1396 notrans = nprop = 0; 1397 for (p = pair[i]; p; p = p->next) { 1398 if (p->trns == NULL) { 1399 notrans++; 1400 break; 1401 } 1402 for (q = p; q; q = q->tnext) 1403 nprop++; 1404 } 1405 1406 #if 0 1407 /* 1408 * XXX at this moment, we cannot accept proposal group 1409 * with multiple proposals. this should be fixed. 1410 */ 1411 if (pair[i]->next) { 1412 plog(LLV_WARNING, LOCATION, NULL, 1413 "proposal #%u ignored " 1414 "(multiple proposal not supported)\n", 1415 pair[i]->prop->p_no); 1416 notrans++; 1417 } 1418 #endif 1419 1420 if (notrans) { 1421 for (p = pair[i]; p; p = q) { 1422 q = p->next; 1423 racoon_free(p); 1424 } 1425 pair[i] = NULL; 1426 num_p--; 1427 } else { 1428 plog(LLV_DEBUG, LOCATION, NULL, 1429 "proposal #%u: %d transform\n", 1430 pair[i]->prop->p_no, nprop); 1431 } 1432 } 1433 } 1434 1435 /* bark if no proposal is found. */ 1436 if (num_p <= 0) { 1437 plog(LLV_ERROR, LOCATION, NULL, 1438 "no Proposal found.\n"); 1439 goto bad; 1440 } 1441 1442 return pair; 1443 bad: 1444 if (pair != NULL) 1445 racoon_free(pair); 1446 return NULL; 1447 } 1448 1449 /* 1450 * check transform payload. 1451 * OUT: 1452 * positive: return the pointer to the payload of valid transform. 1453 * 0 : No valid transform found. 1454 */ 1455 static int 1456 get_transform(prop, pair, num_p) 1457 struct isakmp_pl_p *prop; 1458 struct prop_pair **pair; 1459 int *num_p; 1460 { 1461 int tlen; /* total length of all transform in a proposal */ 1462 caddr_t bp; 1463 struct isakmp_pl_t *trns; 1464 int trnslen; 1465 vchar_t *pbuf = NULL; 1466 struct isakmp_parse_t *pa; 1467 struct prop_pair *p = NULL, *q; 1468 int num_t; 1469 1470 bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size; 1471 tlen = ntohs(prop->h.len) 1472 - (sizeof(struct isakmp_pl_p) + prop->spi_size); 1473 pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, tlen); 1474 if (pbuf == NULL) 1475 return -1; 1476 1477 /* check and get transform for use */ 1478 num_t = 0; 1479 for (pa = (struct isakmp_parse_t *)pbuf->v; 1480 pa->type != ISAKMP_NPTYPE_NONE; 1481 pa++) { 1482 1483 num_t++; 1484 1485 /* check the value of next payload */ 1486 if (pa->type != ISAKMP_NPTYPE_T) { 1487 plog(LLV_ERROR, LOCATION, NULL, 1488 "Invalid payload type=%u\n", pa->type); 1489 break; 1490 } 1491 1492 trns = (struct isakmp_pl_t *)pa->ptr; 1493 trnslen = pa->len; 1494 1495 plog(LLV_DEBUG, LOCATION, NULL, 1496 "transform #%u len=%u\n", trns->t_no, trnslen); 1497 1498 /* check transform ID */ 1499 if (prop->proto_id >= ARRAYLEN(check_transform)) { 1500 plog(LLV_WARNING, LOCATION, NULL, 1501 "unsupported proto_id %u\n", 1502 prop->proto_id); 1503 continue; 1504 } 1505 if (prop->proto_id >= ARRAYLEN(check_attributes)) { 1506 plog(LLV_WARNING, LOCATION, NULL, 1507 "unsupported proto_id %u\n", 1508 prop->proto_id); 1509 continue; 1510 } 1511 1512 if (!check_transform[prop->proto_id] 1513 || !check_attributes[prop->proto_id]) { 1514 plog(LLV_WARNING, LOCATION, NULL, 1515 "unsupported proto_id %u\n", 1516 prop->proto_id); 1517 continue; 1518 } 1519 if (check_transform[prop->proto_id](trns->t_id) < 0) 1520 continue; 1521 1522 /* check data attributes */ 1523 if (check_attributes[prop->proto_id](trns) != 0) 1524 continue; 1525 1526 p = racoon_calloc(1, sizeof(*p)); 1527 if (p == NULL) { 1528 plog(LLV_ERROR, LOCATION, NULL, 1529 "failed to get buffer.\n"); 1530 vfree(pbuf); 1531 return -1; 1532 } 1533 p->prop = prop; 1534 p->trns = trns; 1535 1536 /* need to preserve the order */ 1537 for (q = pair[prop->p_no]; q && q->next; q = q->next) 1538 ; 1539 if (q && q->prop == p->prop) { 1540 for (/*nothing*/; q && q->tnext; q = q->tnext) 1541 ; 1542 q->tnext = p; 1543 } else { 1544 if (q) 1545 q->next = p; 1546 else { 1547 pair[prop->p_no] = p; 1548 (*num_p)++; 1549 } 1550 } 1551 } 1552 1553 vfree(pbuf); 1554 1555 return 0; 1556 } 1557 1558 /* 1559 * make a new SA payload from prop_pair. 1560 * NOTE: this function make spi value clear. 1561 */ 1562 vchar_t * 1563 get_sabyproppair(pair, iph1) 1564 struct prop_pair *pair; 1565 struct ph1handle *iph1; 1566 { 1567 vchar_t *newsa; 1568 int newtlen; 1569 u_int8_t *np_p = NULL; 1570 struct prop_pair *p; 1571 int prophlen, trnslen; 1572 caddr_t bp; 1573 1574 newtlen = sizeof(struct ipsecdoi_sa_b); 1575 for (p = pair; p; p = p->next) { 1576 newtlen += sizeof(struct isakmp_pl_p); 1577 newtlen += p->prop->spi_size; 1578 newtlen += ntohs(p->trns->h.len); 1579 } 1580 1581 newsa = vmalloc(newtlen); 1582 if (newsa == NULL) { 1583 plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n"); 1584 return NULL; 1585 } 1586 bp = newsa->v; 1587 1588 ((struct isakmp_gen *)bp)->len = htons(newtlen); 1589 1590 /* update some of values in SA header */ 1591 ((struct ipsecdoi_sa_b *)bp)->doi = htonl(iph1->rmconf->doitype); 1592 ((struct ipsecdoi_sa_b *)bp)->sit = htonl(iph1->rmconf->sittype); 1593 bp += sizeof(struct ipsecdoi_sa_b); 1594 1595 /* create proposal payloads */ 1596 for (p = pair; p; p = p->next) { 1597 prophlen = sizeof(struct isakmp_pl_p) 1598 + p->prop->spi_size; 1599 trnslen = ntohs(p->trns->h.len); 1600 1601 if (np_p) 1602 *np_p = ISAKMP_NPTYPE_P; 1603 1604 /* create proposal */ 1605 1606 memcpy(bp, p->prop, prophlen); 1607 ((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE; 1608 ((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen); 1609 ((struct isakmp_pl_p *)bp)->num_t = 1; 1610 np_p = &((struct isakmp_pl_p *)bp)->h.np; 1611 memset(bp + sizeof(struct isakmp_pl_p), 0, p->prop->spi_size); 1612 bp += prophlen; 1613 1614 /* create transform */ 1615 memcpy(bp, p->trns, trnslen); 1616 ((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE; 1617 ((struct isakmp_pl_t *)bp)->h.len = htons(trnslen); 1618 bp += trnslen; 1619 } 1620 1621 return newsa; 1622 } 1623 1624 /* 1625 * update responder's spi 1626 */ 1627 int 1628 ipsecdoi_updatespi(iph2) 1629 struct ph2handle *iph2; 1630 { 1631 struct prop_pair **pair, *p; 1632 struct saprop *pp; 1633 struct saproto *pr; 1634 int i; 1635 int error = -1; 1636 u_int8_t *spi; 1637 1638 pair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2); 1639 if (pair == NULL) 1640 return -1; 1641 for (i = 0; i < MAXPROPPAIRLEN; i++) { 1642 if (pair[i]) 1643 break; 1644 } 1645 if (i == MAXPROPPAIRLEN || pair[i]->tnext) { 1646 /* multiple transform must be filtered by selectph2proposal.*/ 1647 goto end; 1648 } 1649 1650 pp = iph2->approval; 1651 1652 /* create proposal payloads */ 1653 for (p = pair[i]; p; p = p->next) { 1654 /* 1655 * find a proposal/transform with matching proto_id/t_id. 1656 * we have analyzed validity already, in cmpsaprop_alloc(). 1657 */ 1658 for (pr = pp->head; pr; pr = pr->next) { 1659 if (p->prop->proto_id == pr->proto_id && 1660 p->trns->t_id == pr->head->trns_id) { 1661 break; 1662 } 1663 } 1664 if (!pr) 1665 goto end; 1666 1667 /* 1668 * XXX SPI bits are left-filled, for use with IPComp. 1669 * we should be switching to variable-length spi field... 1670 */ 1671 spi = (u_int8_t *)&pr->spi; 1672 spi += sizeof(pr->spi); 1673 spi -= pr->spisize; 1674 memcpy((caddr_t)p->prop + sizeof(*p->prop), spi, pr->spisize); 1675 } 1676 1677 error = 0; 1678 end: 1679 free_proppair(pair); 1680 return error; 1681 } 1682 1683 /* 1684 * make a new SA payload from prop_pair. 1685 */ 1686 vchar_t * 1687 get_sabysaprop(pp0, sa0) 1688 struct saprop *pp0; 1689 vchar_t *sa0; 1690 { 1691 struct prop_pair **pair = NULL; 1692 vchar_t *newsa = NULL; 1693 int newtlen; 1694 u_int8_t *np_p = NULL; 1695 struct prop_pair *p = NULL; 1696 struct saprop *pp; 1697 struct saproto *pr; 1698 struct satrns *tr; 1699 int prophlen, trnslen; 1700 caddr_t bp; 1701 int error = -1; 1702 1703 /* get proposal pair */ 1704 pair = get_proppair(sa0, IPSECDOI_TYPE_PH2); 1705 if (pair == NULL) 1706 goto out; 1707 1708 newtlen = sizeof(struct ipsecdoi_sa_b); 1709 for (pp = pp0; pp; pp = pp->next) { 1710 1711 if (pair[pp->prop_no] == NULL) 1712 goto out; 1713 1714 for (pr = pp->head; pr; pr = pr->next) { 1715 newtlen += (sizeof(struct isakmp_pl_p) 1716 + pr->spisize); 1717 1718 for (tr = pr->head; tr; tr = tr->next) { 1719 for (p = pair[pp->prop_no]; p; p = p->tnext) { 1720 if (tr->trns_no == p->trns->t_no) 1721 break; 1722 } 1723 if (p == NULL) 1724 goto out; 1725 1726 newtlen += ntohs(p->trns->h.len); 1727 } 1728 } 1729 } 1730 1731 newsa = vmalloc(newtlen); 1732 if (newsa == NULL) { 1733 plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n"); 1734 goto out; 1735 } 1736 bp = newsa->v; 1737 1738 /* some of values of SA must be updated in the out of this function */ 1739 ((struct isakmp_gen *)bp)->len = htons(newtlen); 1740 bp += sizeof(struct ipsecdoi_sa_b); 1741 1742 /* create proposal payloads */ 1743 for (pp = pp0; pp; pp = pp->next) { 1744 1745 for (pr = pp->head; pr; pr = pr->next) { 1746 prophlen = sizeof(struct isakmp_pl_p) 1747 + p->prop->spi_size; 1748 1749 for (tr = pr->head; tr; tr = tr->next) { 1750 for (p = pair[pp->prop_no]; p; p = p->tnext) { 1751 if (tr->trns_no == p->trns->t_no) 1752 break; 1753 } 1754 if (p == NULL) 1755 goto out; 1756 1757 trnslen = ntohs(p->trns->h.len); 1758 1759 if (np_p) 1760 *np_p = ISAKMP_NPTYPE_P; 1761 1762 /* create proposal */ 1763 1764 memcpy(bp, p->prop, prophlen); 1765 ((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE; 1766 ((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen); 1767 ((struct isakmp_pl_p *)bp)->num_t = 1; 1768 np_p = &((struct isakmp_pl_p *)bp)->h.np; 1769 bp += prophlen; 1770 1771 /* create transform */ 1772 memcpy(bp, p->trns, trnslen); 1773 ((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE; 1774 ((struct isakmp_pl_t *)bp)->h.len = htons(trnslen); 1775 bp += trnslen; 1776 } 1777 } 1778 } 1779 1780 error = 0; 1781 out: 1782 if (pair != NULL) 1783 racoon_free(pair); 1784 1785 if (error != 0) { 1786 if (newsa != NULL) { 1787 vfree(newsa); 1788 newsa = NULL; 1789 } 1790 } 1791 1792 return newsa; 1793 } 1794 1795 /* 1796 * If some error happens then return 0. Although 0 means that lifetime is zero, 1797 * such a value should not be accepted. 1798 * Also 0 of lifebyte should not be included in a packet although 0 means not 1799 * to care of it. 1800 */ 1801 static u_int32_t 1802 ipsecdoi_set_ld(buf) 1803 vchar_t *buf; 1804 { 1805 u_int32_t ld; 1806 1807 if (buf == 0) 1808 return 0; 1809 1810 switch (buf->l) { 1811 case 2: 1812 ld = ntohs(*(u_int16_t *)buf->v); 1813 break; 1814 case 4: 1815 ld = ntohl(*(u_int32_t *)buf->v); 1816 break; 1817 default: 1818 plog(LLV_ERROR, LOCATION, NULL, 1819 "length %zu of life duration " 1820 "isn't supported.\n", buf->l); 1821 return 0; 1822 } 1823 1824 return ld; 1825 } 1826 1827 /*%%%*/ 1828 /* 1829 * check DOI 1830 */ 1831 static int 1832 check_doi(doi) 1833 u_int32_t doi; 1834 { 1835 switch (doi) { 1836 case IPSEC_DOI: 1837 return 0; 1838 default: 1839 plog(LLV_ERROR, LOCATION, NULL, 1840 "invalid value of DOI 0x%08x.\n", doi); 1841 return -1; 1842 } 1843 /* NOT REACHED */ 1844 } 1845 1846 /* 1847 * check situation 1848 */ 1849 static int 1850 check_situation(sit) 1851 u_int32_t sit; 1852 { 1853 switch (sit) { 1854 case IPSECDOI_SIT_IDENTITY_ONLY: 1855 return 0; 1856 1857 case IPSECDOI_SIT_SECRECY: 1858 case IPSECDOI_SIT_INTEGRITY: 1859 plog(LLV_ERROR, LOCATION, NULL, 1860 "situation 0x%08x unsupported yet.\n", sit); 1861 return -1; 1862 1863 default: 1864 plog(LLV_ERROR, LOCATION, NULL, 1865 "invalid situation 0x%08x.\n", sit); 1866 return -1; 1867 } 1868 /* NOT REACHED */ 1869 } 1870 1871 /* 1872 * check protocol id in main mode 1873 */ 1874 static int 1875 check_prot_main(proto_id) 1876 int proto_id; 1877 { 1878 switch (proto_id) { 1879 case IPSECDOI_PROTO_ISAKMP: 1880 return 0; 1881 1882 default: 1883 plog(LLV_ERROR, LOCATION, NULL, 1884 "Illegal protocol id=%u.\n", proto_id); 1885 return -1; 1886 } 1887 /* NOT REACHED */ 1888 } 1889 1890 /* 1891 * check protocol id in quick mode 1892 */ 1893 static int 1894 check_prot_quick(proto_id) 1895 int proto_id; 1896 { 1897 switch (proto_id) { 1898 case IPSECDOI_PROTO_IPSEC_AH: 1899 case IPSECDOI_PROTO_IPSEC_ESP: 1900 return 0; 1901 1902 case IPSECDOI_PROTO_IPCOMP: 1903 return 0; 1904 1905 default: 1906 plog(LLV_ERROR, LOCATION, NULL, 1907 "invalid protocol id %d.\n", proto_id); 1908 return -1; 1909 } 1910 /* NOT REACHED */ 1911 } 1912 1913 static int 1914 check_spi_size(proto_id, size) 1915 int proto_id, size; 1916 { 1917 switch (proto_id) { 1918 case IPSECDOI_PROTO_ISAKMP: 1919 if (size != 0) { 1920 /* WARNING */ 1921 plog(LLV_WARNING, LOCATION, NULL, 1922 "SPI size isn't zero, but IKE proposal.\n"); 1923 } 1924 return 0; 1925 1926 case IPSECDOI_PROTO_IPSEC_AH: 1927 case IPSECDOI_PROTO_IPSEC_ESP: 1928 if (size != 4) { 1929 plog(LLV_ERROR, LOCATION, NULL, 1930 "invalid SPI size=%d for IPSEC proposal.\n", 1931 size); 1932 return -1; 1933 } 1934 return 0; 1935 1936 case IPSECDOI_PROTO_IPCOMP: 1937 if (size != 2 && size != 4) { 1938 plog(LLV_ERROR, LOCATION, NULL, 1939 "invalid SPI size=%d for IPCOMP proposal.\n", 1940 size); 1941 return -1; 1942 } 1943 return 0; 1944 1945 default: 1946 /* ??? */ 1947 return -1; 1948 } 1949 /* NOT REACHED */ 1950 } 1951 1952 /* 1953 * check transform ID in ISAKMP. 1954 */ 1955 static int 1956 check_trns_isakmp(t_id) 1957 int t_id; 1958 { 1959 switch (t_id) { 1960 case IPSECDOI_KEY_IKE: 1961 return 0; 1962 default: 1963 plog(LLV_ERROR, LOCATION, NULL, 1964 "invalid transform-id=%u in proto_id=%u.\n", 1965 t_id, IPSECDOI_KEY_IKE); 1966 return -1; 1967 } 1968 /* NOT REACHED */ 1969 } 1970 1971 /* 1972 * check transform ID in AH. 1973 */ 1974 static int 1975 check_trns_ah(t_id) 1976 int t_id; 1977 { 1978 switch (t_id) { 1979 case IPSECDOI_AH_MD5: 1980 case IPSECDOI_AH_SHA: 1981 case IPSECDOI_AH_SHA256: 1982 case IPSECDOI_AH_SHA384: 1983 case IPSECDOI_AH_SHA512: 1984 return 0; 1985 case IPSECDOI_AH_DES: 1986 plog(LLV_ERROR, LOCATION, NULL, 1987 "not support transform-id=%u in AH.\n", t_id); 1988 return -1; 1989 default: 1990 plog(LLV_ERROR, LOCATION, NULL, 1991 "invalid transform-id=%u in AH.\n", t_id); 1992 return -1; 1993 } 1994 /* NOT REACHED */ 1995 } 1996 1997 /* 1998 * check transform ID in ESP. 1999 */ 2000 static int 2001 check_trns_esp(t_id) 2002 int t_id; 2003 { 2004 switch (t_id) { 2005 case IPSECDOI_ESP_DES: 2006 case IPSECDOI_ESP_3DES: 2007 case IPSECDOI_ESP_NULL: 2008 case IPSECDOI_ESP_RC5: 2009 case IPSECDOI_ESP_CAST: 2010 case IPSECDOI_ESP_BLOWFISH: 2011 case IPSECDOI_ESP_AES: 2012 case IPSECDOI_ESP_TWOFISH: 2013 case IPSECDOI_ESP_CAMELLIA: 2014 return 0; 2015 case IPSECDOI_ESP_DES_IV32: 2016 case IPSECDOI_ESP_DES_IV64: 2017 case IPSECDOI_ESP_IDEA: 2018 case IPSECDOI_ESP_3IDEA: 2019 case IPSECDOI_ESP_RC4: 2020 plog(LLV_ERROR, LOCATION, NULL, 2021 "not support transform-id=%u in ESP.\n", t_id); 2022 return -1; 2023 default: 2024 plog(LLV_ERROR, LOCATION, NULL, 2025 "invalid transform-id=%u in ESP.\n", t_id); 2026 return -1; 2027 } 2028 /* NOT REACHED */ 2029 } 2030 2031 /* 2032 * check transform ID in IPCOMP. 2033 */ 2034 static int 2035 check_trns_ipcomp(t_id) 2036 int t_id; 2037 { 2038 switch (t_id) { 2039 case IPSECDOI_IPCOMP_OUI: 2040 case IPSECDOI_IPCOMP_DEFLATE: 2041 case IPSECDOI_IPCOMP_LZS: 2042 return 0; 2043 default: 2044 plog(LLV_ERROR, LOCATION, NULL, 2045 "invalid transform-id=%u in IPCOMP.\n", t_id); 2046 return -1; 2047 } 2048 /* NOT REACHED */ 2049 } 2050 2051 /* 2052 * check data attributes in IKE. 2053 */ 2054 static int 2055 check_attr_isakmp(trns) 2056 struct isakmp_pl_t *trns; 2057 { 2058 struct isakmp_data *d; 2059 int tlen; 2060 int flag, type; 2061 u_int16_t lorv; 2062 2063 tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t); 2064 d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t)); 2065 2066 while (tlen > 0) { 2067 type = ntohs(d->type) & ~ISAKMP_GEN_MASK; 2068 flag = ntohs(d->type) & ISAKMP_GEN_MASK; 2069 lorv = ntohs(d->lorv); 2070 2071 plog(LLV_DEBUG, LOCATION, NULL, 2072 "type=%s, flag=0x%04x, lorv=%s\n", 2073 s_oakley_attr(type), flag, 2074 s_oakley_attr_v(type, lorv)); 2075 2076 /* 2077 * some of the attributes must be encoded in TV. 2078 * see RFC2409 Appendix A "Attribute Classes". 2079 */ 2080 switch (type) { 2081 case OAKLEY_ATTR_ENC_ALG: 2082 case OAKLEY_ATTR_HASH_ALG: 2083 case OAKLEY_ATTR_AUTH_METHOD: 2084 case OAKLEY_ATTR_GRP_DESC: 2085 case OAKLEY_ATTR_GRP_TYPE: 2086 case OAKLEY_ATTR_SA_LD_TYPE: 2087 case OAKLEY_ATTR_PRF: 2088 case OAKLEY_ATTR_KEY_LEN: 2089 case OAKLEY_ATTR_FIELD_SIZE: 2090 if (!flag) { /* TLV*/ 2091 plog(LLV_ERROR, LOCATION, NULL, 2092 "oakley attribute %d must be TV.\n", 2093 type); 2094 return -1; 2095 } 2096 break; 2097 } 2098 2099 /* sanity check for TLV. length must be specified. */ 2100 if (!flag && lorv == 0) { /*TLV*/ 2101 plog(LLV_ERROR, LOCATION, NULL, 2102 "invalid length %d for TLV attribute %d.\n", 2103 lorv, type); 2104 return -1; 2105 } 2106 2107 switch (type) { 2108 case OAKLEY_ATTR_ENC_ALG: 2109 if (!alg_oakley_encdef_ok(lorv)) { 2110 plog(LLV_ERROR, LOCATION, NULL, 2111 "invalied encryption algorithm=%d.\n", 2112 lorv); 2113 return -1; 2114 } 2115 break; 2116 2117 case OAKLEY_ATTR_HASH_ALG: 2118 if (!alg_oakley_hashdef_ok(lorv)) { 2119 plog(LLV_ERROR, LOCATION, NULL, 2120 "invalied hash algorithm=%d.\n", 2121 lorv); 2122 return -1; 2123 } 2124 break; 2125 2126 case OAKLEY_ATTR_AUTH_METHOD: 2127 switch (lorv) { 2128 case OAKLEY_ATTR_AUTH_METHOD_PSKEY: 2129 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 2130 #ifdef ENABLE_HYBRID 2131 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 2132 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: 2133 #if 0 /* Clashes with OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB */ 2134 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: 2135 #endif 2136 #endif 2137 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: 2138 break; 2139 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: 2140 #ifdef ENABLE_HYBRID 2141 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 2142 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 2143 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 2144 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: 2145 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 2146 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: 2147 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 2148 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 2149 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 2150 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 2151 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 2152 #endif 2153 case OAKLEY_ATTR_AUTH_METHOD_RSAENC: 2154 case OAKLEY_ATTR_AUTH_METHOD_RSAREV: 2155 plog(LLV_ERROR, LOCATION, NULL, 2156 "auth method %s isn't supported.\n", 2157 s_oakley_attr_method(lorv)); 2158 return -1; 2159 default: 2160 plog(LLV_ERROR, LOCATION, NULL, 2161 "invalid auth method %d.\n", 2162 lorv); 2163 return -1; 2164 } 2165 break; 2166 2167 case OAKLEY_ATTR_GRP_DESC: 2168 if (!alg_oakley_dhdef_ok(lorv)) { 2169 plog(LLV_ERROR, LOCATION, NULL, 2170 "invalid DH group %d.\n", 2171 lorv); 2172 return -1; 2173 } 2174 break; 2175 2176 case OAKLEY_ATTR_GRP_TYPE: 2177 switch (lorv) { 2178 case OAKLEY_ATTR_GRP_TYPE_MODP: 2179 break; 2180 default: 2181 plog(LLV_ERROR, LOCATION, NULL, 2182 "unsupported DH group type %d.\n", 2183 lorv); 2184 return -1; 2185 } 2186 break; 2187 2188 case OAKLEY_ATTR_GRP_PI: 2189 case OAKLEY_ATTR_GRP_GEN_ONE: 2190 /* sanity checks? */ 2191 break; 2192 2193 case OAKLEY_ATTR_GRP_GEN_TWO: 2194 case OAKLEY_ATTR_GRP_CURVE_A: 2195 case OAKLEY_ATTR_GRP_CURVE_B: 2196 plog(LLV_ERROR, LOCATION, NULL, 2197 "attr type=%u isn't supported.\n", type); 2198 return -1; 2199 2200 case OAKLEY_ATTR_SA_LD_TYPE: 2201 switch (lorv) { 2202 case OAKLEY_ATTR_SA_LD_TYPE_SEC: 2203 case OAKLEY_ATTR_SA_LD_TYPE_KB: 2204 break; 2205 default: 2206 plog(LLV_ERROR, LOCATION, NULL, 2207 "invalid life type %d.\n", lorv); 2208 return -1; 2209 } 2210 break; 2211 2212 case OAKLEY_ATTR_SA_LD: 2213 /* should check the value */ 2214 break; 2215 2216 case OAKLEY_ATTR_PRF: 2217 case OAKLEY_ATTR_KEY_LEN: 2218 break; 2219 2220 case OAKLEY_ATTR_FIELD_SIZE: 2221 plog(LLV_ERROR, LOCATION, NULL, 2222 "attr type=%u isn't supported.\n", type); 2223 return -1; 2224 2225 case OAKLEY_ATTR_GRP_ORDER: 2226 break; 2227 2228 case OAKLEY_ATTR_GSS_ID: 2229 break; 2230 2231 default: 2232 plog(LLV_ERROR, LOCATION, NULL, 2233 "invalid attribute type %d.\n", type); 2234 return -1; 2235 } 2236 2237 if (flag) { 2238 tlen -= sizeof(*d); 2239 d = (struct isakmp_data *)((char *)d 2240 + sizeof(*d)); 2241 } else { 2242 tlen -= (sizeof(*d) + lorv); 2243 d = (struct isakmp_data *)((char *)d 2244 + sizeof(*d) + lorv); 2245 } 2246 } 2247 2248 return 0; 2249 } 2250 2251 /* 2252 * check data attributes in IPSEC AH/ESP. 2253 */ 2254 static int 2255 check_attr_ah(trns) 2256 struct isakmp_pl_t *trns; 2257 { 2258 return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_AH, trns); 2259 } 2260 2261 static int 2262 check_attr_esp(trns) 2263 struct isakmp_pl_t *trns; 2264 { 2265 return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_ESP, trns); 2266 } 2267 2268 static int 2269 check_attr_ipsec(proto_id, trns) 2270 int proto_id; 2271 struct isakmp_pl_t *trns; 2272 { 2273 struct isakmp_data *d; 2274 int tlen; 2275 int flag, type = 0; 2276 u_int16_t lorv; 2277 int attrseen[16]; /* XXX magic number */ 2278 2279 tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t); 2280 d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t)); 2281 memset(attrseen, 0, sizeof(attrseen)); 2282 2283 while (tlen > 0) { 2284 type = ntohs(d->type) & ~ISAKMP_GEN_MASK; 2285 flag = ntohs(d->type) & ISAKMP_GEN_MASK; 2286 lorv = ntohs(d->lorv); 2287 2288 plog(LLV_DEBUG, LOCATION, NULL, 2289 "type=%s, flag=0x%04x, lorv=%s\n", 2290 s_ipsecdoi_attr(type), flag, 2291 s_ipsecdoi_attr_v(type, lorv)); 2292 2293 if (type < sizeof(attrseen)/sizeof(attrseen[0])) 2294 attrseen[type]++; 2295 2296 switch (type) { 2297 case IPSECDOI_ATTR_ENC_MODE: 2298 if (! flag) { 2299 plog(LLV_ERROR, LOCATION, NULL, 2300 "must be TV when ENC_MODE.\n"); 2301 return -1; 2302 } 2303 2304 switch (lorv) { 2305 case IPSECDOI_ATTR_ENC_MODE_TUNNEL: 2306 case IPSECDOI_ATTR_ENC_MODE_TRNS: 2307 break; 2308 #ifdef ENABLE_NATT 2309 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC: 2310 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC: 2311 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT: 2312 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT: 2313 plog(LLV_DEBUG, LOCATION, NULL, 2314 "UDP encapsulation requested\n"); 2315 break; 2316 #endif 2317 default: 2318 plog(LLV_ERROR, LOCATION, NULL, 2319 "invalid encryption mode=%u.\n", 2320 lorv); 2321 return -1; 2322 } 2323 break; 2324 2325 case IPSECDOI_ATTR_AUTH: 2326 if (! flag) { 2327 plog(LLV_ERROR, LOCATION, NULL, 2328 "must be TV when AUTH.\n"); 2329 return -1; 2330 } 2331 2332 switch (lorv) { 2333 case IPSECDOI_ATTR_AUTH_HMAC_MD5: 2334 if (proto_id == IPSECDOI_PROTO_IPSEC_AH && 2335 trns->t_id != IPSECDOI_AH_MD5) { 2336 ahmismatch: 2337 plog(LLV_ERROR, LOCATION, NULL, 2338 "auth algorithm %u conflicts " 2339 "with transform %u.\n", 2340 lorv, trns->t_id); 2341 return -1; 2342 } 2343 break; 2344 case IPSECDOI_ATTR_AUTH_HMAC_SHA1: 2345 if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { 2346 if (trns->t_id != IPSECDOI_AH_SHA) 2347 goto ahmismatch; 2348 } 2349 break; 2350 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256: 2351 if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { 2352 if (trns->t_id != IPSECDOI_AH_SHA256) 2353 goto ahmismatch; 2354 } 2355 break; 2356 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384: 2357 if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { 2358 if (trns->t_id != IPSECDOI_AH_SHA384) 2359 goto ahmismatch; 2360 } 2361 break; 2362 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512: 2363 if (proto_id == IPSECDOI_PROTO_IPSEC_AH) { 2364 if (trns->t_id != IPSECDOI_AH_SHA512) 2365 goto ahmismatch; 2366 } 2367 break; 2368 case IPSECDOI_ATTR_AUTH_DES_MAC: 2369 case IPSECDOI_ATTR_AUTH_KPDK: 2370 plog(LLV_ERROR, LOCATION, NULL, 2371 "auth algorithm %u isn't supported.\n", 2372 lorv); 2373 return -1; 2374 default: 2375 plog(LLV_ERROR, LOCATION, NULL, 2376 "invalid auth algorithm=%u.\n", 2377 lorv); 2378 return -1; 2379 } 2380 break; 2381 2382 case IPSECDOI_ATTR_SA_LD_TYPE: 2383 if (! flag) { 2384 plog(LLV_ERROR, LOCATION, NULL, 2385 "must be TV when LD_TYPE.\n"); 2386 return -1; 2387 } 2388 2389 switch (lorv) { 2390 case IPSECDOI_ATTR_SA_LD_TYPE_SEC: 2391 case IPSECDOI_ATTR_SA_LD_TYPE_KB: 2392 break; 2393 default: 2394 plog(LLV_ERROR, LOCATION, NULL, 2395 "invalid life type %d.\n", lorv); 2396 return -1; 2397 } 2398 break; 2399 2400 case IPSECDOI_ATTR_SA_LD: 2401 if (flag) { 2402 /* i.e. ISAKMP_GEN_TV */ 2403 plog(LLV_DEBUG, LOCATION, NULL, 2404 "life duration was in TLV.\n"); 2405 } else { 2406 /* i.e. ISAKMP_GEN_TLV */ 2407 if (lorv == 0) { 2408 plog(LLV_ERROR, LOCATION, NULL, 2409 "invalid length of LD\n"); 2410 return -1; 2411 } 2412 } 2413 break; 2414 2415 case IPSECDOI_ATTR_GRP_DESC: 2416 if (! flag) { 2417 plog(LLV_ERROR, LOCATION, NULL, 2418 "must be TV when GRP_DESC.\n"); 2419 return -1; 2420 } 2421 2422 if (!alg_oakley_dhdef_ok(lorv)) { 2423 plog(LLV_ERROR, LOCATION, NULL, 2424 "invalid group description=%u.\n", 2425 lorv); 2426 return -1; 2427 } 2428 break; 2429 2430 case IPSECDOI_ATTR_KEY_LENGTH: 2431 if (! flag) { 2432 plog(LLV_ERROR, LOCATION, NULL, 2433 "must be TV when KEY_LENGTH.\n"); 2434 return -1; 2435 } 2436 break; 2437 2438 #ifdef HAVE_SECCTX 2439 case IPSECDOI_ATTR_SECCTX: 2440 if (flag) { 2441 plog(LLV_ERROR, LOCATION, NULL, 2442 "SECCTX must be in TLV.\n"); 2443 return -1; 2444 } 2445 break; 2446 #endif 2447 2448 case IPSECDOI_ATTR_KEY_ROUNDS: 2449 case IPSECDOI_ATTR_COMP_DICT_SIZE: 2450 case IPSECDOI_ATTR_COMP_PRIVALG: 2451 plog(LLV_ERROR, LOCATION, NULL, 2452 "attr type=%u isn't supported.\n", type); 2453 return -1; 2454 2455 default: 2456 plog(LLV_ERROR, LOCATION, NULL, 2457 "invalid attribute type %d.\n", type); 2458 return -1; 2459 } 2460 2461 if (flag) { 2462 tlen -= sizeof(*d); 2463 d = (struct isakmp_data *)((char *)d 2464 + sizeof(*d)); 2465 } else { 2466 tlen -= (sizeof(*d) + lorv); 2467 d = (struct isakmp_data *)((caddr_t)d 2468 + sizeof(*d) + lorv); 2469 } 2470 } 2471 2472 if (proto_id == IPSECDOI_PROTO_IPSEC_AH && 2473 !attrseen[IPSECDOI_ATTR_AUTH]) { 2474 plog(LLV_ERROR, LOCATION, NULL, 2475 "attr AUTH must be present for AH.\n"); 2476 return -1; 2477 } 2478 2479 if (proto_id == IPSECDOI_PROTO_IPSEC_ESP && 2480 trns->t_id == IPSECDOI_ESP_NULL && 2481 !attrseen[IPSECDOI_ATTR_AUTH]) { 2482 plog(LLV_ERROR, LOCATION, NULL, 2483 "attr AUTH must be present for ESP NULL encryption.\n"); 2484 return -1; 2485 } 2486 2487 return 0; 2488 } 2489 2490 static int 2491 check_attr_ipcomp(trns) 2492 struct isakmp_pl_t *trns; 2493 { 2494 struct isakmp_data *d; 2495 int tlen; 2496 int flag, type = 0; 2497 u_int16_t lorv; 2498 int attrseen[16]; /* XXX magic number */ 2499 2500 tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t); 2501 d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t)); 2502 memset(attrseen, 0, sizeof(attrseen)); 2503 2504 while (tlen > 0) { 2505 type = ntohs(d->type) & ~ISAKMP_GEN_MASK; 2506 flag = ntohs(d->type) & ISAKMP_GEN_MASK; 2507 lorv = ntohs(d->lorv); 2508 2509 plog(LLV_DEBUG, LOCATION, NULL, 2510 "type=%d, flag=0x%04x, lorv=0x%04x\n", 2511 type, flag, lorv); 2512 2513 if (type < sizeof(attrseen)/sizeof(attrseen[0])) 2514 attrseen[type]++; 2515 2516 switch (type) { 2517 case IPSECDOI_ATTR_ENC_MODE: 2518 if (! flag) { 2519 plog(LLV_ERROR, LOCATION, NULL, 2520 "must be TV when ENC_MODE.\n"); 2521 return -1; 2522 } 2523 2524 switch (lorv) { 2525 case IPSECDOI_ATTR_ENC_MODE_TUNNEL: 2526 case IPSECDOI_ATTR_ENC_MODE_TRNS: 2527 break; 2528 #ifdef ENABLE_NATT 2529 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC: 2530 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC: 2531 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT: 2532 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT: 2533 plog(LLV_DEBUG, LOCATION, NULL, 2534 "UDP encapsulation requested\n"); 2535 break; 2536 #endif 2537 default: 2538 plog(LLV_ERROR, LOCATION, NULL, 2539 "invalid encryption mode=%u.\n", 2540 lorv); 2541 return -1; 2542 } 2543 break; 2544 2545 case IPSECDOI_ATTR_SA_LD_TYPE: 2546 if (! flag) { 2547 plog(LLV_ERROR, LOCATION, NULL, 2548 "must be TV when LD_TYPE.\n"); 2549 return -1; 2550 } 2551 2552 switch (lorv) { 2553 case IPSECDOI_ATTR_SA_LD_TYPE_SEC: 2554 case IPSECDOI_ATTR_SA_LD_TYPE_KB: 2555 break; 2556 default: 2557 plog(LLV_ERROR, LOCATION, NULL, 2558 "invalid life type %d.\n", lorv); 2559 return -1; 2560 } 2561 break; 2562 2563 case IPSECDOI_ATTR_SA_LD: 2564 if (flag) { 2565 /* i.e. ISAKMP_GEN_TV */ 2566 plog(LLV_DEBUG, LOCATION, NULL, 2567 "life duration was in TLV.\n"); 2568 } else { 2569 /* i.e. ISAKMP_GEN_TLV */ 2570 if (lorv == 0) { 2571 plog(LLV_ERROR, LOCATION, NULL, 2572 "invalid length of LD\n"); 2573 return -1; 2574 } 2575 } 2576 break; 2577 2578 case IPSECDOI_ATTR_GRP_DESC: 2579 if (! flag) { 2580 plog(LLV_ERROR, LOCATION, NULL, 2581 "must be TV when GRP_DESC.\n"); 2582 return -1; 2583 } 2584 2585 if (!alg_oakley_dhdef_ok(lorv)) { 2586 plog(LLV_ERROR, LOCATION, NULL, 2587 "invalid group description=%u.\n", 2588 lorv); 2589 return -1; 2590 } 2591 break; 2592 2593 case IPSECDOI_ATTR_AUTH: 2594 plog(LLV_ERROR, LOCATION, NULL, 2595 "invalid attr type=%u.\n", type); 2596 return -1; 2597 2598 case IPSECDOI_ATTR_KEY_LENGTH: 2599 case IPSECDOI_ATTR_KEY_ROUNDS: 2600 case IPSECDOI_ATTR_COMP_DICT_SIZE: 2601 case IPSECDOI_ATTR_COMP_PRIVALG: 2602 plog(LLV_ERROR, LOCATION, NULL, 2603 "attr type=%u isn't supported.\n", type); 2604 return -1; 2605 2606 default: 2607 plog(LLV_ERROR, LOCATION, NULL, 2608 "invalid attribute type %d.\n", type); 2609 return -1; 2610 } 2611 2612 if (flag) { 2613 tlen -= sizeof(*d); 2614 d = (struct isakmp_data *)((char *)d 2615 + sizeof(*d)); 2616 } else { 2617 tlen -= (sizeof(*d) + lorv); 2618 d = (struct isakmp_data *)((caddr_t)d 2619 + sizeof(*d) + lorv); 2620 } 2621 } 2622 2623 #if 0 2624 if (proto_id == IPSECDOI_PROTO_IPCOMP && 2625 !attrseen[IPSECDOI_ATTR_AUTH]) { 2626 plog(LLV_ERROR, LOCATION, NULL, 2627 "attr AUTH must be present for AH.\n", type); 2628 return -1; 2629 } 2630 #endif 2631 2632 return 0; 2633 } 2634 2635 /* %%% */ 2636 /* 2637 * create phase1 proposal from remote configuration. 2638 * NOT INCLUDING isakmp general header of SA payload 2639 */ 2640 vchar_t * 2641 ipsecdoi_setph1proposal(props) 2642 struct isakmpsa *props; 2643 { 2644 vchar_t *mysa; 2645 int sablen; 2646 2647 /* count total size of SA minus isakmp general header */ 2648 /* not including isakmp general header of SA payload */ 2649 sablen = sizeof(struct ipsecdoi_sa_b); 2650 sablen += setph1prop(props, NULL); 2651 2652 mysa = vmalloc(sablen); 2653 if (mysa == NULL) { 2654 plog(LLV_ERROR, LOCATION, NULL, 2655 "failed to allocate my sa buffer\n"); 2656 return NULL; 2657 } 2658 2659 /* create SA payload */ 2660 /* not including isakmp general header */ 2661 ((struct ipsecdoi_sa_b *)mysa->v)->doi = htonl(props->rmconf->doitype); 2662 ((struct ipsecdoi_sa_b *)mysa->v)->sit = htonl(props->rmconf->sittype); 2663 2664 (void)setph1prop(props, mysa->v + sizeof(struct ipsecdoi_sa_b)); 2665 2666 return mysa; 2667 } 2668 2669 static int 2670 setph1prop(props, buf) 2671 struct isakmpsa *props; 2672 caddr_t buf; 2673 { 2674 struct isakmp_pl_p *prop = NULL; 2675 struct isakmpsa *s = NULL; 2676 int proplen, trnslen; 2677 u_int8_t *np_t; /* pointer next trns type in previous header */ 2678 int trns_num; 2679 caddr_t p = buf; 2680 2681 proplen = sizeof(*prop); 2682 if (buf) { 2683 /* create proposal */ 2684 prop = (struct isakmp_pl_p *)p; 2685 prop->h.np = ISAKMP_NPTYPE_NONE; 2686 prop->p_no = props->prop_no; 2687 prop->proto_id = IPSECDOI_PROTO_ISAKMP; 2688 prop->spi_size = 0; 2689 p += sizeof(*prop); 2690 } 2691 2692 np_t = NULL; 2693 trns_num = 0; 2694 2695 for (s = props; s != NULL; s = s->next) { 2696 if (np_t) 2697 *np_t = ISAKMP_NPTYPE_T; 2698 2699 trnslen = setph1trns(s, p); 2700 proplen += trnslen; 2701 if (buf) { 2702 /* save buffer to pre-next payload */ 2703 np_t = &((struct isakmp_pl_t *)p)->h.np; 2704 p += trnslen; 2705 2706 /* count up transform length */ 2707 trns_num++; 2708 } 2709 } 2710 2711 /* update proposal length */ 2712 if (buf) { 2713 prop->h.len = htons(proplen); 2714 prop->num_t = trns_num; 2715 } 2716 2717 return proplen; 2718 } 2719 2720 static int 2721 setph1trns(sa, buf) 2722 struct isakmpsa *sa; 2723 caddr_t buf; 2724 { 2725 struct isakmp_pl_t *trns = NULL; 2726 int trnslen, attrlen; 2727 caddr_t p = buf; 2728 2729 trnslen = sizeof(*trns); 2730 if (buf) { 2731 /* create transform */ 2732 trns = (struct isakmp_pl_t *)p; 2733 trns->h.np = ISAKMP_NPTYPE_NONE; 2734 trns->t_no = sa->trns_no; 2735 trns->t_id = IPSECDOI_KEY_IKE; 2736 p += sizeof(*trns); 2737 } 2738 2739 attrlen = setph1attr(sa, p); 2740 trnslen += attrlen; 2741 if (buf) 2742 p += attrlen; 2743 2744 if (buf) 2745 trns->h.len = htons(trnslen); 2746 2747 return trnslen; 2748 } 2749 2750 static int 2751 setph1attr(sa, buf) 2752 struct isakmpsa *sa; 2753 caddr_t buf; 2754 { 2755 caddr_t p = buf; 2756 int attrlen = 0; 2757 2758 if (sa->lifetime) { 2759 u_int32_t lifetime = htonl((u_int32_t)sa->lifetime); 2760 2761 attrlen += sizeof(struct isakmp_data) 2762 + sizeof(struct isakmp_data); 2763 if (sa->lifetime > 0xffff) 2764 attrlen += sizeof(lifetime); 2765 if (buf) { 2766 p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE, 2767 OAKLEY_ATTR_SA_LD_TYPE_SEC); 2768 if (sa->lifetime > 0xffff) { 2769 p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD, 2770 (caddr_t)&lifetime, 2771 sizeof(lifetime)); 2772 } else { 2773 p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD, 2774 sa->lifetime); 2775 } 2776 } 2777 } 2778 2779 if (sa->lifebyte) { 2780 u_int32_t lifebyte = htonl((u_int32_t)sa->lifebyte); 2781 2782 attrlen += sizeof(struct isakmp_data) 2783 + sizeof(struct isakmp_data); 2784 if (sa->lifebyte > 0xffff) 2785 attrlen += sizeof(lifebyte); 2786 if (buf) { 2787 p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE, 2788 OAKLEY_ATTR_SA_LD_TYPE_KB); 2789 if (sa->lifebyte > 0xffff) { 2790 p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD, 2791 (caddr_t)&lifebyte, 2792 sizeof(lifebyte)); 2793 } else { 2794 p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD, 2795 sa->lifebyte); 2796 } 2797 } 2798 } 2799 2800 if (sa->enctype) { 2801 attrlen += sizeof(struct isakmp_data); 2802 if (buf) 2803 p = isakmp_set_attr_l(p, OAKLEY_ATTR_ENC_ALG, sa->enctype); 2804 } 2805 if (sa->encklen) { 2806 attrlen += sizeof(struct isakmp_data); 2807 if (buf) 2808 p = isakmp_set_attr_l(p, OAKLEY_ATTR_KEY_LEN, sa->encklen); 2809 } 2810 if (sa->authmethod) { 2811 int authmethod; 2812 2813 #ifdef ENABLE_HYBRID 2814 authmethod = switch_authmethod(sa->authmethod); 2815 #else 2816 authmethod = sa->authmethod; 2817 #endif 2818 attrlen += sizeof(struct isakmp_data); 2819 if (buf) 2820 p = isakmp_set_attr_l(p, OAKLEY_ATTR_AUTH_METHOD, authmethod); 2821 } 2822 if (sa->hashtype) { 2823 attrlen += sizeof(struct isakmp_data); 2824 if (buf) 2825 p = isakmp_set_attr_l(p, OAKLEY_ATTR_HASH_ALG, sa->hashtype); 2826 } 2827 switch (sa->dh_group) { 2828 case OAKLEY_ATTR_GRP_DESC_MODP768: 2829 case OAKLEY_ATTR_GRP_DESC_MODP1024: 2830 case OAKLEY_ATTR_GRP_DESC_MODP1536: 2831 case OAKLEY_ATTR_GRP_DESC_MODP2048: 2832 case OAKLEY_ATTR_GRP_DESC_MODP3072: 2833 case OAKLEY_ATTR_GRP_DESC_MODP4096: 2834 case OAKLEY_ATTR_GRP_DESC_MODP6144: 2835 case OAKLEY_ATTR_GRP_DESC_MODP8192: 2836 /* don't attach group type for known groups */ 2837 attrlen += sizeof(struct isakmp_data); 2838 if (buf) { 2839 p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_DESC, 2840 sa->dh_group); 2841 } 2842 break; 2843 case OAKLEY_ATTR_GRP_DESC_EC2N155: 2844 case OAKLEY_ATTR_GRP_DESC_EC2N185: 2845 /* don't attach group type for known groups */ 2846 attrlen += sizeof(struct isakmp_data); 2847 if (buf) { 2848 p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_TYPE, 2849 OAKLEY_ATTR_GRP_TYPE_EC2N); 2850 } 2851 break; 2852 case 0: 2853 default: 2854 break; 2855 } 2856 2857 #ifdef HAVE_GSSAPI 2858 if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && 2859 sa->gssid != NULL) { 2860 attrlen += sizeof(struct isakmp_data); 2861 /* 2862 * Older versions of racoon just placed the ISO-Latin-1 2863 * string on the wire directly. Check to see if we are 2864 * configured to be compatible with this behavior. Otherwise, 2865 * we encode the GSS ID as UTF-16LE for Windows 2000 2866 * compatibility, which requires twice the number of octets. 2867 */ 2868 if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) 2869 attrlen += sa->gssid->l; 2870 else 2871 attrlen += sa->gssid->l * 2; 2872 if (buf) { 2873 plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %zu, " 2874 "val '%.*s'\n", sa->gssid->l, (int)sa->gssid->l, 2875 sa->gssid->v); 2876 if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) { 2877 p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID, 2878 (caddr_t)sa->gssid->v, 2879 sa->gssid->l); 2880 } else { 2881 size_t dstleft = sa->gssid->l * 2; 2882 size_t srcleft = sa->gssid->l; 2883 const char *src = (const char *)sa->gssid->v; 2884 char *odst, *dst = racoon_malloc(dstleft); 2885 iconv_t cd; 2886 size_t rv; 2887 2888 cd = iconv_open("utf-16le", "latin1"); 2889 if (cd == (iconv_t) -1) { 2890 plog(LLV_ERROR, LOCATION, NULL, 2891 "unable to initialize " 2892 "latin1 -> utf-16le " 2893 "converstion descriptor: %s\n", 2894 strerror(errno)); 2895 attrlen -= sa->gssid->l * 2; 2896 goto gssid_done; 2897 } 2898 odst = dst; 2899 rv = iconv(cd, (__iconv_const char **)&src, 2900 &srcleft, &dst, &dstleft); 2901 if (rv != 0) { 2902 if (rv == -1) { 2903 plog(LLV_ERROR, LOCATION, NULL, 2904 "unable to convert GSS ID " 2905 "from latin1 -> utf-16le: " 2906 "%s\n", strerror(errno)); 2907 } else { 2908 /* should never happen */ 2909 plog(LLV_ERROR, LOCATION, NULL, 2910 "%zd character%s in GSS ID " 2911 "cannot be represented " 2912 "in utf-16le\n", 2913 rv, rv == 1 ? "" : "s"); 2914 } 2915 (void) iconv_close(cd); 2916 attrlen -= sa->gssid->l * 2; 2917 goto gssid_done; 2918 } 2919 (void) iconv_close(cd); 2920 2921 /* XXX Check srcleft and dstleft? */ 2922 2923 p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID, 2924 odst, sa->gssid->l * 2); 2925 2926 racoon_free(odst); 2927 } 2928 } 2929 } 2930 gssid_done: 2931 #endif /* HAVE_GSSAPI */ 2932 2933 return attrlen; 2934 } 2935 2936 static vchar_t * 2937 setph2proposal0(iph2, pp, pr) 2938 const struct ph2handle *iph2; 2939 const struct saprop *pp; 2940 const struct saproto *pr; 2941 { 2942 vchar_t *p; 2943 struct isakmp_pl_p *prop; 2944 struct isakmp_pl_t *trns; 2945 struct satrns *tr; 2946 int attrlen; 2947 size_t trnsoff; 2948 caddr_t x0, x; 2949 u_int8_t *np_t; /* pointer next trns type in previous header */ 2950 const u_int8_t *spi; 2951 #ifdef HAVE_SECCTX 2952 int truectxlen = 0; 2953 #endif 2954 2955 p = vmalloc(sizeof(*prop) + sizeof(pr->spi)); 2956 if (p == NULL) 2957 return NULL; 2958 2959 /* create proposal */ 2960 prop = (struct isakmp_pl_p *)p->v; 2961 prop->h.np = ISAKMP_NPTYPE_NONE; 2962 prop->p_no = pp->prop_no; 2963 prop->proto_id = pr->proto_id; 2964 prop->num_t = 1; 2965 2966 spi = (const u_int8_t *)&pr->spi; 2967 switch (pr->proto_id) { 2968 case IPSECDOI_PROTO_IPCOMP: 2969 /* 2970 * draft-shacham-ippcp-rfc2393bis-05.txt: 2971 * construct 16bit SPI (CPI). 2972 * XXX we may need to provide a configuration option to 2973 * generate 32bit SPI. otherwise we cannot interoeprate 2974 * with nodes that uses 32bit SPI, in case we are initiator. 2975 */ 2976 prop->spi_size = sizeof(u_int16_t); 2977 spi += sizeof(pr->spi) - sizeof(u_int16_t); 2978 p->l -= sizeof(pr->spi); 2979 p->l += sizeof(u_int16_t); 2980 break; 2981 default: 2982 prop->spi_size = sizeof(pr->spi); 2983 break; 2984 } 2985 memcpy(prop + 1, spi, prop->spi_size); 2986 2987 /* create transform */ 2988 trnsoff = sizeof(*prop) + prop->spi_size; 2989 np_t = NULL; 2990 2991 for (tr = pr->head; tr; tr = tr->next) { 2992 2993 switch (pr->proto_id) { 2994 case IPSECDOI_PROTO_IPSEC_ESP: 2995 /* 2996 * don't build a null encryption 2997 * with no authentication transform. 2998 */ 2999 if (tr->trns_id == IPSECDOI_ESP_NULL && 3000 tr->authtype == IPSECDOI_ATTR_AUTH_NONE) 3001 continue; 3002 break; 3003 } 3004 3005 if (np_t) { 3006 *np_t = ISAKMP_NPTYPE_T; 3007 prop->num_t++; 3008 } 3009 3010 /* get attribute length */ 3011 attrlen = 0; 3012 if (pp->lifetime) { 3013 attrlen += sizeof(struct isakmp_data) 3014 + sizeof(struct isakmp_data); 3015 if (pp->lifetime > 0xffff) 3016 attrlen += sizeof(u_int32_t); 3017 } 3018 if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) { 3019 attrlen += sizeof(struct isakmp_data) 3020 + sizeof(struct isakmp_data); 3021 if (pp->lifebyte > 0xffff) 3022 attrlen += sizeof(u_int32_t); 3023 } 3024 attrlen += sizeof(struct isakmp_data); /* enc mode */ 3025 if (tr->encklen) 3026 attrlen += sizeof(struct isakmp_data); 3027 3028 switch (pr->proto_id) { 3029 case IPSECDOI_PROTO_IPSEC_ESP: 3030 /* non authentication mode ? */ 3031 if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE) 3032 attrlen += sizeof(struct isakmp_data); 3033 break; 3034 case IPSECDOI_PROTO_IPSEC_AH: 3035 if (tr->authtype == IPSECDOI_ATTR_AUTH_NONE) { 3036 plog(LLV_ERROR, LOCATION, NULL, 3037 "no authentication algorithm found " 3038 "but protocol is AH.\n"); 3039 vfree(p); 3040 return NULL; 3041 } 3042 attrlen += sizeof(struct isakmp_data); 3043 break; 3044 case IPSECDOI_PROTO_IPCOMP: 3045 break; 3046 default: 3047 plog(LLV_ERROR, LOCATION, NULL, 3048 "invalid protocol: %d\n", pr->proto_id); 3049 vfree(p); 3050 return NULL; 3051 } 3052 3053 if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group)) 3054 attrlen += sizeof(struct isakmp_data); 3055 3056 #ifdef HAVE_SECCTX 3057 /* ctx_str is defined as char ctx_str[MAX_CTXSTR_SIZ]. 3058 * The string may be smaller than MAX_CTXSTR_SIZ. 3059 */ 3060 if (*pp->sctx.ctx_str) { 3061 truectxlen = sizeof(struct security_ctx) - 3062 (MAX_CTXSTR_SIZE - pp->sctx.ctx_strlen); 3063 attrlen += sizeof(struct isakmp_data) + truectxlen; 3064 } 3065 #endif /* HAVE_SECCTX */ 3066 3067 p = vrealloc(p, p->l + sizeof(*trns) + attrlen); 3068 if (p == NULL) 3069 return NULL; 3070 prop = (struct isakmp_pl_p *)p->v; 3071 3072 /* set transform's values */ 3073 trns = (struct isakmp_pl_t *)(p->v + trnsoff); 3074 trns->h.np = ISAKMP_NPTYPE_NONE; 3075 trns->t_no = tr->trns_no; 3076 trns->t_id = tr->trns_id; 3077 3078 /* set attributes */ 3079 x = x0 = p->v + trnsoff + sizeof(*trns); 3080 3081 if (pp->lifetime) { 3082 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE, 3083 IPSECDOI_ATTR_SA_LD_TYPE_SEC); 3084 if (pp->lifetime > 0xffff) { 3085 u_int32_t v = htonl((u_int32_t)pp->lifetime); 3086 x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD, 3087 (caddr_t)&v, sizeof(v)); 3088 } else { 3089 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD, 3090 pp->lifetime); 3091 } 3092 } 3093 3094 if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) { 3095 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE, 3096 IPSECDOI_ATTR_SA_LD_TYPE_KB); 3097 if (pp->lifebyte > 0xffff) { 3098 u_int32_t v = htonl((u_int32_t)pp->lifebyte); 3099 x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD, 3100 (caddr_t)&v, sizeof(v)); 3101 } else { 3102 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD, 3103 pp->lifebyte); 3104 } 3105 } 3106 3107 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_ENC_MODE, pr->encmode); 3108 3109 if (tr->encklen) 3110 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_KEY_LENGTH, tr->encklen); 3111 3112 /* mandatory check has done above. */ 3113 if ((pr->proto_id == IPSECDOI_PROTO_IPSEC_ESP && tr->authtype != IPSECDOI_ATTR_AUTH_NONE) 3114 || pr->proto_id == IPSECDOI_PROTO_IPSEC_AH) 3115 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_AUTH, tr->authtype); 3116 3117 if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group)) 3118 x = isakmp_set_attr_l(x, IPSECDOI_ATTR_GRP_DESC, 3119 iph2->sainfo->pfs_group); 3120 3121 #ifdef HAVE_SECCTX 3122 if (*pp->sctx.ctx_str) { 3123 struct security_ctx secctx; 3124 secctx = pp->sctx; 3125 secctx.ctx_strlen = htons(pp->sctx.ctx_strlen); 3126 x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SECCTX, 3127 (caddr_t)&secctx, truectxlen); 3128 } 3129 #endif 3130 /* update length of this transform. */ 3131 trns = (struct isakmp_pl_t *)(p->v + trnsoff); 3132 trns->h.len = htons(sizeof(*trns) + attrlen); 3133 3134 /* save buffer to pre-next payload */ 3135 np_t = &trns->h.np; 3136 3137 trnsoff += (sizeof(*trns) + attrlen); 3138 } 3139 3140 if (np_t == NULL) { 3141 plog(LLV_ERROR, LOCATION, NULL, 3142 "no suitable proposal was created.\n"); 3143 return NULL; 3144 } 3145 3146 /* update length of this protocol. */ 3147 prop->h.len = htons(p->l); 3148 3149 return p; 3150 } 3151 3152 /* 3153 * create phase2 proposal from policy configuration. 3154 * NOT INCLUDING isakmp general header of SA payload. 3155 * This function is called by initiator only. 3156 */ 3157 int 3158 ipsecdoi_setph2proposal(iph2) 3159 struct ph2handle *iph2; 3160 { 3161 struct saprop *proposal, *a; 3162 struct saproto *b = NULL; 3163 vchar_t *q; 3164 struct ipsecdoi_sa_b *sab; 3165 struct isakmp_pl_p *prop; 3166 size_t propoff; /* for previous field of type of next payload. */ 3167 3168 proposal = iph2->proposal; 3169 3170 iph2->sa = vmalloc(sizeof(*sab)); 3171 if (iph2->sa == NULL) { 3172 plog(LLV_ERROR, LOCATION, NULL, 3173 "failed to allocate my sa buffer\n"); 3174 return -1; 3175 } 3176 3177 /* create SA payload */ 3178 sab = (struct ipsecdoi_sa_b *)iph2->sa->v; 3179 sab->doi = htonl(IPSEC_DOI); 3180 sab->sit = htonl(IPSECDOI_SIT_IDENTITY_ONLY); /* XXX configurable ? */ 3181 3182 prop = NULL; 3183 propoff = 0; 3184 for (a = proposal; a; a = a->next) { 3185 for (b = a->head; b; b = b->next) { 3186 #ifdef ENABLE_NATT 3187 if (iph2->ph1->natt_flags & NAT_DETECTED) { 3188 int udp_diff = iph2->ph1->natt_options->mode_udp_diff; 3189 plog (LLV_INFO, LOCATION, NULL, 3190 "NAT detected -> UDP encapsulation " 3191 "(ENC_MODE %d->%d).\n", 3192 b->encmode, 3193 b->encmode+udp_diff); 3194 /* Tunnel -> UDP-Tunnel, Transport -> UDP_Transport */ 3195 b->encmode += udp_diff; 3196 b->udp_encap = 1; 3197 } 3198 #endif 3199 3200 q = setph2proposal0(iph2, a, b); 3201 if (q == NULL) { 3202 VPTRINIT(iph2->sa); 3203 return -1; 3204 } 3205 3206 iph2->sa = vrealloc(iph2->sa, iph2->sa->l + q->l); 3207 if (iph2->sa == NULL) { 3208 plog(LLV_ERROR, LOCATION, NULL, 3209 "failed to allocate my sa buffer\n"); 3210 if (q) 3211 vfree(q); 3212 return -1; 3213 } 3214 memcpy(iph2->sa->v + iph2->sa->l - q->l, q->v, q->l); 3215 if (propoff != 0) { 3216 prop = (struct isakmp_pl_p *)(iph2->sa->v + 3217 propoff); 3218 prop->h.np = ISAKMP_NPTYPE_P; 3219 } 3220 propoff = iph2->sa->l - q->l; 3221 3222 vfree(q); 3223 } 3224 } 3225 3226 return 0; 3227 } 3228 3229 /* 3230 * return 1 if all of the given protocols are transport mode. 3231 */ 3232 int 3233 ipsecdoi_transportmode(pp) 3234 struct saprop *pp; 3235 { 3236 struct saproto *pr = NULL; 3237 3238 for (; pp; pp = pp->next) { 3239 for (pr = pp->head; pr; pr = pr->next) { 3240 if (pr->encmode != IPSECDOI_ATTR_ENC_MODE_TRNS) 3241 return 0; 3242 } 3243 } 3244 3245 return 1; 3246 } 3247 3248 int 3249 ipsecdoi_get_defaultlifetime() 3250 { 3251 return IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; 3252 } 3253 3254 int 3255 ipsecdoi_checkalgtypes(proto_id, enc, auth, comp) 3256 int proto_id, enc, auth, comp; 3257 { 3258 #define TMPALGTYPE2STR(n) s_algtype(algclass_ipsec_##n, n) 3259 switch (proto_id) { 3260 case IPSECDOI_PROTO_IPSEC_ESP: 3261 if (enc == 0 || comp != 0) { 3262 plog(LLV_ERROR, LOCATION, NULL, 3263 "illegal algorithm defined " 3264 "ESP enc=%s auth=%s comp=%s.\n", 3265 TMPALGTYPE2STR(enc), 3266 TMPALGTYPE2STR(auth), 3267 TMPALGTYPE2STR(comp)); 3268 return -1; 3269 } 3270 break; 3271 case IPSECDOI_PROTO_IPSEC_AH: 3272 if (enc != 0 || auth == 0 || comp != 0) { 3273 plog(LLV_ERROR, LOCATION, NULL, 3274 "illegal algorithm defined " 3275 "AH enc=%s auth=%s comp=%s.\n", 3276 TMPALGTYPE2STR(enc), 3277 TMPALGTYPE2STR(auth), 3278 TMPALGTYPE2STR(comp)); 3279 return -1; 3280 } 3281 break; 3282 case IPSECDOI_PROTO_IPCOMP: 3283 if (enc != 0 || auth != 0 || comp == 0) { 3284 plog(LLV_ERROR, LOCATION, NULL, 3285 "illegal algorithm defined " 3286 "IPcomp enc=%s auth=%s comp=%s.\n", 3287 TMPALGTYPE2STR(enc), 3288 TMPALGTYPE2STR(auth), 3289 TMPALGTYPE2STR(comp)); 3290 return -1; 3291 } 3292 break; 3293 default: 3294 plog(LLV_ERROR, LOCATION, NULL, 3295 "invalid ipsec protocol %d\n", proto_id); 3296 return -1; 3297 } 3298 #undef TMPALGTYPE2STR 3299 return 0; 3300 } 3301 3302 int 3303 ipproto2doi(proto) 3304 int proto; 3305 { 3306 switch (proto) { 3307 case IPPROTO_AH: 3308 return IPSECDOI_PROTO_IPSEC_AH; 3309 case IPPROTO_ESP: 3310 return IPSECDOI_PROTO_IPSEC_ESP; 3311 case IPPROTO_IPCOMP: 3312 return IPSECDOI_PROTO_IPCOMP; 3313 } 3314 return -1; /* XXX */ 3315 } 3316 3317 int 3318 doi2ipproto(proto) 3319 int proto; 3320 { 3321 switch (proto) { 3322 case IPSECDOI_PROTO_IPSEC_AH: 3323 return IPPROTO_AH; 3324 case IPSECDOI_PROTO_IPSEC_ESP: 3325 return IPPROTO_ESP; 3326 case IPSECDOI_PROTO_IPCOMP: 3327 return IPPROTO_IPCOMP; 3328 } 3329 return -1; /* XXX */ 3330 } 3331 3332 /* 3333 * Check if a subnet id is valid for comparison 3334 * with an address id ( address length mask ) 3335 * and compare them 3336 * Return value 3337 * = 0 for match 3338 * = 1 for mismatch 3339 */ 3340 3341 int 3342 ipsecdoi_subnetisaddr_v4( subnet, address ) 3343 const vchar_t *subnet; 3344 const vchar_t *address; 3345 { 3346 struct in_addr *mask; 3347 3348 if (address->l != sizeof(struct in_addr)) 3349 return 1; 3350 3351 if (subnet->l != (sizeof(struct in_addr)*2)) 3352 return 1; 3353 3354 mask = (struct in_addr*)(subnet->v + sizeof(struct in_addr)); 3355 3356 if (mask->s_addr!=0xffffffff) 3357 return 1; 3358 3359 return memcmp(subnet->v,address->v,address->l); 3360 } 3361 3362 #ifdef INET6 3363 3364 int 3365 ipsecdoi_subnetisaddr_v6( subnet, address ) 3366 const vchar_t *subnet; 3367 const vchar_t *address; 3368 { 3369 struct in6_addr *mask; 3370 int i; 3371 3372 if (address->l != sizeof(struct in6_addr)) 3373 return 1; 3374 3375 if (subnet->l != (sizeof(struct in6_addr)*2)) 3376 return 1; 3377 3378 mask = (struct in6_addr*)(subnet->v + sizeof(struct in6_addr)); 3379 3380 for (i=0; i<16; i++) 3381 if(mask->s6_addr[i]!=0xff) 3382 return 1; 3383 3384 return memcmp(subnet->v,address->v,address->l); 3385 } 3386 3387 #endif 3388 3389 /* 3390 * Check and Compare two IDs 3391 * - specify 0 for exact if wildcards are allowed 3392 * Return value 3393 * = 0 for match 3394 * = 1 for misatch 3395 * = -1 for integrity error 3396 */ 3397 3398 int 3399 ipsecdoi_chkcmpids( idt, ids, exact ) 3400 const vchar_t *idt; /* id cmp target */ 3401 const vchar_t *ids; /* id cmp source */ 3402 int exact; 3403 { 3404 struct ipsecdoi_id_b *id_bt; 3405 struct ipsecdoi_id_b *id_bs; 3406 vchar_t ident_t; 3407 vchar_t ident_s; 3408 int result; 3409 3410 /* handle wildcard IDs */ 3411 3412 if (idt == NULL || ids == NULL) 3413 { 3414 if( !exact ) 3415 { 3416 plog(LLV_DEBUG, LOCATION, NULL, 3417 "check and compare ids : values matched (ANONYMOUS)\n" ); 3418 return 0; 3419 } 3420 else 3421 { 3422 plog(LLV_DEBUG, LOCATION, NULL, 3423 "check and compare ids : value mismatch (ANONYMOUS)\n" ); 3424 return -1; 3425 } 3426 } 3427 3428 /* make sure the ids are of the same type */ 3429 3430 id_bt = (struct ipsecdoi_id_b *) idt->v; 3431 id_bs = (struct ipsecdoi_id_b *) ids->v; 3432 3433 ident_t.v = idt->v + sizeof(*id_bt); 3434 ident_t.l = idt->l - sizeof(*id_bt); 3435 ident_s.v = ids->v + sizeof(*id_bs); 3436 ident_s.l = ids->l - sizeof(*id_bs); 3437 3438 if (id_bs->type != id_bt->type) 3439 { 3440 /* 3441 * special exception for comparing 3442 * address to subnet id types when 3443 * the netmask is address length 3444 */ 3445 3446 if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&& 3447 (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) { 3448 result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s); 3449 goto cmpid_result; 3450 } 3451 3452 if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&& 3453 (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) { 3454 result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t); 3455 goto cmpid_result; 3456 } 3457 3458 #ifdef INET6 3459 if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&& 3460 (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { 3461 result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s); 3462 goto cmpid_result; 3463 } 3464 3465 if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&& 3466 (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) { 3467 result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t); 3468 goto cmpid_result; 3469 } 3470 #endif 3471 plog(LLV_DEBUG, LOCATION, NULL, 3472 "check and compare ids : id type mismatch %s != %s\n", 3473 s_ipsecdoi_ident(id_bs->type), 3474 s_ipsecdoi_ident(id_bt->type)); 3475 3476 return 1; 3477 } 3478 3479 if(id_bs->proto_id != id_bt->proto_id){ 3480 plog(LLV_DEBUG, LOCATION, NULL, 3481 "check and compare ids : proto_id mismatch %d != %d\n", 3482 id_bs->proto_id, id_bt->proto_id); 3483 3484 return 1; 3485 } 3486 3487 /* compare the ID data. */ 3488 3489 switch (id_bt->type) { 3490 case IPSECDOI_ID_DER_ASN1_DN: 3491 case IPSECDOI_ID_DER_ASN1_GN: 3492 /* compare asn1 ids */ 3493 result = eay_cmp_asn1dn(&ident_t, &ident_s); 3494 goto cmpid_result; 3495 3496 case IPSECDOI_ID_IPV4_ADDR: 3497 /* validate lengths */ 3498 if ((ident_t.l != sizeof(struct in_addr))|| 3499 (ident_s.l != sizeof(struct in_addr))) 3500 goto cmpid_invalid; 3501 break; 3502 3503 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 3504 case IPSECDOI_ID_IPV4_ADDR_RANGE: 3505 /* validate lengths */ 3506 if ((ident_t.l != (sizeof(struct in_addr)*2))|| 3507 (ident_s.l != (sizeof(struct in_addr)*2))) 3508 goto cmpid_invalid; 3509 break; 3510 3511 #ifdef INET6 3512 case IPSECDOI_ID_IPV6_ADDR: 3513 /* validate lengths */ 3514 if ((ident_t.l != sizeof(struct in6_addr))|| 3515 (ident_s.l != sizeof(struct in6_addr))) 3516 goto cmpid_invalid; 3517 break; 3518 3519 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 3520 case IPSECDOI_ID_IPV6_ADDR_RANGE: 3521 /* validate lengths */ 3522 if ((ident_t.l != (sizeof(struct in6_addr)*2))|| 3523 (ident_s.l != (sizeof(struct in6_addr)*2))) 3524 goto cmpid_invalid; 3525 break; 3526 #endif 3527 case IPSECDOI_ID_FQDN: 3528 case IPSECDOI_ID_USER_FQDN: 3529 case IPSECDOI_ID_KEY_ID: 3530 break; 3531 3532 default: 3533 plog(LLV_ERROR, LOCATION, NULL, 3534 "Unhandled id type %i specified for comparison\n", 3535 id_bt->type); 3536 return -1; 3537 } 3538 3539 /* validate matching data and length */ 3540 if (ident_t.l == ident_s.l) 3541 result = memcmp(ident_t.v,ident_s.v,ident_t.l); 3542 else 3543 result = 1; 3544 3545 cmpid_result: 3546 3547 /* debug level output */ 3548 if(loglevel >= LLV_DEBUG) { 3549 char *idstrt = ipsecdoi_id2str(idt); 3550 char *idstrs = ipsecdoi_id2str(ids); 3551 3552 if (!result) 3553 plog(LLV_DEBUG, LOCATION, NULL, 3554 "check and compare ids : values matched (%s)\n", 3555 s_ipsecdoi_ident(id_bs->type) ); 3556 else 3557 plog(LLV_DEBUG, LOCATION, NULL, 3558 "check and compare ids : value mismatch (%s)\n", 3559 s_ipsecdoi_ident(id_bs->type)); 3560 3561 plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: \'%s\'\n", idstrt ); 3562 plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: \'%s\'\n", idstrs ); 3563 3564 racoon_free(idstrs); 3565 racoon_free(idstrt); 3566 } 3567 3568 /* return result */ 3569 if( !result ) 3570 return 0; 3571 else 3572 return 1; 3573 3574 cmpid_invalid: 3575 3576 /* id integrity error */ 3577 plog(LLV_DEBUG, LOCATION, NULL, "check and compare ids : %s integrity error\n", 3578 s_ipsecdoi_ident(id_bs->type)); 3579 plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: length = \'%zu\'\n", ident_t.l ); 3580 plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: length = \'%zu\'\n", ident_s.l ); 3581 3582 return -1; 3583 } 3584 3585 /* 3586 * check the following: 3587 * - In main mode with pre-shared key, only address type can be used. 3588 * - if proper type for phase 1 ? 3589 * - if phase 1 ID payload conformed RFC2407 4.6.2. 3590 * (proto, port) must be (0, 0), (udp, 500) or (udp, [specified]). 3591 * - if ID payload sent from peer is equal to the ID expected by me. 3592 * 3593 * both of "id" and "id_p" should be ID payload without general header, 3594 */ 3595 int 3596 ipsecdoi_checkid1(iph1) 3597 struct ph1handle *iph1; 3598 { 3599 struct ipsecdoi_id_b *id_b; 3600 struct sockaddr *sa; 3601 caddr_t sa1, sa2; 3602 3603 if (iph1->id_p == NULL) { 3604 plog(LLV_ERROR, LOCATION, NULL, 3605 "invalid iph1 passed id_p == NULL\n"); 3606 return ISAKMP_INTERNAL_ERROR; 3607 } 3608 if (iph1->id_p->l < sizeof(*id_b)) { 3609 plog(LLV_ERROR, LOCATION, NULL, 3610 "invalid value passed as \"ident\" (len=%lu)\n", 3611 (u_long)iph1->id_p->l); 3612 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 3613 } 3614 3615 id_b = (struct ipsecdoi_id_b *)iph1->id_p->v; 3616 3617 #ifndef ANDROID_PATCHED 3618 /* In main mode with pre-shared key, only address type can be used. */ 3619 if (iph1->etype == ISAKMP_ETYPE_IDENT && 3620 iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_PSKEY) { 3621 if (id_b->type != IPSECDOI_ID_IPV4_ADDR 3622 && id_b->type != IPSECDOI_ID_IPV6_ADDR) { 3623 plog(LLV_ERROR, LOCATION, NULL, 3624 "Expecting IP address type in main mode, " 3625 "but %s.\n", s_ipsecdoi_ident(id_b->type)); 3626 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 3627 } 3628 } 3629 #endif 3630 3631 /* if proper type for phase 1 ? */ 3632 switch (id_b->type) { 3633 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 3634 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 3635 case IPSECDOI_ID_IPV4_ADDR_RANGE: 3636 case IPSECDOI_ID_IPV6_ADDR_RANGE: 3637 plog(LLV_WARNING, LOCATION, NULL, 3638 "such ID type %s is not proper.\n", 3639 s_ipsecdoi_ident(id_b->type)); 3640 /*FALLTHROUGH*/ 3641 } 3642 3643 /* if phase 1 ID payload conformed RFC2407 4.6.2. */ 3644 if (id_b->type == IPSECDOI_ID_IPV4_ADDR || 3645 id_b->type == IPSECDOI_ID_IPV6_ADDR) { 3646 3647 if (id_b->proto_id == 0 && ntohs(id_b->port) != 0) { 3648 plog(LLV_WARNING, LOCATION, NULL, 3649 "protocol ID and Port mismatched. " 3650 "proto_id:%d port:%d\n", 3651 id_b->proto_id, ntohs(id_b->port)); 3652 /*FALLTHROUGH*/ 3653 3654 } else if (id_b->proto_id == IPPROTO_UDP) { 3655 /* 3656 * copmaring with expecting port. 3657 * always permit if port is equal to PORT_ISAKMP 3658 */ 3659 if (ntohs(id_b->port) != PORT_ISAKMP) { 3660 u_int16_t port; 3661 3662 port = extract_port(iph1->remote); 3663 if (ntohs(id_b->port) != port) { 3664 plog(LLV_WARNING, LOCATION, NULL, 3665 "port %d expected, but %d\n", 3666 port, ntohs(id_b->port)); 3667 /*FALLTHROUGH*/ 3668 } 3669 } 3670 } 3671 } 3672 3673 /* compare with the ID if specified. */ 3674 if (genlist_next(iph1->rmconf->idvl_p, 0)) { 3675 vchar_t *ident0 = NULL; 3676 vchar_t ident; 3677 struct idspec *id; 3678 struct genlist_entry *gpb; 3679 3680 for (id = genlist_next (iph1->rmconf->idvl_p, &gpb); id; id = genlist_next (0, &gpb)) { 3681 /* check the type of both IDs */ 3682 if (id->idtype != doi2idtype(id_b->type)) 3683 continue; /* ID type mismatch */ 3684 if (id->id == 0) 3685 goto matched; 3686 3687 /* compare defined ID with the ID sent by peer. */ 3688 if (ident0 != NULL) 3689 vfree(ident0); 3690 ident0 = getidval(id->idtype, id->id); 3691 3692 switch (id->idtype) { 3693 case IDTYPE_ASN1DN: 3694 ident.v = iph1->id_p->v + sizeof(*id_b); 3695 ident.l = iph1->id_p->l - sizeof(*id_b); 3696 if (eay_cmp_asn1dn(ident0, &ident) == 0) 3697 goto matched; 3698 break; 3699 case IDTYPE_ADDRESS: 3700 sa = (struct sockaddr *)ident0->v; 3701 sa2 = (caddr_t)(id_b + 1); 3702 switch (sa->sa_family) { 3703 case AF_INET: 3704 if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in_addr)) 3705 continue; /* ID value mismatch */ 3706 sa1 = (caddr_t)&((struct sockaddr_in *)sa)->sin_addr; 3707 if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0) 3708 goto matched; 3709 break; 3710 #ifdef INET6 3711 case AF_INET6: 3712 if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in6_addr)) 3713 continue; /* ID value mismatch */ 3714 sa1 = (caddr_t)&((struct sockaddr_in6 *)sa)->sin6_addr; 3715 if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0) 3716 goto matched; 3717 break; 3718 #endif 3719 default: 3720 break; 3721 } 3722 break; 3723 default: 3724 if (memcmp(ident0->v, id_b + 1, ident0->l) == 0) 3725 goto matched; 3726 break; 3727 } 3728 } 3729 if (ident0 != NULL) { 3730 vfree(ident0); 3731 ident0 = NULL; 3732 } 3733 plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n"); 3734 if (iph1->rmconf->verify_identifier) 3735 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 3736 matched: /* ID value match */ 3737 if (ident0 != NULL) 3738 vfree(ident0); 3739 } 3740 3741 return 0; 3742 } 3743 3744 /* 3745 * create ID payload for phase 1 and set into iph1->id. 3746 * NOT INCLUDING isakmp general header. 3747 * see, RFC2407 4.6.2.1 3748 */ 3749 int 3750 ipsecdoi_setid1(iph1) 3751 struct ph1handle *iph1; 3752 { 3753 vchar_t *ret = NULL; 3754 struct ipsecdoi_id_b id_b; 3755 vchar_t *ident = NULL; 3756 struct sockaddr *ipid = NULL; 3757 3758 /* init */ 3759 id_b.proto_id = 0; 3760 id_b.port = 0; 3761 ident = NULL; 3762 3763 switch (iph1->rmconf->idvtype) { 3764 case IDTYPE_FQDN: 3765 id_b.type = IPSECDOI_ID_FQDN; 3766 ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv); 3767 break; 3768 case IDTYPE_USERFQDN: 3769 id_b.type = IPSECDOI_ID_USER_FQDN; 3770 ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv); 3771 break; 3772 case IDTYPE_KEYID: 3773 id_b.type = IPSECDOI_ID_KEY_ID; 3774 ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv); 3775 break; 3776 case IDTYPE_ASN1DN: 3777 id_b.type = IPSECDOI_ID_DER_ASN1_DN; 3778 if (iph1->rmconf->idv) { 3779 /* XXX it must be encoded to asn1dn. */ 3780 ident = vdup(iph1->rmconf->idv); 3781 } else { 3782 if (oakley_getmycert(iph1) < 0) { 3783 plog(LLV_ERROR, LOCATION, NULL, 3784 "failed to get own CERT.\n"); 3785 goto err; 3786 } 3787 ident = eay_get_x509asn1subjectname(&iph1->cert->cert); 3788 } 3789 break; 3790 case IDTYPE_ADDRESS: 3791 /* 3792 * if the value of the id type was set by the configuration 3793 * file, then use it. otherwise the value is get from local 3794 * ip address by using ike negotiation. 3795 */ 3796 if (iph1->rmconf->idv) 3797 ipid = (struct sockaddr *)iph1->rmconf->idv->v; 3798 /*FALLTHROUGH*/ 3799 default: 3800 { 3801 int l; 3802 caddr_t p; 3803 3804 if (ipid == NULL) 3805 ipid = iph1->local; 3806 3807 /* use IP address */ 3808 switch (ipid->sa_family) { 3809 case AF_INET: 3810 id_b.type = IPSECDOI_ID_IPV4_ADDR; 3811 l = sizeof(struct in_addr); 3812 p = (caddr_t)&((struct sockaddr_in *)ipid)->sin_addr; 3813 break; 3814 #ifdef INET6 3815 case AF_INET6: 3816 id_b.type = IPSECDOI_ID_IPV6_ADDR; 3817 l = sizeof(struct in6_addr); 3818 p = (caddr_t)&((struct sockaddr_in6 *)ipid)->sin6_addr; 3819 break; 3820 #endif 3821 default: 3822 plog(LLV_ERROR, LOCATION, NULL, 3823 "invalid address family.\n"); 3824 goto err; 3825 } 3826 id_b.proto_id = IPPROTO_UDP; 3827 id_b.port = htons(PORT_ISAKMP); 3828 ident = vmalloc(l); 3829 if (!ident) { 3830 plog(LLV_ERROR, LOCATION, NULL, 3831 "failed to get ID buffer.\n"); 3832 return 0; 3833 } 3834 memcpy(ident->v, p, ident->l); 3835 } 3836 } 3837 if (!ident) { 3838 plog(LLV_ERROR, LOCATION, NULL, 3839 "failed to get ID buffer.\n"); 3840 return 0; 3841 } 3842 3843 ret = vmalloc(sizeof(id_b) + ident->l); 3844 if (ret == NULL) { 3845 plog(LLV_ERROR, LOCATION, NULL, 3846 "failed to get ID buffer.\n"); 3847 goto err; 3848 } 3849 3850 memcpy(ret->v, &id_b, sizeof(id_b)); 3851 memcpy(ret->v + sizeof(id_b), ident->v, ident->l); 3852 3853 iph1->id = ret; 3854 3855 plog(LLV_DEBUG, LOCATION, NULL, 3856 "use ID type of %s\n", s_ipsecdoi_ident(id_b.type)); 3857 if (ident) 3858 vfree(ident); 3859 return 0; 3860 3861 err: 3862 if (ident) 3863 vfree(ident); 3864 plog(LLV_ERROR, LOCATION, NULL, "failed get my ID\n"); 3865 return -1; 3866 } 3867 3868 static vchar_t * 3869 getidval(type, val) 3870 int type; 3871 vchar_t *val; 3872 { 3873 vchar_t *new = NULL; 3874 3875 if (val) 3876 new = vdup(val); 3877 else if (lcconf->ident[type]) 3878 new = vdup(lcconf->ident[type]); 3879 3880 return new; 3881 } 3882 3883 /* it's only called by cfparse.y. */ 3884 int 3885 set_identifier(vpp, type, value) 3886 vchar_t **vpp, *value; 3887 int type; 3888 { 3889 return set_identifier_qual(vpp, type, value, IDQUAL_UNSPEC); 3890 } 3891 3892 int 3893 set_identifier_qual(vpp, type, value, qual) 3894 vchar_t **vpp, *value; 3895 int type; 3896 int qual; 3897 { 3898 vchar_t *new = NULL; 3899 3900 /* simply return if value is null. */ 3901 if (!value){ 3902 if( type == IDTYPE_FQDN || type == IDTYPE_USERFQDN){ 3903 plog(LLV_ERROR, LOCATION, NULL, 3904 "No %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn"); 3905 return -1; 3906 } 3907 return 0; 3908 } 3909 3910 switch (type) { 3911 case IDTYPE_FQDN: 3912 case IDTYPE_USERFQDN: 3913 if(value->l <= 1){ 3914 plog(LLV_ERROR, LOCATION, NULL, 3915 "Empty %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn"); 3916 return -1; 3917 } 3918 /* length is adjusted since QUOTEDSTRING teminates NULL. */ 3919 new = vmalloc(value->l - 1); 3920 if (new == NULL) 3921 return -1; 3922 memcpy(new->v, value->v, new->l); 3923 break; 3924 case IDTYPE_KEYID: 3925 /* 3926 * If no qualifier is specified: IDQUAL_UNSPEC. It means 3927 * to use a file for backward compatibility sake. 3928 */ 3929 switch(qual) { 3930 case IDQUAL_FILE: 3931 case IDQUAL_UNSPEC: { 3932 FILE *fp; 3933 char b[512]; 3934 int tlen, len; 3935 3936 fp = fopen(value->v, "r"); 3937 if (fp == NULL) { 3938 plog(LLV_ERROR, LOCATION, NULL, 3939 "can not open %s\n", value->v); 3940 return -1; 3941 } 3942 tlen = 0; 3943 while ((len = fread(b, 1, sizeof(b), fp)) != 0) { 3944 new = vrealloc(new, tlen + len); 3945 if (!new) { 3946 fclose(fp); 3947 return -1; 3948 } 3949 memcpy(new->v + tlen, b, len); 3950 tlen += len; 3951 } 3952 break; 3953 } 3954 3955 case IDQUAL_TAG: 3956 new = vmalloc(value->l - 1); 3957 if (new == NULL) { 3958 plog(LLV_ERROR, LOCATION, NULL, 3959 "can not allocate memory"); 3960 return -1; 3961 } 3962 memcpy(new->v, value->v, new->l); 3963 break; 3964 3965 default: 3966 plog(LLV_ERROR, LOCATION, NULL, 3967 "unknown qualifier"); 3968 return -1; 3969 } 3970 break; 3971 3972 case IDTYPE_ADDRESS: { 3973 struct sockaddr *sa; 3974 3975 /* length is adjusted since QUOTEDSTRING teminates NULL. */ 3976 if (value->l == 0) 3977 break; 3978 3979 sa = str2saddr(value->v, NULL); 3980 if (sa == NULL) { 3981 plog(LLV_ERROR, LOCATION, NULL, 3982 "invalid ip address %s\n", value->v); 3983 return -1; 3984 } 3985 3986 new = vmalloc(sysdep_sa_len(sa)); 3987 if (new == NULL) { 3988 racoon_free(sa); 3989 return -1; 3990 } 3991 memcpy(new->v, sa, new->l); 3992 racoon_free(sa); 3993 break; 3994 } 3995 case IDTYPE_ASN1DN: 3996 if (value->v[0] == '~') 3997 /* Hex-encoded ASN1 strings */ 3998 new = eay_hex2asn1dn(value->v + 1, - 1); 3999 else 4000 /* DN encoded strings */ 4001 new = eay_str2asn1dn(value->v, value->l - 1); 4002 4003 if (new == NULL) 4004 return -1; 4005 4006 if (loglevel >= LLV_DEBUG) { 4007 X509_NAME *xn; 4008 BIO *bio; 4009 unsigned char *ptr = (unsigned char *) new->v, *buf; 4010 size_t len; 4011 char save; 4012 4013 xn = d2i_X509_NAME(NULL, (void *)&ptr, new->l); 4014 bio = BIO_new(BIO_s_mem()); 4015 4016 X509_NAME_print_ex(bio, xn, 0, 0); 4017 len = BIO_get_mem_data(bio, &ptr); 4018 save = ptr[len]; 4019 ptr[len] = 0; 4020 plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", ptr); 4021 ptr[len] = save; 4022 X509_NAME_free(xn); 4023 BIO_free(bio); 4024 } 4025 4026 break; 4027 } 4028 4029 *vpp = new; 4030 4031 return 0; 4032 } 4033 4034 /* 4035 * create ID payload for phase 2, and set into iph2->id and id_p. There are 4036 * NOT INCLUDING isakmp general header. 4037 * this function is for initiator. responder will get to copy from payload. 4038 * responder ID type is always address type. 4039 * see, RFC2407 4.6.2.1 4040 */ 4041 int 4042 ipsecdoi_setid2(iph2) 4043 struct ph2handle *iph2; 4044 { 4045 struct secpolicy *sp; 4046 4047 /* check there is phase 2 handler ? */ 4048 sp = getspbyspid(iph2->spid); 4049 if (sp == NULL) { 4050 plog(LLV_ERROR, LOCATION, NULL, 4051 "no policy found for spid:%u.\n", iph2->spid); 4052 return -1; 4053 } 4054 4055 iph2->id = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.src, 4056 sp->spidx.prefs, sp->spidx.ul_proto); 4057 if (iph2->id == NULL) { 4058 plog(LLV_ERROR, LOCATION, NULL, 4059 "failed to get ID for %s\n", 4060 spidx2str(&sp->spidx)); 4061 return -1; 4062 } 4063 plog(LLV_DEBUG, LOCATION, NULL, "use local ID type %s\n", 4064 s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id->v)->type)); 4065 4066 /* remote side */ 4067 iph2->id_p = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.dst, 4068 sp->spidx.prefd, sp->spidx.ul_proto); 4069 if (iph2->id_p == NULL) { 4070 plog(LLV_ERROR, LOCATION, NULL, 4071 "failed to get ID for %s\n", 4072 spidx2str(&sp->spidx)); 4073 VPTRINIT(iph2->id); 4074 return -1; 4075 } 4076 plog(LLV_DEBUG, LOCATION, NULL, 4077 "use remote ID type %s\n", 4078 s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id_p->v)->type)); 4079 4080 return 0; 4081 } 4082 4083 /* 4084 * set address type of ID. 4085 * NOT INCLUDING general header. 4086 */ 4087 vchar_t * 4088 ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto) 4089 struct sockaddr *saddr; 4090 u_int prefixlen; 4091 u_int ul_proto; 4092 { 4093 vchar_t *new; 4094 int type, len1, len2; 4095 caddr_t sa; 4096 u_short port; 4097 4098 /* 4099 * Q. When type is SUBNET, is it allowed to be ::1/128. 4100 * A. Yes. (consensus at bake-off) 4101 */ 4102 switch (saddr->sa_family) { 4103 case AF_INET: 4104 len1 = sizeof(struct in_addr); 4105 if (prefixlen == (sizeof(struct in_addr) << 3)) { 4106 type = IPSECDOI_ID_IPV4_ADDR; 4107 len2 = 0; 4108 } else { 4109 type = IPSECDOI_ID_IPV4_ADDR_SUBNET; 4110 len2 = sizeof(struct in_addr); 4111 } 4112 sa = (caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr; 4113 port = ((struct sockaddr_in *)(saddr))->sin_port; 4114 break; 4115 #ifdef INET6 4116 case AF_INET6: 4117 len1 = sizeof(struct in6_addr); 4118 if (prefixlen == (sizeof(struct in6_addr) << 3)) { 4119 type = IPSECDOI_ID_IPV6_ADDR; 4120 len2 = 0; 4121 } else { 4122 type = IPSECDOI_ID_IPV6_ADDR_SUBNET; 4123 len2 = sizeof(struct in6_addr); 4124 } 4125 sa = (caddr_t)&((struct sockaddr_in6 *)(saddr))->sin6_addr; 4126 port = ((struct sockaddr_in6 *)(saddr))->sin6_port; 4127 break; 4128 #endif 4129 default: 4130 plog(LLV_ERROR, LOCATION, NULL, 4131 "invalid family: %d.\n", saddr->sa_family); 4132 return NULL; 4133 } 4134 4135 /* get ID buffer */ 4136 new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2); 4137 if (new == NULL) { 4138 plog(LLV_ERROR, LOCATION, NULL, 4139 "failed to get ID buffer.\n"); 4140 return NULL; 4141 } 4142 4143 memset(new->v, 0, new->l); 4144 4145 /* set the part of header. */ 4146 ((struct ipsecdoi_id_b *)new->v)->type = type; 4147 4148 /* set ul_proto and port */ 4149 /* 4150 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card 4151 * because 0 means port number of 0. Instead of 0, we use IPSEC_*_ANY. 4152 */ 4153 ((struct ipsecdoi_id_b *)new->v)->proto_id = 4154 ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto; 4155 ((struct ipsecdoi_id_b *)new->v)->port = 4156 port == IPSEC_PORT_ANY ? 0 : port; 4157 memcpy(new->v + sizeof(struct ipsecdoi_id_b), sa, len1); 4158 4159 /* set address */ 4160 4161 /* set prefix */ 4162 if (len2) { 4163 u_char *p = (unsigned char *) new->v + 4164 sizeof(struct ipsecdoi_id_b) + len1; 4165 u_int bits = prefixlen; 4166 4167 while (bits >= 8) { 4168 *p++ = 0xff; 4169 bits -= 8; 4170 } 4171 4172 if (bits > 0) 4173 *p = ~((1 << (8 - bits)) - 1); 4174 } 4175 4176 return new; 4177 } 4178 4179 vchar_t * 4180 ipsecdoi_sockrange2id(laddr, haddr, ul_proto) 4181 struct sockaddr *laddr, *haddr; 4182 u_int ul_proto; 4183 { 4184 vchar_t *new; 4185 int type, len1, len2; 4186 u_short port; 4187 4188 if (laddr->sa_family != haddr->sa_family) { 4189 plog(LLV_ERROR, LOCATION, NULL, "Address family mismatch\n"); 4190 return NULL; 4191 } 4192 4193 switch (laddr->sa_family) { 4194 case AF_INET: 4195 type = IPSECDOI_ID_IPV4_ADDR_RANGE; 4196 len1 = sizeof(struct in_addr); 4197 len2 = sizeof(struct in_addr); 4198 break; 4199 #ifdef INET6 4200 case AF_INET6: 4201 type = IPSECDOI_ID_IPV6_ADDR_RANGE; 4202 len1 = sizeof(struct in6_addr); 4203 len2 = sizeof(struct in6_addr); 4204 break; 4205 #endif 4206 default: 4207 plog(LLV_ERROR, LOCATION, NULL, 4208 "invalid family: %d.\n", laddr->sa_family); 4209 return NULL; 4210 } 4211 4212 /* get ID buffer */ 4213 new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2); 4214 if (new == NULL) { 4215 plog(LLV_ERROR, LOCATION, NULL, 4216 "failed to get ID buffer.\n"); 4217 return NULL; 4218 } 4219 4220 memset(new->v, 0, new->l); 4221 /* set the part of header. */ 4222 ((struct ipsecdoi_id_b *)new->v)->type = type; 4223 4224 /* set ul_proto and port */ 4225 /* 4226 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card 4227 * because 0 means port number of 0. Instead of 0, we use IPSEC_*_ANY. 4228 */ 4229 ((struct ipsecdoi_id_b *)new->v)->proto_id = 4230 ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto; 4231 port = ((struct sockaddr_in *)(laddr))->sin_port; 4232 ((struct ipsecdoi_id_b *)new->v)->port = 4233 port == IPSEC_PORT_ANY ? 0 : port; 4234 memcpy(new->v + sizeof(struct ipsecdoi_id_b), 4235 (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr, 4236 len1); 4237 memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1, 4238 (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr, 4239 len2); 4240 return new; 4241 } 4242 4243 4244 /* 4245 * create sockaddr structure from ID payload (buf). 4246 * buffers (saddr, prefixlen, ul_proto) must be allocated. 4247 * see, RFC2407 4.6.2.1 4248 */ 4249 int 4250 ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto) 4251 vchar_t *buf; 4252 struct sockaddr *saddr; 4253 u_int8_t *prefixlen; 4254 u_int16_t *ul_proto; 4255 { 4256 struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)buf->v; 4257 u_int plen = 0; 4258 4259 /* 4260 * When a ID payload of subnet type with a IP address of full bit 4261 * masked, it has to be processed as host address. 4262 * e.g. below 2 type are same. 4263 * type = ipv6 subnet, data = 2001::1/128 4264 * type = ipv6 address, data = 2001::1 4265 */ 4266 switch (id_b->type) { 4267 case IPSECDOI_ID_IPV4_ADDR: 4268 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4269 #ifndef __linux__ 4270 saddr->sa_len = sizeof(struct sockaddr_in); 4271 #endif 4272 saddr->sa_family = AF_INET; 4273 ((struct sockaddr_in *)saddr)->sin_port = 4274 (id_b->port == 0 4275 ? IPSEC_PORT_ANY 4276 : id_b->port); /* see sockaddr2id() */ 4277 memcpy(&((struct sockaddr_in *)saddr)->sin_addr, 4278 buf->v + sizeof(*id_b), sizeof(struct in_addr)); 4279 break; 4280 #ifdef INET6 4281 case IPSECDOI_ID_IPV6_ADDR: 4282 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4283 #ifndef __linux__ 4284 saddr->sa_len = sizeof(struct sockaddr_in6); 4285 #endif 4286 saddr->sa_family = AF_INET6; 4287 ((struct sockaddr_in6 *)saddr)->sin6_port = 4288 (id_b->port == 0 4289 ? IPSEC_PORT_ANY 4290 : id_b->port); /* see sockaddr2id() */ 4291 memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr, 4292 buf->v + sizeof(*id_b), sizeof(struct in6_addr)); 4293 break; 4294 #endif 4295 default: 4296 plog(LLV_ERROR, LOCATION, NULL, 4297 "unsupported ID type %d\n", id_b->type); 4298 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 4299 } 4300 4301 /* get prefix length */ 4302 switch (id_b->type) { 4303 case IPSECDOI_ID_IPV4_ADDR: 4304 plen = sizeof(struct in_addr) << 3; 4305 break; 4306 #ifdef INET6 4307 case IPSECDOI_ID_IPV6_ADDR: 4308 plen = sizeof(struct in6_addr) << 3; 4309 break; 4310 #endif 4311 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4312 #ifdef INET6 4313 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4314 #endif 4315 { 4316 u_char *p; 4317 u_int max; 4318 int alen = sizeof(struct in_addr); 4319 4320 switch (id_b->type) { 4321 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4322 alen = sizeof(struct in_addr); 4323 break; 4324 #ifdef INET6 4325 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4326 alen = sizeof(struct in6_addr); 4327 break; 4328 #endif 4329 } 4330 4331 /* sanity check */ 4332 if (buf->l < alen) 4333 return ISAKMP_INTERNAL_ERROR; 4334 4335 /* get subnet mask length */ 4336 plen = 0; 4337 max = alen <<3; 4338 4339 p = (unsigned char *) buf->v 4340 + sizeof(struct ipsecdoi_id_b) 4341 + alen; 4342 4343 for (; *p == 0xff; p++) { 4344 plen += 8; 4345 if (plen >= max) 4346 break; 4347 } 4348 4349 if (plen < max) { 4350 u_int l = 0; 4351 u_char b = ~(*p); 4352 4353 while (b) { 4354 b >>= 1; 4355 l++; 4356 } 4357 4358 l = 8 - l; 4359 plen += l; 4360 } 4361 } 4362 break; 4363 } 4364 4365 *prefixlen = plen; 4366 *ul_proto = id_b->proto_id == 0 4367 ? IPSEC_ULPROTO_ANY 4368 : id_b->proto_id; /* see sockaddr2id() */ 4369 4370 return 0; 4371 } 4372 4373 /* 4374 * make printable string from ID payload except of general header. 4375 */ 4376 char * 4377 ipsecdoi_id2str(id) 4378 const vchar_t *id; 4379 { 4380 #define BUFLEN 512 4381 char * ret = NULL; 4382 int len = 0; 4383 char *dat; 4384 static char buf[BUFLEN]; 4385 struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v; 4386 struct sockaddr_storage saddr_storage; 4387 struct sockaddr *saddr; 4388 struct sockaddr_in *saddr_in; 4389 struct sockaddr_in6 *saddr_in6; 4390 u_int plen = 0; 4391 4392 saddr = (struct sockaddr *)&saddr_storage; 4393 saddr_in = (struct sockaddr_in *)&saddr_storage; 4394 saddr_in6 = (struct sockaddr_in6 *)&saddr_storage; 4395 4396 4397 switch (id_b->type) { 4398 case IPSECDOI_ID_IPV4_ADDR: 4399 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4400 case IPSECDOI_ID_IPV4_ADDR_RANGE: 4401 4402 #ifndef __linux__ 4403 saddr->sa_len = sizeof(struct sockaddr_in); 4404 #endif 4405 saddr->sa_family = AF_INET; 4406 4407 saddr_in->sin_port = IPSEC_PORT_ANY; 4408 memcpy(&saddr_in->sin_addr, 4409 id->v + sizeof(*id_b), sizeof(struct in_addr)); 4410 break; 4411 #ifdef INET6 4412 case IPSECDOI_ID_IPV6_ADDR: 4413 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4414 case IPSECDOI_ID_IPV6_ADDR_RANGE: 4415 4416 #ifndef __linux__ 4417 saddr->sa_len = sizeof(struct sockaddr_in6); 4418 #endif 4419 saddr->sa_family = AF_INET6; 4420 4421 saddr_in6->sin6_port = IPSEC_PORT_ANY; 4422 memcpy(&saddr_in6->sin6_addr, 4423 id->v + sizeof(*id_b), sizeof(struct in6_addr)); 4424 saddr_in6->sin6_scope_id = 4425 (IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr) 4426 ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id 4427 : 0); 4428 break; 4429 #endif 4430 } 4431 4432 switch (id_b->type) { 4433 case IPSECDOI_ID_IPV4_ADDR: 4434 #ifdef INET6 4435 case IPSECDOI_ID_IPV6_ADDR: 4436 #endif 4437 len = snprintf( buf, BUFLEN, "%s", saddrwop2str(saddr)); 4438 break; 4439 4440 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4441 #ifdef INET6 4442 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4443 #endif 4444 { 4445 u_char *p; 4446 u_int max; 4447 int alen = sizeof(struct in_addr); 4448 4449 switch (id_b->type) { 4450 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4451 alen = sizeof(struct in_addr); 4452 break; 4453 #ifdef INET6 4454 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4455 alen = sizeof(struct in6_addr); 4456 break; 4457 #endif 4458 } 4459 4460 /* sanity check */ 4461 if (id->l < alen) { 4462 len = 0; 4463 break; 4464 } 4465 4466 /* get subnet mask length */ 4467 plen = 0; 4468 max = alen <<3; 4469 4470 p = (unsigned char *) id->v 4471 + sizeof(struct ipsecdoi_id_b) 4472 + alen; 4473 4474 for (; *p == 0xff; p++) { 4475 plen += 8; 4476 if (plen >= max) 4477 break; 4478 } 4479 4480 if (plen < max) { 4481 u_int l = 0; 4482 u_char b = ~(*p); 4483 4484 while (b) { 4485 b >>= 1; 4486 l++; 4487 } 4488 4489 l = 8 - l; 4490 plen += l; 4491 } 4492 4493 len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(saddr), plen); 4494 } 4495 break; 4496 4497 case IPSECDOI_ID_IPV4_ADDR_RANGE: 4498 4499 len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr)); 4500 4501 #ifndef __linux__ 4502 saddr->sa_len = sizeof(struct sockaddr_in); 4503 #endif 4504 saddr->sa_family = AF_INET; 4505 saddr_in->sin_port = IPSEC_PORT_ANY; 4506 memcpy(&saddr_in->sin_addr, 4507 id->v + sizeof(*id_b) + sizeof(struct in_addr), 4508 sizeof(struct in_addr)); 4509 4510 len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr)); 4511 4512 break; 4513 4514 #ifdef INET6 4515 case IPSECDOI_ID_IPV6_ADDR_RANGE: 4516 4517 len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr)); 4518 4519 #ifndef __linux__ 4520 saddr->sa_len = sizeof(struct sockaddr_in6); 4521 #endif 4522 saddr->sa_family = AF_INET6; 4523 saddr_in6->sin6_port = IPSEC_PORT_ANY; 4524 memcpy(&saddr_in6->sin6_addr, 4525 id->v + sizeof(*id_b) + sizeof(struct in6_addr), 4526 sizeof(struct in6_addr)); 4527 saddr_in6->sin6_scope_id = 4528 (IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr) 4529 ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id 4530 : 0); 4531 4532 len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr)); 4533 4534 break; 4535 #endif 4536 4537 case IPSECDOI_ID_FQDN: 4538 case IPSECDOI_ID_USER_FQDN: 4539 len = id->l - sizeof(*id_b); 4540 if (len > BUFLEN) 4541 len = BUFLEN; 4542 memcpy(buf, id->v + sizeof(*id_b), len); 4543 break; 4544 4545 case IPSECDOI_ID_DER_ASN1_DN: 4546 case IPSECDOI_ID_DER_ASN1_GN: 4547 { 4548 X509_NAME *xn = NULL; 4549 4550 dat = id->v + sizeof(*id_b); 4551 len = id->l - sizeof(*id_b); 4552 4553 if (d2i_X509_NAME(&xn, (void*) &dat, len) != NULL) { 4554 BIO *bio = BIO_new(BIO_s_mem()); 4555 X509_NAME_print_ex(bio, xn, 0, 0); 4556 len = BIO_get_mem_data(bio, &dat); 4557 if (len > BUFLEN) 4558 len = BUFLEN; 4559 memcpy(buf,dat,len); 4560 BIO_free(bio); 4561 X509_NAME_free(xn); 4562 } else { 4563 plog(LLV_ERROR, LOCATION, NULL, 4564 "unable to extract asn1dn from id\n"); 4565 4566 len = sprintf(buf, "<ASN1-DN>"); 4567 } 4568 4569 break; 4570 } 4571 4572 /* currently unhandled id types */ 4573 case IPSECDOI_ID_KEY_ID: 4574 len = sprintf( buf, "<KEY-ID>"); 4575 break; 4576 4577 default: 4578 plog(LLV_ERROR, LOCATION, NULL, 4579 "unknown ID type %d\n", id_b->type); 4580 } 4581 4582 if (!len) 4583 len = sprintf( buf, "<?>"); 4584 4585 ret = racoon_malloc(len+1); 4586 if (ret != NULL) { 4587 memcpy(ret,buf,len); 4588 ret[len]=0; 4589 } 4590 4591 return ret; 4592 } 4593 4594 /* 4595 * set IPsec data attributes into a proposal. 4596 * NOTE: MUST called per a transform. 4597 */ 4598 int 4599 ipsecdoi_t2satrns(t, pp, pr, tr) 4600 struct isakmp_pl_t *t; 4601 struct saprop *pp; 4602 struct saproto *pr; 4603 struct satrns *tr; 4604 { 4605 struct isakmp_data *d, *prev; 4606 int flag, type; 4607 int error = -1; 4608 int life_t; 4609 int tlen; 4610 4611 tr->trns_no = t->t_no; 4612 tr->trns_id = t->t_id; 4613 4614 tlen = ntohs(t->h.len) - sizeof(*t); 4615 prev = (struct isakmp_data *)NULL; 4616 d = (struct isakmp_data *)(t + 1); 4617 4618 /* default */ 4619 life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT; 4620 pp->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; 4621 pp->lifebyte = 0; 4622 tr->authtype = IPSECDOI_ATTR_AUTH_NONE; 4623 4624 while (tlen > 0) { 4625 4626 type = ntohs(d->type) & ~ISAKMP_GEN_MASK; 4627 flag = ntohs(d->type) & ISAKMP_GEN_MASK; 4628 4629 plog(LLV_DEBUG, LOCATION, NULL, 4630 "type=%s, flag=0x%04x, lorv=%s\n", 4631 s_ipsecdoi_attr(type), flag, 4632 s_ipsecdoi_attr_v(type, ntohs(d->lorv))); 4633 4634 switch (type) { 4635 case IPSECDOI_ATTR_SA_LD_TYPE: 4636 { 4637 int type = ntohs(d->lorv); 4638 switch (type) { 4639 case IPSECDOI_ATTR_SA_LD_TYPE_SEC: 4640 case IPSECDOI_ATTR_SA_LD_TYPE_KB: 4641 life_t = type; 4642 break; 4643 default: 4644 plog(LLV_WARNING, LOCATION, NULL, 4645 "invalid life duration type. " 4646 "use default\n"); 4647 life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT; 4648 break; 4649 } 4650 break; 4651 } 4652 case IPSECDOI_ATTR_SA_LD: 4653 if (prev == NULL 4654 || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) != 4655 IPSECDOI_ATTR_SA_LD_TYPE) { 4656 plog(LLV_ERROR, LOCATION, NULL, 4657 "life duration must follow ltype\n"); 4658 break; 4659 } 4660 4661 { 4662 u_int32_t t; 4663 vchar_t *ld_buf = NULL; 4664 4665 if (flag) { 4666 /* i.e. ISAKMP_GEN_TV */ 4667 ld_buf = vmalloc(sizeof(d->lorv)); 4668 if (ld_buf == NULL) { 4669 plog(LLV_ERROR, LOCATION, NULL, 4670 "failed to get LD buffer.\n"); 4671 goto end; 4672 } 4673 memcpy(ld_buf->v, &d->lorv, sizeof(d->lorv)); 4674 } else { 4675 int len = ntohs(d->lorv); 4676 /* i.e. ISAKMP_GEN_TLV */ 4677 ld_buf = vmalloc(len); 4678 if (ld_buf == NULL) { 4679 plog(LLV_ERROR, LOCATION, NULL, 4680 "failed to get LD buffer.\n"); 4681 goto end; 4682 } 4683 memcpy(ld_buf->v, d + 1, len); 4684 } 4685 switch (life_t) { 4686 case IPSECDOI_ATTR_SA_LD_TYPE_SEC: 4687 t = ipsecdoi_set_ld(ld_buf); 4688 vfree(ld_buf); 4689 if (t == 0) { 4690 plog(LLV_ERROR, LOCATION, NULL, 4691 "invalid life duration.\n"); 4692 goto end; 4693 } 4694 /* lifetime must be equal in a proposal. */ 4695 if (pp->lifetime == IPSECDOI_ATTR_SA_LD_SEC_DEFAULT) 4696 pp->lifetime = t; 4697 else if (pp->lifetime != t) { 4698 plog(LLV_ERROR, LOCATION, NULL, 4699 "lifetime mismatched " 4700 "in a proposal, " 4701 "prev:%ld curr:%u.\n", 4702 (long)pp->lifetime, t); 4703 goto end; 4704 } 4705 break; 4706 case IPSECDOI_ATTR_SA_LD_TYPE_KB: 4707 t = ipsecdoi_set_ld(ld_buf); 4708 vfree(ld_buf); 4709 if (t == 0) { 4710 plog(LLV_ERROR, LOCATION, NULL, 4711 "invalid life duration.\n"); 4712 goto end; 4713 } 4714 /* lifebyte must be equal in a proposal. */ 4715 if (pp->lifebyte == 0) 4716 pp->lifebyte = t; 4717 else if (pp->lifebyte != t) { 4718 plog(LLV_ERROR, LOCATION, NULL, 4719 "lifebyte mismatched " 4720 "in a proposal, " 4721 "prev:%d curr:%u.\n", 4722 pp->lifebyte, t); 4723 goto end; 4724 } 4725 break; 4726 default: 4727 vfree(ld_buf); 4728 plog(LLV_ERROR, LOCATION, NULL, 4729 "invalid life type: %d\n", life_t); 4730 goto end; 4731 } 4732 } 4733 break; 4734 4735 case IPSECDOI_ATTR_GRP_DESC: 4736 /* 4737 * RFC2407: 4.5 IPSEC Security Association Attributes 4738 * Specifies the Oakley Group to be used in a PFS QM 4739 * negotiation. For a list of supported values, see 4740 * Appendix A of [IKE]. 4741 */ 4742 if (pp->pfs_group == 0) 4743 pp->pfs_group = (u_int16_t)ntohs(d->lorv); 4744 else if (pp->pfs_group != (u_int16_t)ntohs(d->lorv)) { 4745 plog(LLV_ERROR, LOCATION, NULL, 4746 "pfs_group mismatched " 4747 "in a proposal.\n"); 4748 goto end; 4749 } 4750 break; 4751 4752 case IPSECDOI_ATTR_ENC_MODE: 4753 if (pr->encmode && 4754 pr->encmode != (u_int16_t)ntohs(d->lorv)) { 4755 plog(LLV_ERROR, LOCATION, NULL, 4756 "multiple encmode exist " 4757 "in a transform.\n"); 4758 goto end; 4759 } 4760 pr->encmode = (u_int16_t)ntohs(d->lorv); 4761 break; 4762 4763 case IPSECDOI_ATTR_AUTH: 4764 if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE) { 4765 plog(LLV_ERROR, LOCATION, NULL, 4766 "multiple authtype exist " 4767 "in a transform.\n"); 4768 goto end; 4769 } 4770 tr->authtype = (u_int16_t)ntohs(d->lorv); 4771 break; 4772 4773 case IPSECDOI_ATTR_KEY_LENGTH: 4774 if (pr->proto_id != IPSECDOI_PROTO_IPSEC_ESP) { 4775 plog(LLV_ERROR, LOCATION, NULL, 4776 "key length defined but not ESP"); 4777 goto end; 4778 } 4779 tr->encklen = ntohs(d->lorv); 4780 break; 4781 #ifdef HAVE_SECCTX 4782 case IPSECDOI_ATTR_SECCTX: 4783 { 4784 int len = ntohs(d->lorv); 4785 memcpy(&pp->sctx, d + 1, len); 4786 pp->sctx.ctx_strlen = ntohs(pp->sctx.ctx_strlen); 4787 break; 4788 } 4789 #endif /* HAVE_SECCTX */ 4790 case IPSECDOI_ATTR_KEY_ROUNDS: 4791 case IPSECDOI_ATTR_COMP_DICT_SIZE: 4792 case IPSECDOI_ATTR_COMP_PRIVALG: 4793 default: 4794 break; 4795 } 4796 4797 prev = d; 4798 if (flag) { 4799 tlen -= sizeof(*d); 4800 d = (struct isakmp_data *)((char *)d + sizeof(*d)); 4801 } else { 4802 tlen -= (sizeof(*d) + ntohs(d->lorv)); 4803 d = (struct isakmp_data *)((caddr_t)d + sizeof(*d) + ntohs(d->lorv)); 4804 } 4805 } 4806 4807 error = 0; 4808 end: 4809 return error; 4810 } 4811 4812 int 4813 ipsecdoi_authalg2trnsid(alg) 4814 int alg; 4815 { 4816 switch (alg) { 4817 case IPSECDOI_ATTR_AUTH_HMAC_MD5: 4818 return IPSECDOI_AH_MD5; 4819 case IPSECDOI_ATTR_AUTH_HMAC_SHA1: 4820 return IPSECDOI_AH_SHA; 4821 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256: 4822 return IPSECDOI_AH_SHA256; 4823 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384: 4824 return IPSECDOI_AH_SHA384; 4825 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512: 4826 return IPSECDOI_AH_SHA512; 4827 case IPSECDOI_ATTR_AUTH_DES_MAC: 4828 return IPSECDOI_AH_DES; 4829 case IPSECDOI_ATTR_AUTH_KPDK: 4830 return IPSECDOI_AH_MD5; /* XXX */ 4831 default: 4832 plog(LLV_ERROR, LOCATION, NULL, 4833 "invalid authentication algorithm:%d\n", alg); 4834 } 4835 return -1; 4836 } 4837 4838 #ifdef HAVE_GSSAPI 4839 struct isakmpsa * 4840 fixup_initiator_sa(match, received) 4841 struct isakmpsa *match, *received; 4842 { 4843 if (received->gssid != NULL) 4844 match->gssid = vdup(received->gssid); 4845 4846 return match; 4847 } 4848 #endif 4849 4850 static int rm_idtype2doi[] = { 4851 255, /* IDTYPE_UNDEFINED, 0 */ 4852 IPSECDOI_ID_FQDN, /* IDTYPE_FQDN, 1 */ 4853 IPSECDOI_ID_USER_FQDN, /* IDTYPE_USERFQDN, 2 */ 4854 IPSECDOI_ID_KEY_ID, /* IDTYPE_KEYID, 3 */ 4855 255, /* IDTYPE_ADDRESS, 4 4856 * it expands into 4 types by another function. */ 4857 IPSECDOI_ID_DER_ASN1_DN, /* IDTYPE_ASN1DN, 5 */ 4858 }; 4859 4860 /* 4861 * convert idtype to DOI value. 4862 * OUT 255 : NG 4863 * other: converted. 4864 */ 4865 int 4866 idtype2doi(idtype) 4867 int idtype; 4868 { 4869 if (ARRAYLEN(rm_idtype2doi) > idtype) 4870 return rm_idtype2doi[idtype]; 4871 return 255; 4872 } 4873 4874 int 4875 doi2idtype(doi) 4876 int doi; 4877 { 4878 switch(doi) { 4879 case IPSECDOI_ID_FQDN: 4880 return(IDTYPE_FQDN); 4881 case IPSECDOI_ID_USER_FQDN: 4882 return(IDTYPE_USERFQDN); 4883 case IPSECDOI_ID_KEY_ID: 4884 return(IDTYPE_KEYID); 4885 case IPSECDOI_ID_DER_ASN1_DN: 4886 return(IDTYPE_ASN1DN); 4887 case IPSECDOI_ID_IPV4_ADDR: 4888 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4889 case IPSECDOI_ID_IPV6_ADDR: 4890 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4891 return(IDTYPE_ADDRESS); 4892 default: 4893 plog(LLV_WARNING, LOCATION, NULL, 4894 "Inproper idtype:%s in this function.\n", 4895 s_ipsecdoi_ident(doi)); 4896 return(IDTYPE_ADDRESS); /* XXX */ 4897 } 4898 /*NOTREACHED*/ 4899 } 4900 4901 #ifdef ENABLE_HYBRID 4902 static int 4903 switch_authmethod(authmethod) 4904 int authmethod; 4905 { 4906 switch(authmethod) { 4907 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 4908 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I; 4909 break; 4910 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 4911 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I; 4912 break; 4913 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 4914 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; 4915 break; 4916 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 4917 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; 4918 break; 4919 /* Those are not implemented */ 4920 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 4921 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I; 4922 break; 4923 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 4924 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I; 4925 break; 4926 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 4927 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I; 4928 break; 4929 default: 4930 break; 4931 } 4932 4933 return authmethod; 4934 } 4935 #endif 4936