1 /* $NetBSD: ipsec_doi.c,v 1.34 2008/02/25 20:06:55 manu 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 && iph1->approval != 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 pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC && 3242 pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT) 3243 return 0; 3244 } 3245 } 3246 3247 return 1; 3248 } 3249 3250 int 3251 ipsecdoi_get_defaultlifetime() 3252 { 3253 return IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; 3254 } 3255 3256 int 3257 ipsecdoi_checkalgtypes(proto_id, enc, auth, comp) 3258 int proto_id, enc, auth, comp; 3259 { 3260 #define TMPALGTYPE2STR(n) s_algtype(algclass_ipsec_##n, n) 3261 switch (proto_id) { 3262 case IPSECDOI_PROTO_IPSEC_ESP: 3263 if (enc == 0 || comp != 0) { 3264 plog(LLV_ERROR, LOCATION, NULL, 3265 "illegal algorithm defined " 3266 "ESP enc=%s auth=%s comp=%s.\n", 3267 TMPALGTYPE2STR(enc), 3268 TMPALGTYPE2STR(auth), 3269 TMPALGTYPE2STR(comp)); 3270 return -1; 3271 } 3272 break; 3273 case IPSECDOI_PROTO_IPSEC_AH: 3274 if (enc != 0 || auth == 0 || comp != 0) { 3275 plog(LLV_ERROR, LOCATION, NULL, 3276 "illegal algorithm defined " 3277 "AH enc=%s auth=%s comp=%s.\n", 3278 TMPALGTYPE2STR(enc), 3279 TMPALGTYPE2STR(auth), 3280 TMPALGTYPE2STR(comp)); 3281 return -1; 3282 } 3283 break; 3284 case IPSECDOI_PROTO_IPCOMP: 3285 if (enc != 0 || auth != 0 || comp == 0) { 3286 plog(LLV_ERROR, LOCATION, NULL, 3287 "illegal algorithm defined " 3288 "IPcomp enc=%s auth=%s comp=%s.\n", 3289 TMPALGTYPE2STR(enc), 3290 TMPALGTYPE2STR(auth), 3291 TMPALGTYPE2STR(comp)); 3292 return -1; 3293 } 3294 break; 3295 default: 3296 plog(LLV_ERROR, LOCATION, NULL, 3297 "invalid ipsec protocol %d\n", proto_id); 3298 return -1; 3299 } 3300 #undef TMPALGTYPE2STR 3301 return 0; 3302 } 3303 3304 int 3305 ipproto2doi(proto) 3306 int proto; 3307 { 3308 switch (proto) { 3309 case IPPROTO_AH: 3310 return IPSECDOI_PROTO_IPSEC_AH; 3311 case IPPROTO_ESP: 3312 return IPSECDOI_PROTO_IPSEC_ESP; 3313 case IPPROTO_IPCOMP: 3314 return IPSECDOI_PROTO_IPCOMP; 3315 } 3316 return -1; /* XXX */ 3317 } 3318 3319 int 3320 doi2ipproto(proto) 3321 int proto; 3322 { 3323 switch (proto) { 3324 case IPSECDOI_PROTO_IPSEC_AH: 3325 return IPPROTO_AH; 3326 case IPSECDOI_PROTO_IPSEC_ESP: 3327 return IPPROTO_ESP; 3328 case IPSECDOI_PROTO_IPCOMP: 3329 return IPPROTO_IPCOMP; 3330 } 3331 return -1; /* XXX */ 3332 } 3333 3334 /* 3335 * Check if a subnet id is valid for comparison 3336 * with an address id ( address length mask ) 3337 * and compare them 3338 * Return value 3339 * = 0 for match 3340 * = 1 for mismatch 3341 */ 3342 3343 int 3344 ipsecdoi_subnetisaddr_v4( subnet, address ) 3345 const vchar_t *subnet; 3346 const vchar_t *address; 3347 { 3348 struct in_addr *mask; 3349 3350 if (address->l != sizeof(struct in_addr)) 3351 return 1; 3352 3353 if (subnet->l != (sizeof(struct in_addr)*2)) 3354 return 1; 3355 3356 mask = (struct in_addr*)(subnet->v + sizeof(struct in_addr)); 3357 3358 if (mask->s_addr!=0xffffffff) 3359 return 1; 3360 3361 return memcmp(subnet->v,address->v,address->l); 3362 } 3363 3364 #ifdef INET6 3365 3366 int 3367 ipsecdoi_subnetisaddr_v6( subnet, address ) 3368 const vchar_t *subnet; 3369 const vchar_t *address; 3370 { 3371 struct in6_addr *mask; 3372 int i; 3373 3374 if (address->l != sizeof(struct in6_addr)) 3375 return 1; 3376 3377 if (subnet->l != (sizeof(struct in6_addr)*2)) 3378 return 1; 3379 3380 mask = (struct in6_addr*)(subnet->v + sizeof(struct in6_addr)); 3381 3382 for (i=0; i<16; i++) 3383 if(mask->s6_addr[i]!=0xff) 3384 return 1; 3385 3386 return memcmp(subnet->v,address->v,address->l); 3387 } 3388 3389 #endif 3390 3391 /* 3392 * Check and Compare two IDs 3393 * - specify 0 for exact if wildcards are allowed 3394 * Return value 3395 * = 0 for match 3396 * = 1 for misatch 3397 * = -1 for integrity error 3398 */ 3399 3400 int 3401 ipsecdoi_chkcmpids( idt, ids, exact ) 3402 const vchar_t *idt; /* id cmp target */ 3403 const vchar_t *ids; /* id cmp source */ 3404 int exact; 3405 { 3406 struct ipsecdoi_id_b *id_bt; 3407 struct ipsecdoi_id_b *id_bs; 3408 vchar_t ident_t; 3409 vchar_t ident_s; 3410 int result; 3411 3412 /* handle wildcard IDs */ 3413 3414 if (idt == NULL || ids == NULL) 3415 { 3416 if( !exact ) 3417 { 3418 plog(LLV_DEBUG, LOCATION, NULL, 3419 "check and compare ids : values matched (ANONYMOUS)\n" ); 3420 return 0; 3421 } 3422 else 3423 { 3424 plog(LLV_DEBUG, LOCATION, NULL, 3425 "check and compare ids : value mismatch (ANONYMOUS)\n" ); 3426 return -1; 3427 } 3428 } 3429 3430 /* make sure the ids are of the same type */ 3431 3432 id_bt = (struct ipsecdoi_id_b *) idt->v; 3433 id_bs = (struct ipsecdoi_id_b *) ids->v; 3434 3435 ident_t.v = idt->v + sizeof(*id_bt); 3436 ident_t.l = idt->l - sizeof(*id_bt); 3437 ident_s.v = ids->v + sizeof(*id_bs); 3438 ident_s.l = ids->l - sizeof(*id_bs); 3439 3440 if (id_bs->type != id_bt->type) 3441 { 3442 /* 3443 * special exception for comparing 3444 * address to subnet id types when 3445 * the netmask is address length 3446 */ 3447 3448 if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&& 3449 (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) { 3450 result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s); 3451 goto cmpid_result; 3452 } 3453 3454 if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&& 3455 (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) { 3456 result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t); 3457 goto cmpid_result; 3458 } 3459 3460 #ifdef INET6 3461 if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&& 3462 (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { 3463 result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s); 3464 goto cmpid_result; 3465 } 3466 3467 if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&& 3468 (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) { 3469 result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t); 3470 goto cmpid_result; 3471 } 3472 #endif 3473 plog(LLV_DEBUG, LOCATION, NULL, 3474 "check and compare ids : id type mismatch %s != %s\n", 3475 s_ipsecdoi_ident(id_bs->type), 3476 s_ipsecdoi_ident(id_bt->type)); 3477 3478 return 1; 3479 } 3480 3481 if(id_bs->proto_id != id_bt->proto_id){ 3482 plog(LLV_DEBUG, LOCATION, NULL, 3483 "check and compare ids : proto_id mismatch %d != %d\n", 3484 id_bs->proto_id, id_bt->proto_id); 3485 3486 return 1; 3487 } 3488 3489 /* compare the ID data. */ 3490 3491 switch (id_bt->type) { 3492 case IPSECDOI_ID_DER_ASN1_DN: 3493 case IPSECDOI_ID_DER_ASN1_GN: 3494 /* compare asn1 ids */ 3495 result = eay_cmp_asn1dn(&ident_t, &ident_s); 3496 goto cmpid_result; 3497 3498 case IPSECDOI_ID_IPV4_ADDR: 3499 /* validate lengths */ 3500 if ((ident_t.l != sizeof(struct in_addr))|| 3501 (ident_s.l != sizeof(struct in_addr))) 3502 goto cmpid_invalid; 3503 break; 3504 3505 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 3506 case IPSECDOI_ID_IPV4_ADDR_RANGE: 3507 /* validate lengths */ 3508 if ((ident_t.l != (sizeof(struct in_addr)*2))|| 3509 (ident_s.l != (sizeof(struct in_addr)*2))) 3510 goto cmpid_invalid; 3511 break; 3512 3513 #ifdef INET6 3514 case IPSECDOI_ID_IPV6_ADDR: 3515 /* validate lengths */ 3516 if ((ident_t.l != sizeof(struct in6_addr))|| 3517 (ident_s.l != sizeof(struct in6_addr))) 3518 goto cmpid_invalid; 3519 break; 3520 3521 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 3522 case IPSECDOI_ID_IPV6_ADDR_RANGE: 3523 /* validate lengths */ 3524 if ((ident_t.l != (sizeof(struct in6_addr)*2))|| 3525 (ident_s.l != (sizeof(struct in6_addr)*2))) 3526 goto cmpid_invalid; 3527 break; 3528 #endif 3529 case IPSECDOI_ID_FQDN: 3530 case IPSECDOI_ID_USER_FQDN: 3531 case IPSECDOI_ID_KEY_ID: 3532 break; 3533 3534 default: 3535 plog(LLV_ERROR, LOCATION, NULL, 3536 "Unhandled id type %i specified for comparison\n", 3537 id_bt->type); 3538 return -1; 3539 } 3540 3541 /* validate matching data and length */ 3542 if (ident_t.l == ident_s.l) 3543 result = memcmp(ident_t.v,ident_s.v,ident_t.l); 3544 else 3545 result = 1; 3546 3547 cmpid_result: 3548 3549 /* debug level output */ 3550 if(loglevel >= LLV_DEBUG) { 3551 char *idstrt = ipsecdoi_id2str(idt); 3552 char *idstrs = ipsecdoi_id2str(ids); 3553 3554 if (!result) 3555 plog(LLV_DEBUG, LOCATION, NULL, 3556 "check and compare ids : values matched (%s)\n", 3557 s_ipsecdoi_ident(id_bs->type) ); 3558 else 3559 plog(LLV_DEBUG, LOCATION, NULL, 3560 "check and compare ids : value mismatch (%s)\n", 3561 s_ipsecdoi_ident(id_bs->type)); 3562 3563 plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: \'%s\'\n", idstrt ); 3564 plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: \'%s\'\n", idstrs ); 3565 3566 racoon_free(idstrs); 3567 racoon_free(idstrt); 3568 } 3569 3570 /* return result */ 3571 if( !result ) 3572 return 0; 3573 else 3574 return 1; 3575 3576 cmpid_invalid: 3577 3578 /* id integrity error */ 3579 plog(LLV_DEBUG, LOCATION, NULL, "check and compare ids : %s integrity error\n", 3580 s_ipsecdoi_ident(id_bs->type)); 3581 plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: length = \'%zu\'\n", ident_t.l ); 3582 plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: length = \'%zu\'\n", ident_s.l ); 3583 3584 return -1; 3585 } 3586 3587 /* 3588 * check the following: 3589 * - In main mode with pre-shared key, only address type can be used. 3590 * - if proper type for phase 1 ? 3591 * - if phase 1 ID payload conformed RFC2407 4.6.2. 3592 * (proto, port) must be (0, 0), (udp, 500) or (udp, [specified]). 3593 * - if ID payload sent from peer is equal to the ID expected by me. 3594 * 3595 * both of "id" and "id_p" should be ID payload without general header, 3596 */ 3597 int 3598 ipsecdoi_checkid1(iph1) 3599 struct ph1handle *iph1; 3600 { 3601 struct ipsecdoi_id_b *id_b; 3602 struct sockaddr *sa; 3603 caddr_t sa1, sa2; 3604 3605 if (iph1->id_p == NULL) { 3606 plog(LLV_ERROR, LOCATION, NULL, 3607 "invalid iph1 passed id_p == NULL\n"); 3608 return ISAKMP_INTERNAL_ERROR; 3609 } 3610 if (iph1->id_p->l < sizeof(*id_b)) { 3611 plog(LLV_ERROR, LOCATION, NULL, 3612 "invalid value passed as \"ident\" (len=%lu)\n", 3613 (u_long)iph1->id_p->l); 3614 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 3615 } 3616 3617 id_b = (struct ipsecdoi_id_b *)iph1->id_p->v; 3618 3619 /* In main mode with pre-shared key, only address type can be used. */ 3620 if (iph1->etype == ISAKMP_ETYPE_IDENT && 3621 iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_PSKEY) { 3622 if (id_b->type != IPSECDOI_ID_IPV4_ADDR 3623 && id_b->type != IPSECDOI_ID_IPV6_ADDR) { 3624 plog(LLV_ERROR, LOCATION, NULL, 3625 "Expecting IP address type in main mode, " 3626 "but %s.\n", s_ipsecdoi_ident(id_b->type)); 3627 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 3628 } 3629 } 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 3661 u_int16_t port; 3662 3663 switch (iph1->remote->sa_family) { 3664 case AF_INET: 3665 port = ((struct sockaddr_in *)iph1->remote)->sin_port; 3666 break; 3667 #ifdef INET6 3668 case AF_INET6: 3669 port = ((struct sockaddr_in6 *)iph1->remote)->sin6_port; 3670 break; 3671 #endif 3672 default: 3673 plog(LLV_ERROR, LOCATION, NULL, 3674 "invalid family: %d\n", 3675 iph1->remote->sa_family); 3676 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 3677 } 3678 if (ntohs(id_b->port) != port) { 3679 plog(LLV_WARNING, LOCATION, NULL, 3680 "port %d expected, but %d\n", 3681 port, ntohs(id_b->port)); 3682 /*FALLTHROUGH*/ 3683 } 3684 } 3685 } 3686 } 3687 3688 /* compare with the ID if specified. */ 3689 if (genlist_next(iph1->rmconf->idvl_p, 0)) { 3690 vchar_t *ident0 = NULL; 3691 vchar_t ident; 3692 struct idspec *id; 3693 struct genlist_entry *gpb; 3694 3695 for (id = genlist_next (iph1->rmconf->idvl_p, &gpb); id; id = genlist_next (0, &gpb)) { 3696 /* check the type of both IDs */ 3697 if (id->idtype != doi2idtype(id_b->type)) 3698 continue; /* ID type mismatch */ 3699 if (id->id == 0) 3700 goto matched; 3701 3702 /* compare defined ID with the ID sent by peer. */ 3703 if (ident0 != NULL) 3704 vfree(ident0); 3705 ident0 = getidval(id->idtype, id->id); 3706 3707 switch (id->idtype) { 3708 case IDTYPE_ASN1DN: 3709 ident.v = iph1->id_p->v + sizeof(*id_b); 3710 ident.l = iph1->id_p->l - sizeof(*id_b); 3711 if (eay_cmp_asn1dn(ident0, &ident) == 0) 3712 goto matched; 3713 break; 3714 case IDTYPE_ADDRESS: 3715 sa = (struct sockaddr *)ident0->v; 3716 sa2 = (caddr_t)(id_b + 1); 3717 switch (sa->sa_family) { 3718 case AF_INET: 3719 if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in_addr)) 3720 continue; /* ID value mismatch */ 3721 sa1 = (caddr_t)&((struct sockaddr_in *)sa)->sin_addr; 3722 if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0) 3723 goto matched; 3724 break; 3725 #ifdef INET6 3726 case AF_INET6: 3727 if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in6_addr)) 3728 continue; /* ID value mismatch */ 3729 sa1 = (caddr_t)&((struct sockaddr_in6 *)sa)->sin6_addr; 3730 if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0) 3731 goto matched; 3732 break; 3733 #endif 3734 default: 3735 break; 3736 } 3737 break; 3738 default: 3739 if (memcmp(ident0->v, id_b + 1, ident0->l) == 0) 3740 goto matched; 3741 break; 3742 } 3743 } 3744 if (ident0 != NULL) { 3745 vfree(ident0); 3746 ident0 = NULL; 3747 } 3748 plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n"); 3749 if (iph1->rmconf->verify_identifier) 3750 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 3751 matched: /* ID value match */ 3752 if (ident0 != NULL) 3753 vfree(ident0); 3754 } 3755 3756 return 0; 3757 } 3758 3759 /* 3760 * create ID payload for phase 1 and set into iph1->id. 3761 * NOT INCLUDING isakmp general header. 3762 * see, RFC2407 4.6.2.1 3763 */ 3764 int 3765 ipsecdoi_setid1(iph1) 3766 struct ph1handle *iph1; 3767 { 3768 vchar_t *ret = NULL; 3769 struct ipsecdoi_id_b id_b; 3770 vchar_t *ident = NULL; 3771 struct sockaddr *ipid = NULL; 3772 3773 /* init */ 3774 id_b.proto_id = 0; 3775 id_b.port = 0; 3776 ident = NULL; 3777 3778 switch (iph1->rmconf->idvtype) { 3779 case IDTYPE_FQDN: 3780 id_b.type = IPSECDOI_ID_FQDN; 3781 ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv); 3782 break; 3783 case IDTYPE_USERFQDN: 3784 id_b.type = IPSECDOI_ID_USER_FQDN; 3785 ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv); 3786 break; 3787 case IDTYPE_KEYID: 3788 id_b.type = IPSECDOI_ID_KEY_ID; 3789 ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv); 3790 break; 3791 case IDTYPE_ASN1DN: 3792 id_b.type = IPSECDOI_ID_DER_ASN1_DN; 3793 if (iph1->rmconf->idv) { 3794 /* XXX it must be encoded to asn1dn. */ 3795 ident = vdup(iph1->rmconf->idv); 3796 } else { 3797 if (oakley_getmycert(iph1) < 0) { 3798 plog(LLV_ERROR, LOCATION, NULL, 3799 "failed to get own CERT.\n"); 3800 goto err; 3801 } 3802 ident = eay_get_x509asn1subjectname(&iph1->cert->cert); 3803 } 3804 break; 3805 case IDTYPE_ADDRESS: 3806 /* 3807 * if the value of the id type was set by the configuration 3808 * file, then use it. otherwise the value is get from local 3809 * ip address by using ike negotiation. 3810 */ 3811 if (iph1->rmconf->idv) 3812 ipid = (struct sockaddr *)iph1->rmconf->idv->v; 3813 /*FALLTHROUGH*/ 3814 default: 3815 { 3816 int l; 3817 caddr_t p; 3818 3819 if (ipid == NULL) 3820 ipid = iph1->local; 3821 3822 /* use IP address */ 3823 switch (ipid->sa_family) { 3824 case AF_INET: 3825 id_b.type = IPSECDOI_ID_IPV4_ADDR; 3826 l = sizeof(struct in_addr); 3827 p = (caddr_t)&((struct sockaddr_in *)ipid)->sin_addr; 3828 break; 3829 #ifdef INET6 3830 case AF_INET6: 3831 id_b.type = IPSECDOI_ID_IPV6_ADDR; 3832 l = sizeof(struct in6_addr); 3833 p = (caddr_t)&((struct sockaddr_in6 *)ipid)->sin6_addr; 3834 break; 3835 #endif 3836 default: 3837 plog(LLV_ERROR, LOCATION, NULL, 3838 "invalid address family.\n"); 3839 goto err; 3840 } 3841 id_b.proto_id = IPPROTO_UDP; 3842 id_b.port = htons(PORT_ISAKMP); 3843 ident = vmalloc(l); 3844 if (!ident) { 3845 plog(LLV_ERROR, LOCATION, NULL, 3846 "failed to get ID buffer.\n"); 3847 return 0; 3848 } 3849 memcpy(ident->v, p, ident->l); 3850 } 3851 } 3852 if (!ident) { 3853 plog(LLV_ERROR, LOCATION, NULL, 3854 "failed to get ID buffer.\n"); 3855 return 0; 3856 } 3857 3858 ret = vmalloc(sizeof(id_b) + ident->l); 3859 if (ret == NULL) { 3860 plog(LLV_ERROR, LOCATION, NULL, 3861 "failed to get ID buffer.\n"); 3862 goto err; 3863 } 3864 3865 memcpy(ret->v, &id_b, sizeof(id_b)); 3866 memcpy(ret->v + sizeof(id_b), ident->v, ident->l); 3867 3868 iph1->id = ret; 3869 3870 plog(LLV_DEBUG, LOCATION, NULL, 3871 "use ID type of %s\n", s_ipsecdoi_ident(id_b.type)); 3872 if (ident) 3873 vfree(ident); 3874 return 0; 3875 3876 err: 3877 if (ident) 3878 vfree(ident); 3879 plog(LLV_ERROR, LOCATION, NULL, "failed get my ID\n"); 3880 return -1; 3881 } 3882 3883 static vchar_t * 3884 getidval(type, val) 3885 int type; 3886 vchar_t *val; 3887 { 3888 vchar_t *new = NULL; 3889 3890 if (val) 3891 new = vdup(val); 3892 else if (lcconf->ident[type]) 3893 new = vdup(lcconf->ident[type]); 3894 3895 return new; 3896 } 3897 3898 /* it's only called by cfparse.y. */ 3899 int 3900 set_identifier(vpp, type, value) 3901 vchar_t **vpp, *value; 3902 int type; 3903 { 3904 return set_identifier_qual(vpp, type, value, IDQUAL_UNSPEC); 3905 } 3906 3907 int 3908 set_identifier_qual(vpp, type, value, qual) 3909 vchar_t **vpp, *value; 3910 int type; 3911 int qual; 3912 { 3913 vchar_t *new = NULL; 3914 3915 /* simply return if value is null. */ 3916 if (!value){ 3917 if( type == IDTYPE_FQDN || type == IDTYPE_USERFQDN){ 3918 plog(LLV_ERROR, LOCATION, NULL, 3919 "No %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn"); 3920 return -1; 3921 } 3922 return 0; 3923 } 3924 3925 switch (type) { 3926 case IDTYPE_FQDN: 3927 case IDTYPE_USERFQDN: 3928 if(value->l <= 1){ 3929 plog(LLV_ERROR, LOCATION, NULL, 3930 "Empty %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn"); 3931 return -1; 3932 } 3933 /* length is adjusted since QUOTEDSTRING teminates NULL. */ 3934 new = vmalloc(value->l - 1); 3935 if (new == NULL) 3936 return -1; 3937 memcpy(new->v, value->v, new->l); 3938 break; 3939 case IDTYPE_KEYID: 3940 /* 3941 * If no qualifier is specified: IDQUAL_UNSPEC. It means 3942 * to use a file for backward compatibility sake. 3943 */ 3944 switch(qual) { 3945 case IDQUAL_FILE: 3946 case IDQUAL_UNSPEC: { 3947 FILE *fp; 3948 char b[512]; 3949 int tlen, len; 3950 3951 fp = fopen(value->v, "r"); 3952 if (fp == NULL) { 3953 plog(LLV_ERROR, LOCATION, NULL, 3954 "can not open %s\n", value->v); 3955 return -1; 3956 } 3957 tlen = 0; 3958 while ((len = fread(b, 1, sizeof(b), fp)) != 0) { 3959 new = vrealloc(new, tlen + len); 3960 if (!new) { 3961 fclose(fp); 3962 return -1; 3963 } 3964 memcpy(new->v + tlen, b, len); 3965 tlen += len; 3966 } 3967 break; 3968 } 3969 3970 case IDQUAL_TAG: 3971 new = vmalloc(value->l - 1); 3972 if (new == NULL) { 3973 plog(LLV_ERROR, LOCATION, NULL, 3974 "can not allocate memory"); 3975 return -1; 3976 } 3977 memcpy(new->v, value->v, new->l); 3978 break; 3979 3980 default: 3981 plog(LLV_ERROR, LOCATION, NULL, 3982 "unknown qualifier"); 3983 return -1; 3984 } 3985 break; 3986 3987 case IDTYPE_ADDRESS: { 3988 struct sockaddr *sa; 3989 3990 /* length is adjusted since QUOTEDSTRING teminates NULL. */ 3991 if (value->l == 0) 3992 break; 3993 3994 sa = str2saddr(value->v, NULL); 3995 if (sa == NULL) { 3996 plog(LLV_ERROR, LOCATION, NULL, 3997 "invalid ip address %s\n", value->v); 3998 return -1; 3999 } 4000 4001 new = vmalloc(sysdep_sa_len(sa)); 4002 if (new == NULL) { 4003 racoon_free(sa); 4004 return -1; 4005 } 4006 memcpy(new->v, sa, new->l); 4007 racoon_free(sa); 4008 break; 4009 } 4010 case IDTYPE_ASN1DN: 4011 if (value->v[0] == '~') 4012 /* Hex-encoded ASN1 strings */ 4013 new = eay_hex2asn1dn(value->v + 1, - 1); 4014 else 4015 /* DN encoded strings */ 4016 new = eay_str2asn1dn(value->v, value->l - 1); 4017 4018 if (new == NULL) 4019 return -1; 4020 4021 if (loglevel >= LLV_DEBUG) { 4022 X509_NAME *xn; 4023 BIO *bio; 4024 unsigned char *ptr = (unsigned char *) new->v, *buf; 4025 size_t len; 4026 char save; 4027 4028 xn = d2i_X509_NAME(NULL, (void *)&ptr, new->l); 4029 bio = BIO_new(BIO_s_mem()); 4030 4031 X509_NAME_print_ex(bio, xn, 0, 0); 4032 len = BIO_get_mem_data(bio, &ptr); 4033 save = ptr[len]; 4034 ptr[len] = 0; 4035 plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", ptr); 4036 ptr[len] = save; 4037 X509_NAME_free(xn); 4038 BIO_free(bio); 4039 } 4040 4041 break; 4042 } 4043 4044 *vpp = new; 4045 4046 return 0; 4047 } 4048 4049 /* 4050 * create ID payload for phase 2, and set into iph2->id and id_p. There are 4051 * NOT INCLUDING isakmp general header. 4052 * this function is for initiator. responder will get to copy from payload. 4053 * responder ID type is always address type. 4054 * see, RFC2407 4.6.2.1 4055 */ 4056 int 4057 ipsecdoi_setid2(iph2) 4058 struct ph2handle *iph2; 4059 { 4060 struct secpolicy *sp; 4061 4062 /* check there is phase 2 handler ? */ 4063 sp = getspbyspid(iph2->spid); 4064 if (sp == NULL) { 4065 plog(LLV_ERROR, LOCATION, NULL, 4066 "no policy found for spid:%u.\n", iph2->spid); 4067 return -1; 4068 } 4069 4070 if (!ipsecdoi_transportmode(iph2->proposal)) 4071 iph2->id = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.src, 4072 sp->spidx.prefs, sp->spidx.ul_proto); 4073 else 4074 iph2->id = ipsecdoi_sockaddr2id(iph2->src, IPSECDOI_PREFIX_HOST, 4075 sp->spidx.ul_proto); 4076 if (iph2->id == NULL) { 4077 plog(LLV_ERROR, LOCATION, NULL, 4078 "failed to get ID for %s\n", 4079 spidx2str(&sp->spidx)); 4080 return -1; 4081 } 4082 plog(LLV_DEBUG, LOCATION, NULL, "use local ID type %s\n", 4083 s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id->v)->type)); 4084 4085 /* remote side */ 4086 if (!ipsecdoi_transportmode(iph2->proposal)) 4087 iph2->id_p = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.dst, 4088 sp->spidx.prefd, sp->spidx.ul_proto); 4089 else 4090 iph2->id_p = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST, 4091 sp->spidx.ul_proto); 4092 if (iph2->id_p == NULL) { 4093 plog(LLV_ERROR, LOCATION, NULL, 4094 "failed to get ID for %s\n", 4095 spidx2str(&sp->spidx)); 4096 VPTRINIT(iph2->id); 4097 return -1; 4098 } 4099 plog(LLV_DEBUG, LOCATION, NULL, 4100 "use remote ID type %s\n", 4101 s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id_p->v)->type)); 4102 4103 return 0; 4104 } 4105 4106 /* 4107 * set address type of ID. 4108 * NOT INCLUDING general header. 4109 */ 4110 vchar_t * 4111 ipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto) 4112 struct sockaddr *saddr; 4113 u_int prefixlen; 4114 u_int ul_proto; 4115 { 4116 vchar_t *new; 4117 int type, len1, len2; 4118 caddr_t sa; 4119 u_short port; 4120 4121 /* 4122 * Q. When type is SUBNET, is it allowed to be ::1/128. 4123 * A. Yes. (consensus at bake-off) 4124 */ 4125 switch (saddr->sa_family) { 4126 case AF_INET: 4127 len1 = sizeof(struct in_addr); 4128 if (prefixlen >= (sizeof(struct in_addr) << 3)) { 4129 type = IPSECDOI_ID_IPV4_ADDR; 4130 len2 = 0; 4131 } else { 4132 type = IPSECDOI_ID_IPV4_ADDR_SUBNET; 4133 len2 = sizeof(struct in_addr); 4134 } 4135 sa = (caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr; 4136 port = ((struct sockaddr_in *)(saddr))->sin_port; 4137 break; 4138 #ifdef INET6 4139 case AF_INET6: 4140 len1 = sizeof(struct in6_addr); 4141 if (prefixlen >= (sizeof(struct in6_addr) << 3)) { 4142 type = IPSECDOI_ID_IPV6_ADDR; 4143 len2 = 0; 4144 } else { 4145 type = IPSECDOI_ID_IPV6_ADDR_SUBNET; 4146 len2 = sizeof(struct in6_addr); 4147 } 4148 sa = (caddr_t)&((struct sockaddr_in6 *)(saddr))->sin6_addr; 4149 port = ((struct sockaddr_in6 *)(saddr))->sin6_port; 4150 break; 4151 #endif 4152 default: 4153 plog(LLV_ERROR, LOCATION, NULL, 4154 "invalid family: %d.\n", saddr->sa_family); 4155 return NULL; 4156 } 4157 4158 /* get ID buffer */ 4159 new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2); 4160 if (new == NULL) { 4161 plog(LLV_ERROR, LOCATION, NULL, 4162 "failed to get ID buffer.\n"); 4163 return NULL; 4164 } 4165 4166 memset(new->v, 0, new->l); 4167 4168 /* set the part of header. */ 4169 ((struct ipsecdoi_id_b *)new->v)->type = type; 4170 4171 /* set ul_proto and port */ 4172 /* 4173 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card 4174 * because 0 means port number of 0. Instead of 0, we use IPSEC_*_ANY. 4175 */ 4176 ((struct ipsecdoi_id_b *)new->v)->proto_id = 4177 ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto; 4178 ((struct ipsecdoi_id_b *)new->v)->port = 4179 port == IPSEC_PORT_ANY ? 0 : port; 4180 memcpy(new->v + sizeof(struct ipsecdoi_id_b), sa, len1); 4181 4182 /* set address */ 4183 4184 /* set prefix */ 4185 if (len2) { 4186 u_char *p = (unsigned char *) new->v + 4187 sizeof(struct ipsecdoi_id_b) + len1; 4188 u_int bits = prefixlen; 4189 4190 while (bits >= 8) { 4191 *p++ = 0xff; 4192 bits -= 8; 4193 } 4194 4195 if (bits > 0) 4196 *p = ~((1 << (8 - bits)) - 1); 4197 } 4198 4199 return new; 4200 } 4201 4202 vchar_t * 4203 ipsecdoi_sockrange2id(laddr, haddr, ul_proto) 4204 struct sockaddr *laddr, *haddr; 4205 u_int ul_proto; 4206 { 4207 vchar_t *new; 4208 int type, len1, len2; 4209 u_short port; 4210 4211 if (laddr->sa_family != haddr->sa_family) { 4212 plog(LLV_ERROR, LOCATION, NULL, "Address family mismatch\n"); 4213 return NULL; 4214 } 4215 4216 switch (laddr->sa_family) { 4217 case AF_INET: 4218 type = IPSECDOI_ID_IPV4_ADDR_RANGE; 4219 len1 = sizeof(struct in_addr); 4220 len2 = sizeof(struct in_addr); 4221 break; 4222 #ifdef INET6 4223 case AF_INET6: 4224 type = IPSECDOI_ID_IPV6_ADDR_RANGE; 4225 len1 = sizeof(struct in6_addr); 4226 len2 = sizeof(struct in6_addr); 4227 break; 4228 #endif 4229 default: 4230 plog(LLV_ERROR, LOCATION, NULL, 4231 "invalid family: %d.\n", laddr->sa_family); 4232 return NULL; 4233 } 4234 4235 /* get ID buffer */ 4236 new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2); 4237 if (new == NULL) { 4238 plog(LLV_ERROR, LOCATION, NULL, 4239 "failed to get ID buffer.\n"); 4240 return NULL; 4241 } 4242 4243 memset(new->v, 0, new->l); 4244 /* set the part of header. */ 4245 ((struct ipsecdoi_id_b *)new->v)->type = type; 4246 4247 /* set ul_proto and port */ 4248 /* 4249 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card 4250 * because 0 means port number of 0. Instead of 0, we use IPSEC_*_ANY. 4251 */ 4252 ((struct ipsecdoi_id_b *)new->v)->proto_id = 4253 ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto; 4254 port = ((struct sockaddr_in *)(laddr))->sin_port; 4255 ((struct ipsecdoi_id_b *)new->v)->port = 4256 port == IPSEC_PORT_ANY ? 0 : port; 4257 memcpy(new->v + sizeof(struct ipsecdoi_id_b), 4258 (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr, 4259 len1); 4260 memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1, 4261 (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr, 4262 len2); 4263 return new; 4264 } 4265 4266 4267 /* 4268 * create sockaddr structure from ID payload (buf). 4269 * buffers (saddr, prefixlen, ul_proto) must be allocated. 4270 * see, RFC2407 4.6.2.1 4271 */ 4272 int 4273 ipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto) 4274 vchar_t *buf; 4275 struct sockaddr *saddr; 4276 u_int8_t *prefixlen; 4277 u_int16_t *ul_proto; 4278 { 4279 struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)buf->v; 4280 u_int plen = 0; 4281 4282 /* 4283 * When a ID payload of subnet type with a IP address of full bit 4284 * masked, it has to be processed as host address. 4285 * e.g. below 2 type are same. 4286 * type = ipv6 subnet, data = 2001::1/128 4287 * type = ipv6 address, data = 2001::1 4288 */ 4289 switch (id_b->type) { 4290 case IPSECDOI_ID_IPV4_ADDR: 4291 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4292 #ifndef __linux__ 4293 saddr->sa_len = sizeof(struct sockaddr_in); 4294 #endif 4295 saddr->sa_family = AF_INET; 4296 ((struct sockaddr_in *)saddr)->sin_port = 4297 (id_b->port == 0 4298 ? IPSEC_PORT_ANY 4299 : id_b->port); /* see sockaddr2id() */ 4300 memcpy(&((struct sockaddr_in *)saddr)->sin_addr, 4301 buf->v + sizeof(*id_b), sizeof(struct in_addr)); 4302 break; 4303 #ifdef INET6 4304 case IPSECDOI_ID_IPV6_ADDR: 4305 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4306 #ifndef __linux__ 4307 saddr->sa_len = sizeof(struct sockaddr_in6); 4308 #endif 4309 saddr->sa_family = AF_INET6; 4310 ((struct sockaddr_in6 *)saddr)->sin6_port = 4311 (id_b->port == 0 4312 ? IPSEC_PORT_ANY 4313 : id_b->port); /* see sockaddr2id() */ 4314 memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr, 4315 buf->v + sizeof(*id_b), sizeof(struct in6_addr)); 4316 ((struct sockaddr_in6 *)saddr)->sin6_scope_id = 4317 (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)saddr)->sin6_addr) 4318 ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id 4319 : 0); 4320 4321 break; 4322 #endif 4323 default: 4324 plog(LLV_ERROR, LOCATION, NULL, 4325 "unsupported ID type %d\n", id_b->type); 4326 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 4327 } 4328 4329 /* get prefix length */ 4330 switch (id_b->type) { 4331 case IPSECDOI_ID_IPV4_ADDR: 4332 plen = sizeof(struct in_addr) << 3; 4333 break; 4334 #ifdef INET6 4335 case IPSECDOI_ID_IPV6_ADDR: 4336 plen = sizeof(struct in6_addr) << 3; 4337 break; 4338 #endif 4339 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4340 #ifdef INET6 4341 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4342 #endif 4343 { 4344 u_char *p; 4345 u_int max; 4346 int alen = sizeof(struct in_addr); 4347 4348 switch (id_b->type) { 4349 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4350 alen = sizeof(struct in_addr); 4351 break; 4352 #ifdef INET6 4353 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4354 alen = sizeof(struct in6_addr); 4355 break; 4356 #endif 4357 } 4358 4359 /* sanity check */ 4360 if (buf->l < alen) 4361 return ISAKMP_INTERNAL_ERROR; 4362 4363 /* get subnet mask length */ 4364 plen = 0; 4365 max = alen <<3; 4366 4367 p = (unsigned char *) buf->v 4368 + sizeof(struct ipsecdoi_id_b) 4369 + alen; 4370 4371 for (; *p == 0xff; p++) { 4372 plen += 8; 4373 if (plen >= max) 4374 break; 4375 } 4376 4377 if (plen < max) { 4378 u_int l = 0; 4379 u_char b = ~(*p); 4380 4381 while (b) { 4382 b >>= 1; 4383 l++; 4384 } 4385 4386 l = 8 - l; 4387 plen += l; 4388 } 4389 } 4390 break; 4391 } 4392 4393 *prefixlen = plen; 4394 *ul_proto = id_b->proto_id == 0 4395 ? IPSEC_ULPROTO_ANY 4396 : id_b->proto_id; /* see sockaddr2id() */ 4397 4398 return 0; 4399 } 4400 4401 /* 4402 * make printable string from ID payload except of general header. 4403 */ 4404 char * 4405 ipsecdoi_id2str(id) 4406 const vchar_t *id; 4407 { 4408 #define BUFLEN 512 4409 char * ret = NULL; 4410 int len = 0; 4411 char *dat; 4412 static char buf[BUFLEN]; 4413 struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v; 4414 struct sockaddr saddr; 4415 u_int plen = 0; 4416 4417 switch (id_b->type) { 4418 case IPSECDOI_ID_IPV4_ADDR: 4419 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4420 case IPSECDOI_ID_IPV4_ADDR_RANGE: 4421 4422 #ifndef __linux__ 4423 saddr.sa_len = sizeof(struct sockaddr_in); 4424 #endif 4425 saddr.sa_family = AF_INET; 4426 ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY; 4427 memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, 4428 id->v + sizeof(*id_b), sizeof(struct in_addr)); 4429 break; 4430 #ifdef INET6 4431 case IPSECDOI_ID_IPV6_ADDR: 4432 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4433 case IPSECDOI_ID_IPV6_ADDR_RANGE: 4434 4435 #ifndef __linux__ 4436 saddr.sa_len = sizeof(struct sockaddr_in6); 4437 #endif 4438 saddr.sa_family = AF_INET6; 4439 ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY; 4440 memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr, 4441 id->v + sizeof(*id_b), sizeof(struct in6_addr)); 4442 break; 4443 #endif 4444 } 4445 4446 switch (id_b->type) { 4447 case IPSECDOI_ID_IPV4_ADDR: 4448 #ifdef INET6 4449 case IPSECDOI_ID_IPV6_ADDR: 4450 #endif 4451 len = snprintf( buf, BUFLEN, "%s", saddrwop2str(&saddr)); 4452 break; 4453 4454 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4455 #ifdef INET6 4456 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4457 #endif 4458 { 4459 u_char *p; 4460 u_int max; 4461 int alen = sizeof(struct in_addr); 4462 4463 switch (id_b->type) { 4464 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4465 alen = sizeof(struct in_addr); 4466 break; 4467 #ifdef INET6 4468 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4469 alen = sizeof(struct in6_addr); 4470 break; 4471 #endif 4472 } 4473 4474 /* sanity check */ 4475 if (id->l < alen) { 4476 len = 0; 4477 break; 4478 } 4479 4480 /* get subnet mask length */ 4481 plen = 0; 4482 max = alen <<3; 4483 4484 p = (unsigned char *) id->v 4485 + sizeof(struct ipsecdoi_id_b) 4486 + alen; 4487 4488 for (; *p == 0xff; p++) { 4489 plen += 8; 4490 if (plen >= max) 4491 break; 4492 } 4493 4494 if (plen < max) { 4495 u_int l = 0; 4496 u_char b = ~(*p); 4497 4498 while (b) { 4499 b >>= 1; 4500 l++; 4501 } 4502 4503 l = 8 - l; 4504 plen += l; 4505 } 4506 4507 len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(&saddr), plen); 4508 } 4509 break; 4510 4511 case IPSECDOI_ID_IPV4_ADDR_RANGE: 4512 4513 len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr)); 4514 4515 #ifndef __linux__ 4516 saddr.sa_len = sizeof(struct sockaddr_in); 4517 #endif 4518 saddr.sa_family = AF_INET; 4519 ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY; 4520 memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, 4521 id->v + sizeof(*id_b) + sizeof(struct in_addr), 4522 sizeof(struct in_addr)); 4523 4524 len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr)); 4525 4526 break; 4527 4528 #ifdef INET6 4529 case IPSECDOI_ID_IPV6_ADDR_RANGE: 4530 4531 len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr)); 4532 4533 #ifndef __linux__ 4534 saddr.sa_len = sizeof(struct sockaddr_in6); 4535 #endif 4536 saddr.sa_family = AF_INET6; 4537 ((struct sockaddr_in6 *)&saddr)->sin6_port = IPSEC_PORT_ANY; 4538 memcpy(&((struct sockaddr_in6 *)&saddr)->sin6_addr, 4539 id->v + sizeof(*id_b) + sizeof(struct in6_addr), 4540 sizeof(struct in6_addr)); 4541 4542 len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr)); 4543 4544 break; 4545 #endif 4546 4547 case IPSECDOI_ID_FQDN: 4548 case IPSECDOI_ID_USER_FQDN: 4549 len = id->l - sizeof(*id_b); 4550 if (len > BUFLEN) 4551 len = BUFLEN; 4552 memcpy(buf, id->v + sizeof(*id_b), len); 4553 break; 4554 4555 case IPSECDOI_ID_DER_ASN1_DN: 4556 case IPSECDOI_ID_DER_ASN1_GN: 4557 { 4558 X509_NAME *xn = NULL; 4559 4560 dat = id->v + sizeof(*id_b); 4561 len = id->l - sizeof(*id_b); 4562 4563 if (d2i_X509_NAME(&xn, (void*) &dat, len) != NULL) { 4564 BIO *bio = BIO_new(BIO_s_mem()); 4565 X509_NAME_print_ex(bio, xn, 0, 0); 4566 len = BIO_get_mem_data(bio, &dat); 4567 if (len > BUFLEN) 4568 len = BUFLEN; 4569 memcpy(buf,dat,len); 4570 BIO_free(bio); 4571 X509_NAME_free(xn); 4572 } else { 4573 plog(LLV_ERROR, LOCATION, NULL, 4574 "unable to extract asn1dn from id\n"); 4575 4576 len = sprintf(buf, "<ASN1-DN>"); 4577 } 4578 4579 break; 4580 } 4581 4582 /* currently unhandled id types */ 4583 case IPSECDOI_ID_KEY_ID: 4584 len = sprintf( buf, "<KEY-ID>"); 4585 break; 4586 4587 default: 4588 plog(LLV_ERROR, LOCATION, NULL, 4589 "unknown ID type %d\n", id_b->type); 4590 } 4591 4592 if (!len) 4593 len = sprintf( buf, "<?>"); 4594 4595 ret = racoon_malloc(len+1); 4596 if (ret != NULL) { 4597 memcpy(ret,buf,len); 4598 ret[len]=0; 4599 } 4600 4601 return ret; 4602 } 4603 4604 /* 4605 * set IPsec data attributes into a proposal. 4606 * NOTE: MUST called per a transform. 4607 */ 4608 int 4609 ipsecdoi_t2satrns(t, pp, pr, tr) 4610 struct isakmp_pl_t *t; 4611 struct saprop *pp; 4612 struct saproto *pr; 4613 struct satrns *tr; 4614 { 4615 struct isakmp_data *d, *prev; 4616 int flag, type; 4617 int error = -1; 4618 int life_t; 4619 int tlen; 4620 4621 tr->trns_no = t->t_no; 4622 tr->trns_id = t->t_id; 4623 4624 tlen = ntohs(t->h.len) - sizeof(*t); 4625 prev = (struct isakmp_data *)NULL; 4626 d = (struct isakmp_data *)(t + 1); 4627 4628 /* default */ 4629 life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT; 4630 pp->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; 4631 pp->lifebyte = 0; 4632 tr->authtype = IPSECDOI_ATTR_AUTH_NONE; 4633 4634 while (tlen > 0) { 4635 4636 type = ntohs(d->type) & ~ISAKMP_GEN_MASK; 4637 flag = ntohs(d->type) & ISAKMP_GEN_MASK; 4638 4639 plog(LLV_DEBUG, LOCATION, NULL, 4640 "type=%s, flag=0x%04x, lorv=%s\n", 4641 s_ipsecdoi_attr(type), flag, 4642 s_ipsecdoi_attr_v(type, ntohs(d->lorv))); 4643 4644 switch (type) { 4645 case IPSECDOI_ATTR_SA_LD_TYPE: 4646 { 4647 int type = ntohs(d->lorv); 4648 switch (type) { 4649 case IPSECDOI_ATTR_SA_LD_TYPE_SEC: 4650 case IPSECDOI_ATTR_SA_LD_TYPE_KB: 4651 life_t = type; 4652 break; 4653 default: 4654 plog(LLV_WARNING, LOCATION, NULL, 4655 "invalid life duration type. " 4656 "use default\n"); 4657 life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT; 4658 break; 4659 } 4660 break; 4661 } 4662 case IPSECDOI_ATTR_SA_LD: 4663 if (prev == NULL 4664 || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) != 4665 IPSECDOI_ATTR_SA_LD_TYPE) { 4666 plog(LLV_ERROR, LOCATION, NULL, 4667 "life duration must follow ltype\n"); 4668 break; 4669 } 4670 4671 { 4672 u_int32_t t; 4673 vchar_t *ld_buf = NULL; 4674 4675 if (flag) { 4676 /* i.e. ISAKMP_GEN_TV */ 4677 ld_buf = vmalloc(sizeof(d->lorv)); 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->lorv, sizeof(d->lorv)); 4684 } else { 4685 int len = ntohs(d->lorv); 4686 /* i.e. ISAKMP_GEN_TLV */ 4687 ld_buf = vmalloc(len); 4688 if (ld_buf == NULL) { 4689 plog(LLV_ERROR, LOCATION, NULL, 4690 "failed to get LD buffer.\n"); 4691 goto end; 4692 } 4693 memcpy(ld_buf->v, d + 1, len); 4694 } 4695 switch (life_t) { 4696 case IPSECDOI_ATTR_SA_LD_TYPE_SEC: 4697 t = ipsecdoi_set_ld(ld_buf); 4698 vfree(ld_buf); 4699 if (t == 0) { 4700 plog(LLV_ERROR, LOCATION, NULL, 4701 "invalid life duration.\n"); 4702 goto end; 4703 } 4704 /* lifetime must be equal in a proposal. */ 4705 if (pp->lifetime == IPSECDOI_ATTR_SA_LD_SEC_DEFAULT) 4706 pp->lifetime = t; 4707 else if (pp->lifetime != t) { 4708 plog(LLV_ERROR, LOCATION, NULL, 4709 "lifetime mismatched " 4710 "in a proposal, " 4711 "prev:%ld curr:%u.\n", 4712 (long)pp->lifetime, t); 4713 goto end; 4714 } 4715 break; 4716 case IPSECDOI_ATTR_SA_LD_TYPE_KB: 4717 t = ipsecdoi_set_ld(ld_buf); 4718 vfree(ld_buf); 4719 if (t == 0) { 4720 plog(LLV_ERROR, LOCATION, NULL, 4721 "invalid life duration.\n"); 4722 goto end; 4723 } 4724 /* lifebyte must be equal in a proposal. */ 4725 if (pp->lifebyte == 0) 4726 pp->lifebyte = t; 4727 else if (pp->lifebyte != t) { 4728 plog(LLV_ERROR, LOCATION, NULL, 4729 "lifebyte mismatched " 4730 "in a proposal, " 4731 "prev:%d curr:%u.\n", 4732 pp->lifebyte, t); 4733 goto end; 4734 } 4735 break; 4736 default: 4737 vfree(ld_buf); 4738 plog(LLV_ERROR, LOCATION, NULL, 4739 "invalid life type: %d\n", life_t); 4740 goto end; 4741 } 4742 } 4743 break; 4744 4745 case IPSECDOI_ATTR_GRP_DESC: 4746 /* 4747 * RFC2407: 4.5 IPSEC Security Association Attributes 4748 * Specifies the Oakley Group to be used in a PFS QM 4749 * negotiation. For a list of supported values, see 4750 * Appendix A of [IKE]. 4751 */ 4752 if (pp->pfs_group == 0) 4753 pp->pfs_group = (u_int16_t)ntohs(d->lorv); 4754 else if (pp->pfs_group != (u_int16_t)ntohs(d->lorv)) { 4755 plog(LLV_ERROR, LOCATION, NULL, 4756 "pfs_group mismatched " 4757 "in a proposal.\n"); 4758 goto end; 4759 } 4760 break; 4761 4762 case IPSECDOI_ATTR_ENC_MODE: 4763 if (pr->encmode && 4764 pr->encmode != (u_int16_t)ntohs(d->lorv)) { 4765 plog(LLV_ERROR, LOCATION, NULL, 4766 "multiple encmode exist " 4767 "in a transform.\n"); 4768 goto end; 4769 } 4770 pr->encmode = (u_int16_t)ntohs(d->lorv); 4771 break; 4772 4773 case IPSECDOI_ATTR_AUTH: 4774 if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE) { 4775 plog(LLV_ERROR, LOCATION, NULL, 4776 "multiple authtype exist " 4777 "in a transform.\n"); 4778 goto end; 4779 } 4780 tr->authtype = (u_int16_t)ntohs(d->lorv); 4781 break; 4782 4783 case IPSECDOI_ATTR_KEY_LENGTH: 4784 if (pr->proto_id != IPSECDOI_PROTO_IPSEC_ESP) { 4785 plog(LLV_ERROR, LOCATION, NULL, 4786 "key length defined but not ESP"); 4787 goto end; 4788 } 4789 tr->encklen = ntohs(d->lorv); 4790 break; 4791 #ifdef HAVE_SECCTX 4792 case IPSECDOI_ATTR_SECCTX: 4793 { 4794 int len = ntohs(d->lorv); 4795 memcpy(&pp->sctx, d + 1, len); 4796 pp->sctx.ctx_strlen = ntohs(pp->sctx.ctx_strlen); 4797 break; 4798 } 4799 #endif /* HAVE_SECCTX */ 4800 case IPSECDOI_ATTR_KEY_ROUNDS: 4801 case IPSECDOI_ATTR_COMP_DICT_SIZE: 4802 case IPSECDOI_ATTR_COMP_PRIVALG: 4803 default: 4804 break; 4805 } 4806 4807 prev = d; 4808 if (flag) { 4809 tlen -= sizeof(*d); 4810 d = (struct isakmp_data *)((char *)d + sizeof(*d)); 4811 } else { 4812 tlen -= (sizeof(*d) + ntohs(d->lorv)); 4813 d = (struct isakmp_data *)((caddr_t)d + sizeof(*d) + ntohs(d->lorv)); 4814 } 4815 } 4816 4817 error = 0; 4818 end: 4819 return error; 4820 } 4821 4822 int 4823 ipsecdoi_authalg2trnsid(alg) 4824 int alg; 4825 { 4826 switch (alg) { 4827 case IPSECDOI_ATTR_AUTH_HMAC_MD5: 4828 return IPSECDOI_AH_MD5; 4829 case IPSECDOI_ATTR_AUTH_HMAC_SHA1: 4830 return IPSECDOI_AH_SHA; 4831 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256: 4832 return IPSECDOI_AH_SHA256; 4833 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384: 4834 return IPSECDOI_AH_SHA384; 4835 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512: 4836 return IPSECDOI_AH_SHA512; 4837 case IPSECDOI_ATTR_AUTH_DES_MAC: 4838 return IPSECDOI_AH_DES; 4839 case IPSECDOI_ATTR_AUTH_KPDK: 4840 return IPSECDOI_AH_MD5; /* XXX */ 4841 default: 4842 plog(LLV_ERROR, LOCATION, NULL, 4843 "invalid authentication algorithm:%d\n", alg); 4844 } 4845 return -1; 4846 } 4847 4848 #ifdef HAVE_GSSAPI 4849 struct isakmpsa * 4850 fixup_initiator_sa(match, received) 4851 struct isakmpsa *match, *received; 4852 { 4853 if (received->gssid != NULL) 4854 match->gssid = vdup(received->gssid); 4855 4856 return match; 4857 } 4858 #endif 4859 4860 static int rm_idtype2doi[] = { 4861 255, /* IDTYPE_UNDEFINED, 0 */ 4862 IPSECDOI_ID_FQDN, /* IDTYPE_FQDN, 1 */ 4863 IPSECDOI_ID_USER_FQDN, /* IDTYPE_USERFQDN, 2 */ 4864 IPSECDOI_ID_KEY_ID, /* IDTYPE_KEYID, 3 */ 4865 255, /* IDTYPE_ADDRESS, 4 4866 * it expands into 4 types by another function. */ 4867 IPSECDOI_ID_DER_ASN1_DN, /* IDTYPE_ASN1DN, 5 */ 4868 }; 4869 4870 /* 4871 * convert idtype to DOI value. 4872 * OUT 255 : NG 4873 * other: converted. 4874 */ 4875 int 4876 idtype2doi(idtype) 4877 int idtype; 4878 { 4879 if (ARRAYLEN(rm_idtype2doi) > idtype) 4880 return rm_idtype2doi[idtype]; 4881 return 255; 4882 } 4883 4884 int 4885 doi2idtype(doi) 4886 int doi; 4887 { 4888 switch(doi) { 4889 case IPSECDOI_ID_FQDN: 4890 return(IDTYPE_FQDN); 4891 case IPSECDOI_ID_USER_FQDN: 4892 return(IDTYPE_USERFQDN); 4893 case IPSECDOI_ID_KEY_ID: 4894 return(IDTYPE_KEYID); 4895 case IPSECDOI_ID_DER_ASN1_DN: 4896 return(IDTYPE_ASN1DN); 4897 case IPSECDOI_ID_IPV4_ADDR: 4898 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 4899 case IPSECDOI_ID_IPV6_ADDR: 4900 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 4901 return(IDTYPE_ADDRESS); 4902 default: 4903 plog(LLV_WARNING, LOCATION, NULL, 4904 "Inproper idtype:%s in this function.\n", 4905 s_ipsecdoi_ident(doi)); 4906 return(IDTYPE_ADDRESS); /* XXX */ 4907 } 4908 /*NOTREACHED*/ 4909 } 4910 4911 #ifdef ENABLE_HYBRID 4912 static int 4913 switch_authmethod(authmethod) 4914 int authmethod; 4915 { 4916 switch(authmethod) { 4917 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 4918 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I; 4919 break; 4920 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 4921 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I; 4922 break; 4923 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 4924 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; 4925 break; 4926 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 4927 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; 4928 break; 4929 /* Those are not implemented */ 4930 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 4931 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I; 4932 break; 4933 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 4934 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I; 4935 break; 4936 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 4937 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I; 4938 break; 4939 default: 4940 break; 4941 } 4942 4943 return authmethod; 4944 } 4945 #endif 4946