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