1 /*      $KAME: isakmp_quick.c,v 1.95 2003/10/21 07:18:03 itojun Exp $   */
   2 
   3 /*
   4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
   5  * All rights reserved.
   6  * 
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions and the following disclaimer.
  12  * 2. Redistributions in binary form must reproduce the above copyright
  13  *    notice, this list of conditions and the following disclaimer in the
  14  *    documentation and/or other materials provided with the distribution.
  15  * 3. Neither the name of the project nor the names of its contributors
  16  *    may be used to endorse or promote products derived from this software
  17  *    without specific prior written permission.
  18  * 
  19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29  * SUCH DAMAGE.
  30  */
  31 
  32 #ifdef HAVE_CONFIG_H
  33 #  include <config.h>
  34 #endif
  35 
  36 #include <sys/types.h>
  37 #include <sys/param.h>
  38 #include <sys/socket.h>
  39 
  40 #if 0
  41 #include <netkey/key_var.h>
  42 #endif
  43 #include <netinet/in.h>
  44 
  45 #include <stdlib.h>
  46 #include <stdio.h>
  47 #include <string.h>
  48 #include <errno.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 #ifdef HAVE_NETINET6_IPSEC_H
  61 # include <netinet6/ipsec.h>
  62 #else
  63 # ifdef HAVE_NETIPSEC_IPSEC_H
  64 #  include <netipsec/ipsec.h>
  65 # else
  66 #  include <linux/ipsec.h>
  67 # endif
  68 #endif
  69 
  70 #include "racoon.h"
  71 
  72 #include "var.h"
  73 /* #include "vmbuf.h" */
  74 /* #include "schedule.h" */
  75 /* #include "misc.h" */
  76 #include "plog.h"
  77 #include "debug.h"
  78 
  79 /* #include "localconf.h" */
  80 #include "remoteconf.h"
  81 #include "isakmp.h"
  82 #include "isakmp_var.h"
  83 #include "isakmp_impl.h"
  84 #include "ikev1_impl.h"
  85 #include "isakmp_inf.h"
  86 #include "isakmp_quick.h"
  87 #include "oakley.h"
  88 #include "handler.h"
  89 #include "ipsec_doi.h"
  90 #include "crypto_impl.h"
  91 #include "pfkey.h"
  92 /* #include "policy.h" */
  93 #include "algorithm.h"
  94 #include "sockmisc.h"
  95 #include "proposal.h"
  96 /* #include "sainfo.h" */
  97 /* #include "admin.h" */
  98 #include "strnames.h"
  99 
 100 #include "ike_conf.h"
 101 
 102 /* quick mode */
 103 static rc_vchar_t *quick_ir1mx (struct ph2handle *, rc_vchar_t *, rc_vchar_t *);
 104 static int get_sainfo_r (struct ph2handle *);
 105 static int get_proposal_r (struct ph2handle *);
 106 #ifdef INET6
 107 static uint32_t setscopeid (struct sockaddr *, struct sockaddr *)
 108         GCC_ATTRIBUTE((unused));
 109 #endif
 110 
 111 /* called from scheduler */
 112 void
 113 pfkey_timeover_stub(p)
 114         void *p;
 115 {
 116         void pfkey_timeover();
 117 
 118         pfkey_timeover((struct ph2handle *)p);
 119 }
 120 
 121 void
 122 pfkey_timeover(struct ph2handle *iph2)
 123 {
 124         plog(PLOG_PROTOERR, PLOGLOC, 0,
 125                 "%s give up to get IPsec-SA due to time up to wait.\n",
 126                 rcs_sa2str_wop(iph2->dst));
 127         SCHED_KILL(iph2->sce);
 128 
 129         /* If initiator side, send error to kernel by SADB_ACQUIRE. */
 130         if (iph2->side == INITIATOR)
 131                 pk_sendeacquire(iph2);
 132 
 133         unbindph12(iph2);
 134         remph2(iph2);
 135         delph2(iph2);
 136 
 137         return;
 138 }
 139 
 140 /* %%%
 141  * Quick Mode
 142  */
 143 /*
 144  * begin Quick Mode as initiator.  send pfkey getspi message to kernel.
 145  */
 146 int
 147 quick_i1prep(struct ph2handle *iph2, rc_vchar_t *msg /* must be null pointer */)
 148 {
 149         int error = ISAKMP_INTERNAL_ERROR;
 150 
 151         /* validity check */
 152         if (iph2->status != PHASE2ST_STATUS2) {
 153                 plog(PLOG_INTERR, PLOGLOC, NULL,
 154                         "status mismatched %d.\n", iph2->status);
 155                 goto end;
 156         }
 157 
 158         iph2->msgid = isakmp_newmsgid2(iph2->ph1);
 159         iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid);
 160         if (iph2->ivm == NULL)
 161                 return 0;
 162 
 163         iph2->status = PHASE2ST_GETSPISENT;
 164 
 165 #if 0
 166         /* don't anything if local test mode. */
 167         if (f_local) {
 168                 error = 0;
 169                 goto end;
 170         }
 171 #endif
 172 
 173         /* send getspi message */
 174         if (pk_sendgetspi(iph2) < 0)
 175                 goto end;
 176 
 177         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey getspi sent.\n");
 178 
 179         iph2->sce = sched_new(ikev1_ipsec_sa_nego_time_limit(iph2->ph1->rmconf),
 180                 pfkey_timeover_stub, iph2);
 181 
 182         error = 0;
 183 
 184 end:
 185         return error;
 186 }
 187 
 188 /*
 189  * send to responder
 190  *      HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
 191  */
 192 int
 193 quick_i1send(struct ph2handle *iph2, rc_vchar_t *msg /* must be null pointer */)
 194 {
 195         rc_vchar_t *body = NULL;
 196         rc_vchar_t *hash = NULL;
 197         struct isakmp_gen *gen;
 198         char *p;
 199         int tlen;
 200         int error = ISAKMP_INTERNAL_ERROR;
 201         int pfsgroup, idci, idcr;
 202         int np;
 203         struct ipsecdoi_id_b *id, *id_p;
 204 
 205         /* validity check */
 206         if (msg != NULL) {
 207                 plog(PLOG_INTERR, PLOGLOC, NULL,
 208                         "msg has to be NULL in this function.\n");
 209                 goto end;
 210         }
 211         if (iph2->status != PHASE2ST_GETSPIDONE) {
 212                 plog(PLOG_INTERR, PLOGLOC, NULL,
 213                         "status mismatched %d.\n", iph2->status);
 214                 goto end;
 215         }
 216 
 217         /* create SA payload for my proposal */
 218         if (ipsecdoi_setph2proposal(iph2) < 0)
 219                 goto end;
 220 
 221         /* generate NONCE value */
 222         iph2->nonce = eay_set_random(ikev1_nonce_size(iph2->ph1->rmconf));
 223         if (iph2->nonce == NULL)
 224                 goto end;
 225 
 226         /*
 227          * DH value calculation is kicked out into cfparse.y.
 228          * because pfs group can not be negotiated, it's only to be checked
 229          * acceptable.
 230          */
 231         /* generate KE value if need */
 232         pfsgroup = iph2->proposal->pfs_group;
 233         if (pfsgroup) {
 234                 /* DH group settting if PFS is required. */
 235                 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
 236                         plog(PLOG_INTERR, PLOGLOC, NULL,
 237                                 "failed to set DH value.\n");
 238                         goto end;
 239                 }
 240                 if (oakley_dh_generate(iph2->pfsgrp,
 241                                 &iph2->dhpub, &iph2->dhpriv) < 0) {
 242                         goto end;
 243                 }
 244         }
 245 
 246         /* generate ID value */
 247         if (ipsecdoi_setid2(iph2) < 0) {
 248                 plog(PLOG_INTERR, PLOGLOC, NULL,
 249                         "failed to get ID.\n");
 250                 goto end;
 251         }
 252         plog(PLOG_DEBUG, PLOGLOC, NULL, "IDci:\n");
 253         plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id->v, iph2->id->l);
 254         plog(PLOG_DEBUG, PLOGLOC, NULL, "IDcr:");
 255         plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id_p->v, iph2->id_p->l);
 256 
 257         /*
 258          * we do not attach IDci nor IDcr, under the following condition:
 259          * - all proposals are transport mode
 260          * - no MIP6 or proxy
 261          * - id payload suggests to encrypt all the traffic (no specific
 262          *   protocol type)
 263          */
 264         id = (struct ipsecdoi_id_b *)iph2->id->v;
 265         id_p = (struct ipsecdoi_id_b *)iph2->id_p->v;
 266         if (id->proto_id == 0
 267          && id_p->proto_id == 0
 268          && id->port == 0
 269          && id_p->port == 0
 270          && iph2->selector->pl != 0
 271          && (iph2->selector->pl->my_sa_ipaddr != 0
 272            || iph2->selector->pl->peers_sa_ipaddr != 0)
 273          && ipsecdoi_transportmode(iph2->proposal)) {
 274                 idci = idcr = 0;
 275         } else
 276                 idci = idcr = 1;
 277 
 278         /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
 279         tlen = + sizeof(*gen) + iph2->sa->l
 280                 + sizeof(*gen) + iph2->nonce->l;
 281         if (pfsgroup)
 282                 tlen += (sizeof(*gen) + iph2->dhpub->l);
 283         if (idci)
 284                 tlen += sizeof(*gen) + iph2->id->l;
 285         if (idcr)
 286                 tlen += sizeof(*gen) + iph2->id_p->l;
 287 
 288         body = rc_vmalloc(tlen);
 289         if (body == NULL) {
 290                 plog(PLOG_INTERR, PLOGLOC, NULL,
 291                         "failed to get buffer to send.\n");
 292                 goto end;
 293         }
 294 
 295         p = body->v;
 296 
 297         /* add SA payload */
 298         p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE);
 299 
 300         /* add NONCE payload */
 301         if (pfsgroup)
 302                 np = ISAKMP_NPTYPE_KE;
 303         else if (idci || idcr)
 304                 np = ISAKMP_NPTYPE_ID;
 305         else
 306                 np = ISAKMP_NPTYPE_NONE;
 307         p = set_isakmp_payload(p, iph2->nonce, np);
 308 
 309         /* add KE payload if need. */
 310         np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
 311         if (pfsgroup)
 312                 p = set_isakmp_payload(p, iph2->dhpub, np);
 313 
 314         /* IDci */
 315         np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
 316         if (idci)
 317                 p = set_isakmp_payload(p, iph2->id, np);
 318 
 319         /* IDcr */
 320         if (idcr)
 321                 p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE);
 322 
 323         /* generate HASH(1) */
 324         hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
 325         if (hash == NULL)
 326                 goto end;
 327 
 328         /* send isakmp payload */
 329         iph2->sendbuf = quick_ir1mx(iph2, body, hash);
 330         if (iph2->sendbuf == NULL)
 331                 goto end;
 332 
 333         /* send the packet, add to the schedule to resend */
 334         iph2->retry_counter = ikev1_max_retry_to_send(iph2->ph1->rmconf);
 335         if (isakmp_ph2resend(iph2) == -1)
 336                 goto end;
 337 
 338         /* change status of isakmp status entry */
 339         iph2->status = PHASE2ST_MSG1SENT;
 340 
 341         error = 0;
 342 
 343 end:
 344         if (body != NULL)
 345                 rc_vfree(body);
 346         if (hash != NULL)
 347                 rc_vfree(hash);
 348 
 349         return error;
 350 }
 351 
 352 /*
 353  * receive from responder
 354  *      HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
 355  */
 356 int
 357 quick_i2recv(struct ph2handle *iph2, rc_vchar_t *msg0)
 358 {
 359         rc_vchar_t *msg = NULL;
 360         rc_vchar_t *hbuf = NULL;        /* for hash computing. */
 361         rc_vchar_t *pbuf = NULL;        /* for payload parsing */
 362         struct isakmp_parse_t *pa;
 363         struct isakmp *isakmp = (struct isakmp *)msg0->v;
 364         struct isakmp_pl_hash *hash = NULL;
 365         int f_id;
 366         char *p;
 367         int tlen;
 368         int error = ISAKMP_INTERNAL_ERROR;
 369 
 370         /* validity check */
 371         if (iph2->status != PHASE2ST_MSG1SENT) {
 372                 plog(PLOG_INTERR, PLOGLOC, NULL,
 373                         "status mismatched %d.\n", iph2->status);
 374                 goto end;
 375         }
 376 
 377         /* decrypt packet */
 378         if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
 379                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 380                            PLOG_PROTOERR, PLOGLOC,
 381                            "Packet wasn't encrypted.\n");
 382                 goto end;
 383         }
 384         msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
 385         if (msg == NULL)
 386                 goto end;
 387 
 388         /* create buffer for validating HASH(2) */
 389         /*
 390          * ordering rule:
 391          *      1. the first one must be HASH
 392          *      2. the second one must be SA (added in isakmp-oakley-05!)
 393          *      3. two IDs must be considered as IDci, then IDcr
 394          */
 395         pbuf = isakmp_parse(msg);
 396         if (pbuf == NULL)
 397                 goto end;
 398         pa = (struct isakmp_parse_t *)pbuf->v;
 399 
 400         /* HASH payload is fixed postion */
 401         if (pa->type != ISAKMP_NPTYPE_HASH) {
 402                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 403                            PLOG_PROTOERR, PLOGLOC,
 404                            "received invalid next payload type %d, "
 405                            "expecting %d.\n",
 406                            pa->type, ISAKMP_NPTYPE_HASH);
 407                 goto end;
 408         }
 409         hash = (struct isakmp_pl_hash *)pa->ptr;
 410         pa++;
 411 
 412         /*
 413          * this restriction was introduced in isakmp-oakley-05.
 414          * we do not check this for backward compatibility.
 415          * TODO: command line/config file option to enable/disable this code
 416          */
 417         /* HASH payload is fixed postion */
 418         if (pa->type != ISAKMP_NPTYPE_SA) {
 419                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 420                            PLOG_PROTOWARN, PLOGLOC,
 421                            "received invalid next payload type %d, "
 422                            "expecting %d.\n",
 423                            pa->type, ISAKMP_NPTYPE_HASH);
 424         }
 425 
 426         /* allocate buffer for computing HASH(2) */
 427         tlen = iph2->nonce->l
 428                 + get_uint32(&isakmp->len) - sizeof(*isakmp);
 429         hbuf = rc_vmalloc(tlen);
 430         if (hbuf == NULL) {
 431                 plog(PLOG_INTERR, PLOGLOC, NULL,
 432                         "failed to get hash buffer.\n");
 433                 goto end;
 434         }
 435         p = hbuf->v + iph2->nonce->l;  /* retain the space for Ni_b */
 436 
 437         /*
 438          * parse the payloads.
 439          * copy non-HASH payloads into hbuf, so that we can validate HASH.
 440          */
 441         iph2->sa_ret = NULL;
 442         f_id = 0;       /* flag to use checking ID */
 443         tlen = 0;       /* count payload length except of HASH payload. */
 444         for (; pa->type; pa++) {
 445 
 446                 /* copy to buffer for HASH */
 447                 /* Don't modify the payload */
 448                 memcpy(p, pa->ptr, pa->len);
 449 
 450                 switch (pa->type) {
 451                 case ISAKMP_NPTYPE_SA:
 452                         if (iph2->sa_ret != NULL) {
 453                                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
 454                                         "Ignored, multiple SA "
 455                                         "isn't supported.\n");
 456                                 break;
 457                         }
 458                         if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0)
 459                                 goto end;
 460                         break;
 461 
 462                 case ISAKMP_NPTYPE_NONCE:
 463                         if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
 464                                 goto end;
 465                         break;
 466 
 467                 case ISAKMP_NPTYPE_KE:
 468                         if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
 469                                 goto end;
 470                         break;
 471 
 472                 case ISAKMP_NPTYPE_ID:
 473                     {
 474                         rc_vchar_t *vp;
 475 
 476                         /* check ID value */
 477                         if (f_id == 0) {
 478                                 /* for IDci */
 479                                 f_id = 1;
 480                                 vp = iph2->id;
 481                         } else {
 482                                 /* for IDcr */
 483                                 vp = iph2->id_p;
 484                         }
 485 
 486                         if (memcmp(vp->v, (caddr_t)pa->ptr + sizeof(struct isakmp_gen), vp->l)) {
 487 
 488                                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
 489                                         "mismatched ID was returned.\n");
 490                                 error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
 491                                 goto end;
 492                         }
 493                     }
 494                         break;
 495 
 496                 case ISAKMP_NPTYPE_N:
 497                         isakmp_check_notify(pa->ptr, iph2->ph1);
 498                         break;
 499 
 500 #ifdef ENABLE_NATT
 501                 case ISAKMP_NPTYPE_NATOA_DRAFT:
 502                 case ISAKMP_NPTYPE_NATOA_RFC:
 503                         /* Ignore original source/destination messages */
 504                         break;
 505 #endif
 506 
 507                 default:
 508                         /* don't send information, see ident_r1recv() */
 509                         isakmp_log(0, 0, iph2->ph1->remote, 0,
 510                                    PLOG_PROTOERR, PLOGLOC,
 511                                    "ignore the packet, "
 512                                    "received unexpecting payload type %d.\n",
 513                                    pa->type);
 514                         goto end;
 515                 }
 516 
 517                 p += pa->len;
 518 
 519                 /* compute true length of payload. */
 520                 tlen += pa->len;
 521         }
 522 
 523         /* payload existency check */
 524         if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) {
 525                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 526                            PLOG_PROTOERR, PLOGLOC,
 527                            "few isakmp message received.\n");
 528                 goto end;
 529         }
 530 
 531         /* Fixed buffer for calculating HASH */
 532         memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l);
 533         plog(PLOG_DEBUG, PLOGLOC, NULL,
 534                 "HASH allocated:hbuf->l=%d actual:tlen=%d\n",
 535                 hbuf->l, tlen + iph2->nonce->l);
 536         /* adjust buffer length for HASH */
 537         hbuf->l = iph2->nonce->l + tlen;
 538 
 539         /* validate HASH(2) */
 540     {
 541         char *r_hash;
 542         rc_vchar_t *my_hash = NULL;
 543         int result;
 544 
 545         r_hash = (char *)hash + sizeof(*hash);
 546 
 547         plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(2) received:");
 548         plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
 549 
 550         my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
 551         if (my_hash == NULL)
 552                 goto end;
 553 
 554         result = memcmp(my_hash->v, r_hash, my_hash->l);
 555         rc_vfree(my_hash);
 556 
 557         if (result) {
 558                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 559                            PLOG_PROTOERR, PLOGLOC,
 560                            "HASH(2) mismatch.\n");
 561                 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
 562                 goto end;
 563         }
 564     }
 565 
 566         /* validity check SA payload sent from responder */
 567         if (ipsecdoi_checkph2proposal(iph2) < 0) {
 568                 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
 569                 goto end;
 570         }
 571 
 572         /* change status of isakmp status entry */
 573         iph2->status = PHASE2ST_STATUS6;
 574 
 575         error = 0;
 576 
 577 end:
 578         if (hbuf)
 579                 rc_vfree(hbuf);
 580         if (pbuf)
 581                 rc_vfree(pbuf);
 582         if (msg)
 583                 rc_vfree(msg);
 584 
 585         if (error) {
 586                 VPTRINIT(iph2->sa_ret);
 587                 VPTRINIT(iph2->nonce_p);
 588                 VPTRINIT(iph2->dhpub_p);
 589                 VPTRINIT(iph2->id);
 590                 VPTRINIT(iph2->id_p);
 591         }
 592 
 593         return error;
 594 }
 595 
 596 /*
 597  * send to responder
 598  *      HDR*, HASH(3)
 599  */
 600 int
 601 quick_i2send(struct ph2handle *iph2, rc_vchar_t *msg0)
 602 {
 603         rc_vchar_t *msg = NULL;
 604         rc_vchar_t *buf = NULL;
 605         rc_vchar_t *hash = NULL;
 606         char *p = NULL;
 607         int tlen;
 608         int error = ISAKMP_INTERNAL_ERROR;
 609 
 610         /* validity check */
 611         if (iph2->status != PHASE2ST_STATUS6) {
 612                 plog(PLOG_INTERR, PLOGLOC, NULL,
 613                         "status mismatched %d.\n", iph2->status);
 614                 goto end;
 615         }
 616 
 617         /* generate HASH(3) */
 618     {
 619         rc_vchar_t *tmp = NULL;
 620 
 621         plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(3) generate\n");
 622 
 623         tmp = rc_vmalloc(iph2->nonce->l + iph2->nonce_p->l);
 624         if (tmp == NULL) { 
 625                 plog(PLOG_INTERR, PLOGLOC, NULL,
 626                         "failed to get hash buffer.\n");
 627                 goto end;
 628         }
 629         memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l);
 630         memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l);
 631 
 632         hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
 633         rc_vfree(tmp);
 634 
 635         if (hash == NULL)
 636                 goto end;
 637     }
 638 
 639         /* create buffer for isakmp payload */
 640         tlen = sizeof(struct isakmp)
 641                 + sizeof(struct isakmp_gen) + hash->l;
 642         buf = rc_vmalloc(tlen);
 643         if (buf == NULL) { 
 644                 plog(PLOG_INTERR, PLOGLOC, NULL,
 645                         "failed to get buffer to send.\n");
 646                 goto end;
 647         }
 648 
 649         /* create isakmp header */
 650         p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
 651         if (p == NULL)
 652                 goto end;
 653 
 654         /* add HASH(3) payload */
 655         p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE);
 656 
 657 #ifdef HAVE_PRINT_ISAKMP_C
 658         isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
 659 #endif
 660 
 661         /* encoding */
 662         iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
 663         if (iph2->sendbuf == NULL)
 664                 goto end;
 665 
 666         /* if there is commit bit, need resending */
 667         if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
 668                 /* send the packet, add to the schedule to resend */
 669                 iph2->retry_counter = ikev1_max_retry_to_send(iph2->ph1->rmconf);
 670                 if (isakmp_ph2resend(iph2) == -1)
 671                         goto end;
 672         } else {
 673                 /* send the packet */
 674                 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
 675                         goto end;
 676         }
 677 
 678         /* the sending message is added to the received-list. */
 679         if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
 680                         iph2->sendbuf, msg0, iph2->ph1->rmconf) == -1) {
 681                 plog(PLOG_INTERR , PLOGLOC, NULL,
 682                         "failed to add a response packet to the tree.\n");
 683                 goto end;
 684         }
 685 
 686         /* compute both of KEYMATs */
 687         if (oakley_compute_keymat(iph2, INITIATOR) < 0)
 688                 goto end;
 689 
 690         iph2->status = PHASE2ST_ADDSA;
 691 
 692 #if 0
 693         /* don't anything if local test mode. */
 694         if (f_local) {
 695                 error = 0;
 696                 goto end;
 697         }
 698 #endif
 699         
 700         /* if there is commit bit don't set up SA now. */
 701         if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
 702                 iph2->status = PHASE2ST_COMMIT;
 703                 error = 0;
 704                 goto end;
 705         }
 706 
 707         /* Do UPDATE for initiator */
 708         plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n");
 709         if (pk_sendupdate(iph2) < 0) {
 710                 plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n");
 711                 goto end;
 712         }
 713         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n");
 714 
 715         /* Do ADD for responder */
 716         if (pk_sendadd(iph2) < 0) {
 717                 plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n");
 718                 goto end;
 719         }
 720         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n");
 721 
 722         error = 0;
 723 
 724 end:
 725         if (buf != NULL)
 726                 rc_vfree(buf);
 727         if (msg != NULL)
 728                 rc_vfree(msg);
 729         if (hash != NULL)
 730                 rc_vfree(hash);
 731 
 732         return error;
 733 }
 734 
 735 /*
 736  * receive from responder
 737  *      HDR#*, HASH(4), notify
 738  */
 739 int
 740 quick_i3recv(struct ph2handle *iph2, rc_vchar_t *msg0)
 741 {
 742         rc_vchar_t *msg = NULL;
 743         rc_vchar_t *pbuf = NULL;        /* for payload parsing */
 744         struct isakmp_parse_t *pa;
 745         struct isakmp_pl_hash *hash = NULL;
 746         rc_vchar_t *notify = NULL;
 747         int error = ISAKMP_INTERNAL_ERROR;
 748 
 749         /* validity check */
 750         if (iph2->status != PHASE2ST_COMMIT) {
 751                 plog(PLOG_INTERR, PLOGLOC, NULL,
 752                         "status mismatched %d.\n", iph2->status);
 753                 goto end;
 754         }
 755 
 756         /* decrypt packet */
 757         if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
 758                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 759                            PLOG_PROTOERR, PLOGLOC,
 760                            "Packet wasn't encrypted.\n");
 761                 goto end;
 762         }
 763         msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
 764         if (msg == NULL)
 765                 goto end;
 766 
 767         /* validate the type of next payload */
 768         pbuf = isakmp_parse(msg);
 769         if (pbuf == NULL)
 770                 goto end;
 771 
 772         for (pa = (struct isakmp_parse_t *)pbuf->v;
 773              pa->type != ISAKMP_NPTYPE_NONE;
 774              pa++) {
 775 
 776                 switch (pa->type) {
 777                 case ISAKMP_NPTYPE_HASH:
 778                         hash = (struct isakmp_pl_hash *)pa->ptr;
 779                         break;
 780                 case ISAKMP_NPTYPE_N:
 781                         if (notify != NULL) {
 782                                 plog(PLOG_INTWARN, PLOGLOC, NULL,
 783                                      "Ignoring multiple notifications\n");
 784                                 break;
 785                         }
 786                         isakmp_check_notify(pa->ptr, iph2->ph1);
 787                         notify = rc_vmalloc(pa->len);
 788                         if (notify == NULL) {
 789                                 plog(PLOG_INTERR, PLOGLOC, NULL,
 790                                         "failed to get notify buffer.\n");
 791                                 goto end;
 792                         }
 793                         memcpy(notify->v, pa->ptr, notify->l);
 794                         break;
 795                 default:
 796                         /* don't send information, see ident_r1recv() */
 797                         isakmp_log(0, 0, iph2->ph1->remote, 0,
 798                                    PLOG_PROTOERR, PLOGLOC,
 799                                    "ignore the packet, "
 800                                    "received unexpecting payload type %d.\n",
 801                                    pa->type);
 802                         goto end;
 803                 }
 804         }
 805 
 806         /* payload existency check */
 807         if (hash == NULL) {
 808                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 809                            PLOG_PROTOERR, PLOGLOC,
 810                            "few isakmp message received.\n");
 811                 goto end;
 812         }
 813 
 814         /* validate HASH(4) */
 815     {
 816         char *r_hash;
 817         rc_vchar_t *my_hash = NULL;
 818         rc_vchar_t *tmp = NULL;
 819         int result;
 820 
 821         r_hash = (char *)hash + sizeof(*hash);
 822 
 823         plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(4) validate:");
 824         plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
 825 
 826         my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
 827         rc_vfree(tmp);
 828         if (my_hash == NULL)
 829                 goto end;
 830 
 831         result = memcmp(my_hash->v, r_hash, my_hash->l);
 832         rc_vfree(my_hash);
 833 
 834         if (result) {
 835                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 836                            PLOG_PROTOERR, PLOGLOC,
 837                            "HASH(4) mismatch.\n");
 838                 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
 839                 goto end;
 840         }
 841     }
 842 
 843         iph2->status = PHASE2ST_ADDSA;
 844         iph2->flags ^= ISAKMP_FLAG_C;        /* reset bit */
 845 
 846 #if 0
 847         /* don't anything if local test mode. */
 848         if (f_local) {
 849                 error = 0;
 850                 goto end;
 851         }
 852 #endif
 853 
 854         /* Do UPDATE for initiator */
 855         plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n");
 856         if (pk_sendupdate(iph2) < 0) {
 857                 plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n");
 858                 goto end;
 859         }
 860         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n");
 861 
 862         /* Do ADD for responder */
 863         if (pk_sendadd(iph2) < 0) {
 864                 plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n");
 865                 goto end;
 866         }
 867         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n");
 868 
 869         error = 0;
 870 
 871 end:
 872         if (msg != NULL)
 873                 rc_vfree(msg);
 874         if (pbuf != NULL)
 875                 rc_vfree(pbuf);
 876         if (notify != NULL)
 877                 rc_vfree(notify);
 878 
 879         return error;
 880 }
 881 
 882 /*
 883  * receive from initiator
 884  *      HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
 885  */
 886 int
 887 quick_r1recv(struct ph2handle *iph2, rc_vchar_t *msg0)
 888 {
 889         rc_vchar_t *msg = NULL;
 890         rc_vchar_t *hbuf = NULL;        /* for hash computing. */
 891         rc_vchar_t *pbuf = NULL;        /* for payload parsing */
 892         struct isakmp_parse_t *pa;
 893         struct isakmp *isakmp = (struct isakmp *)msg0->v;
 894         struct isakmp_pl_hash *hash = NULL;
 895         char *p;
 896         int tlen;
 897         int f_id_order; /* for ID payload detection */
 898         int error = ISAKMP_INTERNAL_ERROR;
 899 
 900         /* validity check */
 901         if (iph2->status != PHASE2ST_START) {
 902                 plog(PLOG_INTERR, PLOGLOC, NULL,
 903                         "status mismatched %d.\n", iph2->status);
 904                 goto end;
 905         }
 906 
 907         /* decrypting */
 908         if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
 909                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 910                            PLOG_PROTOERR, PLOGLOC,
 911                            "Packet wasn't encrypted.\n");
 912                 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
 913                 goto end;
 914         }
 915         /* decrypt packet */
 916         msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
 917         if (msg == NULL)
 918                 goto end;
 919 
 920         /* create buffer for using to validate HASH(1) */
 921         /*
 922          * ordering rule:
 923          *      1. the first one must be HASH
 924          *      2. the second one must be SA (added in isakmp-oakley-05!)
 925          *      3. two IDs must be considered as IDci, then IDcr
 926          */
 927         pbuf = isakmp_parse(msg);
 928         if (pbuf == NULL)
 929                 goto end;
 930         pa = (struct isakmp_parse_t *)pbuf->v;
 931 
 932         /* HASH payload is fixed postion */
 933         if (pa->type != ISAKMP_NPTYPE_HASH) {
 934                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 935                            PLOG_PROTOERR, PLOGLOC,
 936                            "received invalid next payload type %d, "
 937                            "expecting %d.\n",
 938                            pa->type, ISAKMP_NPTYPE_HASH);
 939                 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
 940                 goto end;
 941         }
 942         hash = (struct isakmp_pl_hash *)pa->ptr;
 943         pa++;
 944 
 945         /*
 946          * this restriction was introduced in isakmp-oakley-05.
 947          * we do not check this for backward compatibility.
 948          * TODO: command line/config file option to enable/disable this code
 949          */
 950         /* HASH payload is fixed postion */
 951         if (pa->type != ISAKMP_NPTYPE_SA) {
 952                 isakmp_log(0, 0, iph2->ph1->remote, 0,
 953                            PLOG_PROTOERR, PLOGLOC,
 954                            "received invalid next payload type %d, "
 955                            "expecting %d.\n",
 956                            pa->type, ISAKMP_NPTYPE_HASH);
 957                 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
 958         }
 959 
 960         /* allocate buffer for computing HASH(1) */
 961         tlen = get_uint32(&isakmp->len) - sizeof(*isakmp);
 962         hbuf = rc_vmalloc(tlen);
 963         if (hbuf == NULL) {
 964                 plog(PLOG_INTERR, PLOGLOC, NULL,
 965                         "failed to get hash buffer.\n");
 966                 goto end;
 967         }
 968         p = hbuf->v;
 969 
 970         /*
 971          * parse the payloads.
 972          * copy non-HASH payloads into hbuf, so that we can validate HASH.
 973          */
 974         iph2->sa = NULL;     /* we don't support multi SAs. */
 975         iph2->nonce_p = NULL;
 976         iph2->dhpub_p = NULL;
 977         iph2->id_p = NULL;
 978         iph2->id = NULL;
 979         tlen = 0;       /* count payload length except of HASH payload. */
 980 
 981         /*
 982          * IDi2 MUST be immediatelly followed by IDr2.  We allowed the
 983          * illegal case, but logged.  First ID payload is to be IDi2.
 984          * And next ID payload is to be IDr2.
 985          */
 986         f_id_order = 0;
 987 
 988         for (; pa->type; pa++) {
 989 
 990                 /* copy to buffer for HASH */
 991                 /* Don't modify the payload */
 992                 memcpy(p, pa->ptr, pa->len);
 993 
 994                 if (pa->type != ISAKMP_NPTYPE_ID)
 995                         f_id_order = 0;
 996 
 997                 switch (pa->type) {
 998                 case ISAKMP_NPTYPE_SA:
 999                         if (iph2->sa != NULL) {
1000                                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1001                                         "Multi SAs isn't supported.\n");
1002                                 goto end;
1003                         }
1004                         if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0)
1005                                 goto end;
1006                         break;
1007 
1008                 case ISAKMP_NPTYPE_NONCE:
1009                         if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
1010                                 goto end;
1011                         break;
1012 
1013                 case ISAKMP_NPTYPE_KE:
1014                         if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
1015                                 goto end;
1016                         break;
1017 
1018                 case ISAKMP_NPTYPE_ID:
1019                         if (iph2->id_p == NULL) {
1020                                 /* for IDci */
1021                                 f_id_order++;
1022 
1023                                 if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0)
1024                                         goto end;
1025 
1026                         } else if (iph2->id == NULL) {
1027                                 /* for IDcr */
1028                                 if (f_id_order == 0) {
1029                                         plog(PLOG_PROTOERR, PLOGLOC, NULL,
1030                                                 "IDr2 payload is not "
1031                                                 "immediatelly followed "
1032                                                 "by IDi2. We allowed.\n");
1033                                         /* XXX we allowed in this case. */
1034                                 }
1035 
1036                                 if (isakmp_p2ph(&iph2->id, pa->ptr) < 0)
1037                                         goto end;
1038                         } else {
1039                                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1040                                         "received too many ID payloads.\n");
1041                                 plogdump(PLOG_PROTOERR, PLOGLOC, 0, iph2->id->v, iph2->id->l);
1042                                 error = ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1043                                 goto end;
1044                         }
1045                         break;
1046 
1047                 case ISAKMP_NPTYPE_N:
1048                         isakmp_check_notify(pa->ptr, iph2->ph1);
1049                         break;
1050 
1051 #ifdef ENABLE_NATT
1052                 case ISAKMP_NPTYPE_NATOA_DRAFT:
1053                 case ISAKMP_NPTYPE_NATOA_RFC:
1054                         /* Ignore original source/destination messages */
1055                         break;
1056 #endif
1057 
1058                 default:
1059                         isakmp_log(0, 0, iph2->ph1->remote, 0,
1060                                    PLOG_PROTOERR, PLOGLOC,
1061                                    "ignore the packet, "
1062                                    "received unexpecting payload type %d.\n",
1063                                    pa->type);
1064                         error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1065                         goto end;
1066                 }
1067 
1068                 p += pa->len;
1069 
1070                 /* compute true length of payload. */
1071                 tlen += pa->len;
1072         }
1073 
1074         /* payload existency check */
1075         if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) {
1076                 isakmp_log(0, 0, iph2->ph1->remote, 0,
1077                            PLOG_PROTOERR, PLOGLOC,
1078                            "few isakmp message received.\n");
1079                 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1080                 goto end;
1081         }
1082 
1083         if (iph2->id_p) {
1084                 plog(PLOG_DEBUG, PLOGLOC, NULL, "received IDci2:");
1085                 plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id_p->v, iph2->id_p->l);
1086         }
1087         if (iph2->id) {
1088                 plog(PLOG_DEBUG, PLOGLOC, NULL, "received IDcr2:");
1089                 plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id->v, iph2->id->l);
1090         }
1091 
1092         /* adjust buffer length for HASH */
1093         hbuf->l = tlen;
1094 
1095         /* validate HASH(1) */
1096     {
1097         char *r_hash;
1098         rc_vchar_t *my_hash = NULL;
1099         int result;
1100 
1101         r_hash = (caddr_t)hash + sizeof(*hash);
1102 
1103         plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(1) validate:");
1104         plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
1105 
1106         my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
1107         if (my_hash == NULL)
1108                 goto end;
1109 
1110         result = memcmp(my_hash->v, r_hash, my_hash->l);
1111         rc_vfree(my_hash);
1112 
1113         if (result) {
1114                 isakmp_log(0, 0, iph2->ph1->remote, 0,
1115                            PLOG_DEBUG, PLOGLOC,
1116                            "HASH(1) mismatch.\n");
1117                 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1118                 goto end;
1119         }
1120     }
1121 
1122         /* get sainfo */
1123         error = get_sainfo_r(iph2);
1124         if (error) {
1125                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1126                         "failed to get sainfo.\n");
1127                 goto end;
1128         }
1129 
1130         /* check the existence of ID payload and create responder's proposal */
1131         error = get_proposal_r(iph2);
1132         switch (error) {
1133 #ifdef notyet
1134         case -2:
1135                 /* generate a policy template from peer's proposal */
1136                 if (set_proposal_from_proposal(iph2)) {
1137                         plog(PLOG_INTERR, PLOGLOC, NULL,
1138                                 "failed to generate a proposal template "
1139                                 "from client's proposal.\n");
1140                         return ISAKMP_INTERNAL_ERROR;
1141                 }
1142                 /*FALLTHROUGH*/
1143 #endif
1144         case 0:
1145                 /* select single proposal or reject it. */
1146                 if (ipsecdoi_selectph2proposal(iph2) < 0) {
1147                         error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1148                         goto end;
1149                 }
1150                 break;
1151         default:
1152                 plog(PLOG_INTERR, PLOGLOC, NULL,
1153                         "failed to get proposal for responder.\n");
1154                 goto end;
1155         }
1156 
1157         /* check KE and attribute of PFS */
1158         if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) {
1159                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1160                         "no PFS is specified, but peer sends KE.\n");
1161                 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1162                 goto end;
1163         }
1164         if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) {
1165                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1166                         "PFS is specified, but peer doesn't sends KE.\n");
1167                 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1168                 goto end;
1169         }
1170 
1171         /*
1172          * save the packet from the initiator in order to resend the
1173          * responder's first packet against this packet.
1174          */
1175         iph2->msg1 = rc_vdup(msg0);
1176 
1177         /* change status of isakmp status entry */
1178         iph2->status = PHASE2ST_STATUS2;
1179 
1180         error = 0;
1181 
1182 end:
1183         if (hbuf)
1184                 rc_vfree(hbuf);
1185         if (msg)
1186                 rc_vfree(msg);
1187         if (pbuf)
1188                 rc_vfree(pbuf);
1189 
1190         if (error) {
1191                 VPTRINIT(iph2->sa);
1192                 VPTRINIT(iph2->nonce_p);
1193                 VPTRINIT(iph2->dhpub_p);
1194                 VPTRINIT(iph2->id);
1195                 VPTRINIT(iph2->id_p);
1196         }
1197 
1198         return error;
1199 }
1200 
1201 /*
1202  * call pfkey_getspi.
1203  */
1204 int
1205 quick_r1prep(struct ph2handle *iph2, rc_vchar_t *msg)
1206 {
1207         int error = ISAKMP_INTERNAL_ERROR;
1208 
1209         /* validity check */
1210         if (iph2->status != PHASE2ST_STATUS2) {
1211                 plog(PLOG_INTERR, PLOGLOC, NULL,
1212                         "status mismatched %d.\n", iph2->status);
1213                 goto end;
1214         }
1215 
1216         iph2->status = PHASE2ST_GETSPISENT;
1217 
1218         /* send getspi message */
1219         if (pk_sendgetspi(iph2) < 0)
1220                 goto end;
1221 
1222         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey getspi sent.\n");
1223 
1224         iph2->sce = sched_new(ikev1_ipsec_sa_nego_time_limit(iph2->ph1->rmconf),
1225                 pfkey_timeover_stub, iph2);
1226 
1227         error = 0;
1228 
1229 end:
1230         return error;
1231 }
1232 
1233 /*
1234  * send to initiator
1235  *      HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
1236  */
1237 int
1238 quick_r2send(struct ph2handle *iph2, rc_vchar_t *msg)
1239 {
1240         rc_vchar_t *body = NULL;
1241         rc_vchar_t *hash = NULL;
1242         struct isakmp_gen *gen;
1243         char *p;
1244         int tlen;
1245         int error = ISAKMP_INTERNAL_ERROR;
1246         int pfsgroup;
1247         uint8_t *np_p = NULL;
1248 
1249         /* validity check */
1250         if (msg != NULL) {
1251                 plog(PLOG_INTERR, PLOGLOC, NULL,
1252                         "msg has to be NULL in this function.\n");
1253                 goto end;
1254         }
1255         if (iph2->status != PHASE2ST_GETSPIDONE) {
1256                 plog(PLOG_INTERR, PLOGLOC, NULL,
1257                         "status mismatched %d.\n", iph2->status);
1258                 goto end;
1259         }
1260 
1261         /* update responders SPI */
1262         if (ipsecdoi_updatespi(iph2) < 0) {
1263                 plog(PLOG_INTERR, PLOGLOC, NULL, "failed to update spi.\n");
1264                 goto end;
1265         }
1266 
1267         /* generate NONCE value */
1268         iph2->nonce = eay_set_random(ikev1_nonce_size(iph2->ph1->rmconf));
1269         if (iph2->nonce == NULL)
1270                 goto end;
1271 
1272         /* generate KE value if need */
1273         pfsgroup = iph2->approval->pfs_group;
1274         if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1275                 /* DH group settting if PFS is required. */
1276                 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
1277                         plog(PLOG_INTERR, PLOGLOC, NULL,
1278                                 "failed to set DH value.\n");
1279                         goto end;
1280                 }
1281                 /* generate DH public value */
1282                 if (oakley_dh_generate(iph2->pfsgrp,
1283                                 &iph2->dhpub, &iph2->dhpriv) < 0) {
1284                         goto end;
1285                 }
1286         }
1287 
1288         /* create SA;NONCE payload, and KE and ID if need */
1289         tlen = sizeof(*gen) + iph2->sa_ret->l
1290                 + sizeof(*gen) + iph2->nonce->l;
1291         if (iph2->dhpub_p != NULL && pfsgroup != 0)
1292                 tlen += (sizeof(*gen) + iph2->dhpub->l);
1293         if (iph2->id_p != NULL)
1294                 tlen += (sizeof(*gen) + iph2->id_p->l
1295                         + sizeof(*gen) + iph2->id->l);
1296 
1297         body = rc_vmalloc(tlen);
1298         if (body == NULL) { 
1299                 plog(PLOG_INTERR, PLOGLOC, NULL,
1300                         "failed to get buffer to send.\n");
1301                 goto end;
1302         }
1303         p = body->v;
1304 
1305         /* make SA payload */ 
1306         p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE);
1307 
1308         /* add NONCE payload */
1309         np_p = &((struct isakmp_gen *)p)->np;    /* XXX */
1310         p = set_isakmp_payload(p, iph2->nonce,
1311                 (iph2->dhpub_p != NULL && pfsgroup != 0)
1312                                 ? ISAKMP_NPTYPE_KE
1313                                 : (iph2->id_p != NULL
1314                                         ? ISAKMP_NPTYPE_ID
1315                                         : ISAKMP_NPTYPE_NONE));
1316 
1317         /* add KE payload if need. */
1318         if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1319                 np_p = &((struct isakmp_gen *)p)->np;    /* XXX */
1320                 p = set_isakmp_payload(p, iph2->dhpub,
1321                         (iph2->id_p == NULL)
1322                                 ? ISAKMP_NPTYPE_NONE
1323                                 : ISAKMP_NPTYPE_ID);
1324         }
1325 
1326         /* add ID payloads received. */
1327         if (iph2->id_p != NULL) {
1328                 /* IDci */
1329                 p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
1330                 /* IDcr */
1331                 np_p = &((struct isakmp_gen *)p)->np;    /* XXX */
1332                 p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE);
1333         }
1334 
1335         /* add a RESPONDER-LIFETIME notify payload if needed */
1336     {
1337         rc_vchar_t *data = NULL;
1338         struct saprop *pp = iph2->approval;
1339         struct saproto *pr;
1340 
1341         if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) {
1342                 uint32_t v = htonl((uint32_t)pp->lifetime);
1343                 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1344                                         IPSECDOI_ATTR_SA_LD_TYPE_SEC);
1345                 if (!data)
1346                         goto end;
1347                 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1348                                         (caddr_t)&v, sizeof(v));
1349                 if (!data)
1350                         goto end;
1351         }
1352         if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) {
1353                 uint32_t v = htonl((uint32_t)pp->lifebyte);
1354                 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1355                                         IPSECDOI_ATTR_SA_LD_TYPE_KB);
1356                 if (!data)
1357                         goto end;
1358                 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1359                                         (caddr_t)&v, sizeof(v));
1360                 if (!data)
1361                         goto end;
1362         }
1363 
1364         /*
1365          * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1366          * in the case of SA bundle ?
1367          */
1368         if (data) {
1369                 for (pr = pp->head; pr; pr = pr->next) {
1370                         body = isakmp_add_pl_n(body, &np_p,
1371                                         ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data);
1372                         if (!body) {
1373                                 rc_vfree(data);
1374                                 return error;   /* XXX */
1375                         }
1376                 }
1377                 rc_vfree(data);
1378         }
1379     }
1380 
1381         /* generate HASH(2) */
1382     {
1383         rc_vchar_t *tmp;
1384 
1385         tmp = rc_vmalloc(iph2->nonce_p->l + body->l);
1386         if (tmp == NULL) { 
1387                 plog(PLOG_INTERR, PLOGLOC, NULL,
1388                         "failed to get hash buffer.\n");
1389                 goto end;
1390         }
1391         memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1392         memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l);
1393 
1394         hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp);
1395         rc_vfree(tmp);
1396 
1397         if (hash == NULL)
1398                 goto end;
1399     }
1400 
1401         /* send isakmp payload */
1402         iph2->sendbuf = quick_ir1mx(iph2, body, hash);
1403         if (iph2->sendbuf == NULL)
1404                 goto end;
1405 
1406         /* send the packet, add to the schedule to resend */
1407         iph2->retry_counter = ikev1_max_retry_to_send(iph2->ph1->rmconf);
1408         if (isakmp_ph2resend(iph2) == -1)
1409                 goto end;
1410 
1411         /* the sending message is added to the received-list. */
1412         if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1, iph2->ph1->rmconf) == -1) {
1413                 plog(PLOG_INTERR , PLOGLOC, NULL,
1414                         "failed to add a response packet to the tree.\n");
1415                 goto end;
1416         }
1417 
1418         /* change status of isakmp status entry */
1419         iph2->status = PHASE2ST_MSG1SENT;
1420 
1421         error = 0;
1422 
1423 end:
1424         if (body != NULL)
1425                 rc_vfree(body);
1426         if (hash != NULL)
1427                 rc_vfree(hash);
1428 
1429         return error;
1430 }
1431 
1432 /*
1433  * receive from initiator
1434  *      HDR*, HASH(3)
1435  */
1436 int
1437 quick_r3recv(struct ph2handle *iph2, rc_vchar_t *msg0)
1438 {
1439         rc_vchar_t *msg = NULL;
1440         rc_vchar_t *pbuf = NULL;        /* for payload parsing */
1441         struct isakmp_parse_t *pa;
1442         struct isakmp_pl_hash *hash = NULL;
1443         int error = ISAKMP_INTERNAL_ERROR;
1444 
1445         /* validity check */
1446         if (iph2->status != PHASE2ST_MSG1SENT) {
1447                 plog(PLOG_INTERR, PLOGLOC, NULL,
1448                         "status mismatched %d.\n", iph2->status);
1449                 goto end;
1450         }
1451 
1452         /* decrypt packet */
1453         if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1454                 isakmp_log(0, 0, iph2->ph1->remote, 0,
1455                            PLOG_PROTOERR, PLOGLOC,
1456                            "Packet wasn't encrypted.\n");
1457                 goto end;
1458         }
1459         msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
1460         if (msg == NULL)
1461                 goto end;
1462 
1463         /* validate the type of next payload */
1464         pbuf = isakmp_parse(msg);
1465         if (pbuf == NULL)
1466                 goto end;
1467 
1468         for (pa = (struct isakmp_parse_t *)pbuf->v;
1469              pa->type != ISAKMP_NPTYPE_NONE;
1470              pa++) {
1471 
1472                 switch (pa->type) {
1473                 case ISAKMP_NPTYPE_HASH:
1474                         hash = (struct isakmp_pl_hash *)pa->ptr;
1475                         break;
1476                 case ISAKMP_NPTYPE_N:
1477                         isakmp_check_notify(pa->ptr, iph2->ph1);
1478                         break;
1479                 default:
1480                         /* don't send information, see ident_r1recv() */
1481                         isakmp_log(0, 0, iph2->ph1->remote, 0,
1482                                    PLOG_PROTOERR, PLOGLOC,
1483                                    "ignore the packet, "
1484                                    "received unexpecting payload type %d.\n",
1485                                    pa->type);
1486                         goto end;
1487                 }
1488         }
1489 
1490         /* payload existency check */
1491         if (hash == NULL) {
1492                 isakmp_log(0, 0, iph2->ph1->remote, 0,
1493                            PLOG_PROTOERR, PLOGLOC,
1494                            "few isakmp message received.\n");
1495                 goto end;
1496         }
1497 
1498         /* validate HASH(3) */
1499         /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1500     {
1501         char *r_hash;
1502         rc_vchar_t *my_hash = NULL;
1503         rc_vchar_t *tmp = NULL;
1504         int result;
1505 
1506         r_hash = (char *)hash + sizeof(*hash);
1507 
1508         plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(3) validate:");
1509         plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
1510 
1511         tmp = rc_vmalloc(iph2->nonce_p->l + iph2->nonce->l);
1512         if (tmp == NULL) { 
1513                 plog(PLOG_INTERR, PLOGLOC, NULL,
1514                         "failed to get hash buffer.\n");
1515                 goto end;
1516         }
1517         memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1518         memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l);
1519 
1520         my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
1521         rc_vfree(tmp);
1522         if (my_hash == NULL)
1523                 goto end;
1524 
1525         result = memcmp(my_hash->v, r_hash, my_hash->l);
1526         rc_vfree(my_hash);
1527 
1528         if (result) {
1529                 isakmp_log(0, 0, iph2->ph1->remote, 0,
1530                            PLOG_PROTOERR, PLOGLOC,
1531                            "HASH(3) mismatch.\n");
1532                 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1533                 goto end;
1534         }
1535     }
1536 
1537         /* if there is commit bit, don't set up SA now. */
1538         if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
1539                 iph2->status = PHASE2ST_COMMIT;
1540         } else
1541                 iph2->status = PHASE2ST_STATUS6;
1542 
1543         error = 0;
1544 
1545 end:
1546         if (pbuf != NULL)
1547                 rc_vfree(pbuf);
1548         if (msg != NULL)
1549                 rc_vfree(msg);
1550 
1551         return error;
1552 }
1553 
1554 /*
1555  * send to initiator
1556  *      HDR#*, HASH(4), notify
1557  */
1558 int
1559 quick_r3send(struct ph2handle *iph2, rc_vchar_t *msg0)
1560 {
1561         rc_vchar_t *buf = NULL;
1562         rc_vchar_t *myhash = NULL;
1563         struct isakmp_pl_n *n;
1564         rc_vchar_t *notify = NULL;
1565         char *p;
1566         int tlen;
1567         int error = ISAKMP_INTERNAL_ERROR;
1568 
1569         /* validity check */
1570         if (iph2->status != PHASE2ST_COMMIT) {
1571                 plog(PLOG_INTERR, PLOGLOC, NULL,
1572                         "status mismatched %d.\n", iph2->status);
1573                 goto end;
1574         }
1575 
1576         /* generate HASH(4) */
1577         /* XXX What can I do in the case of multiple different SA */
1578         plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(4) generate\n");
1579 
1580         /* XXX What should I do if there are multiple SAs ? */
1581         tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize;
1582         notify = rc_vmalloc(tlen);
1583         if (notify == NULL) { 
1584                 plog(PLOG_INTERR, PLOGLOC, NULL,
1585                         "failed to get notify buffer.\n");
1586                 goto end;
1587         }
1588         n = (struct isakmp_pl_n *)notify->v;
1589         n->h.np = ISAKMP_NPTYPE_NONE;
1590         put_uint16(&n->h.len, tlen);
1591         put_uint32(&n->doi, IPSEC_DOI);
1592         n->proto_id = iph2->approval->head->proto_id;
1593         n->spi_size = sizeof(iph2->approval->head->spisize);
1594         put_uint16(&n->type, ISAKMP_NTYPE_CONNECTED);
1595         memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize);
1596 
1597         myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
1598         if (myhash == NULL)
1599                 goto end;
1600 
1601         /* create buffer for isakmp payload */
1602         tlen = sizeof(struct isakmp)
1603                 + sizeof(struct isakmp_gen) + myhash->l
1604                 + notify->l;
1605         buf = rc_vmalloc(tlen);
1606         if (buf == NULL) { 
1607                 plog(PLOG_INTERR, PLOGLOC, NULL,
1608                         "failed to get buffer to send.\n");
1609                 goto end;
1610         }
1611 
1612         /* create isakmp header */
1613         p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
1614         if (p == NULL)
1615                 goto end;
1616 
1617         /* add HASH(4) payload */
1618         p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N);
1619 
1620         /* add notify payload */
1621         memcpy(p, notify->v, notify->l);
1622 
1623 #ifdef HAVE_PRINT_ISAKMP_C
1624         isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
1625 #endif
1626 
1627         /* encoding */
1628         iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
1629         if (iph2->sendbuf == NULL)
1630                 goto end;
1631 
1632         /* send the packet */
1633         if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
1634                 goto end;
1635 
1636         /* the sending message is added to the received-list. */
1637         if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0, iph2->ph1->rmconf) == -1) {
1638                 plog(PLOG_INTERR , PLOGLOC, NULL,
1639                         "failed to add a response packet to the tree.\n");
1640                 goto end;
1641         }
1642 
1643         iph2->status = PHASE2ST_COMMIT;
1644 
1645         error = 0;
1646 
1647 end:
1648         if (buf != NULL)
1649                 rc_vfree(buf);
1650         if (myhash != NULL)
1651                 rc_vfree(myhash);
1652         if (notify != NULL)
1653                 rc_vfree(notify);
1654 
1655         return error;
1656 }
1657 
1658 
1659 /*
1660  * set SA to kernel.
1661  */
1662 int
1663 quick_r3prep(struct ph2handle *iph2, rc_vchar_t *msg0)
1664 {
1665         rc_vchar_t *msg = NULL;
1666         int lifetime;
1667         int error = ISAKMP_INTERNAL_ERROR;
1668 
1669         /* validity check */
1670         if (iph2->status != PHASE2ST_STATUS6) {
1671                 plog(PLOG_INTERR, PLOGLOC, NULL,
1672                         "status mismatched %d.\n", iph2->status);
1673                 goto end;
1674         }
1675 
1676         /* compute both of KEYMATs */
1677         if (oakley_compute_keymat(iph2, RESPONDER) < 0)
1678                 goto end;
1679 
1680         iph2->status = PHASE2ST_ADDSA;
1681         iph2->flags ^= ISAKMP_FLAG_C;        /* reset bit */
1682 
1683         /* generate policy */
1684         if (rcs_is_addr_rw(iph2->selector->pl->peers_sa_ipaddr)) {
1685                 IPSEC_CONF(lifetime, iph2->selector->pl->ips,
1686                            ipsec_sa_lifetime_time, 0);
1687                 if (ike_spmif_post_policy_add(iph2->selector,
1688                                               ike_ipsec_mode(iph2->selector->pl),
1689                                               lifetime, iph2->src, iph2->dst,
1690                                               iph2->ph1->rmconf) < 0) {
1691                         plog(PLOG_INTERR, PLOGLOC, NULL,
1692                              "generate policy failed.\n");
1693                         goto end;
1694                 }
1695         }
1696 
1697         /* Do UPDATE as responder */
1698         plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n");
1699         if (pk_sendupdate(iph2) < 0) {
1700                 plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n");
1701                 goto end;
1702         }
1703         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n");
1704 
1705         /* Do ADD for responder */
1706         if (pk_sendadd(iph2) < 0) {
1707                 plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n");
1708                 goto end;
1709         }
1710         plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n");
1711 
1712         error = 0;
1713 
1714 end:
1715         if (msg != NULL)
1716                 rc_vfree(msg);
1717 
1718         return error;
1719 }
1720 
1721 
1722 /*
1723  * create HASH, body (SA, NONCE) payload with isakmp header.
1724  */
1725 static rc_vchar_t *
1726 quick_ir1mx(struct ph2handle *iph2, rc_vchar_t *body, rc_vchar_t *hash)
1727 {
1728         struct isakmp *isakmp;
1729         rc_vchar_t *buf = NULL, *new = NULL;
1730         char *p;
1731         int tlen;
1732         struct isakmp_gen *gen;
1733         int error = ISAKMP_INTERNAL_ERROR;
1734 
1735         /* create buffer for isakmp payload */
1736         tlen = sizeof(*isakmp)
1737                 + sizeof(*gen) + hash->l
1738                 + body->l;
1739         buf = rc_vmalloc(tlen);
1740         if (buf == NULL) { 
1741                 plog(PLOG_INTERR, PLOGLOC, NULL,
1742                         "failed to get buffer to send.\n");
1743                 goto end;
1744         }
1745 
1746         /* re-set encryption flag, for serurity. */
1747         iph2->flags |= ISAKMP_FLAG_E;
1748 
1749         /* set isakmp header */
1750         p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
1751         if (p == NULL)
1752                 goto end;
1753 
1754         /* add HASH payload */
1755         /* XXX is next type always SA ? */
1756         p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA);
1757 
1758         /* add body payload */
1759         memcpy(p, body->v, body->l);
1760 
1761 #ifdef HAVE_PRINT_ISAKMP_C
1762         isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
1763 #endif
1764 
1765         /* encoding */
1766         new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
1767         if (new == NULL)
1768                 goto end;
1769 
1770         rc_vfree(buf);
1771 
1772         buf = new;
1773 
1774         error = 0;
1775 
1776 end:
1777         if (error && buf != NULL) {
1778                 rc_vfree(buf);
1779                 buf = NULL;
1780         }
1781 
1782         return buf;
1783 }
1784 
1785 /*
1786  * get remote's sainfo.
1787  * NOTE: this function is for responder.
1788  */
1789 static int
1790 get_sainfo_r(struct ph2handle *iph2)
1791 {
1792         rc_vchar_t *idsrc = NULL, *iddst = NULL;
1793         int prefixlen;
1794         int error = ISAKMP_INTERNAL_ERROR;
1795 
1796         if (iph2->id == NULL) {
1797                 struct sockaddr *sa;
1798 
1799                 switch (iph2->src->sa_family) {
1800                 case AF_INET:
1801                         prefixlen = sizeof(struct in_addr) << 3;
1802                         break;
1803                 case AF_INET6:
1804                         prefixlen = sizeof(struct in6_addr) << 3;
1805                         break;
1806                 default:
1807                         plog(PLOG_PROTOERR, PLOGLOC, NULL,
1808                                 "invalid family: %d\n", iph2->src->sa_family);
1809                         goto end;
1810                 }
1811                 sa = rcs_sadup(iph2->src);
1812                 set_port(sa, 0);
1813                 idsrc = ipsecdoi_sockaddr2id(sa, prefixlen,
1814                                         IPSEC_ULPROTO_ANY);
1815                 rc_free(sa);
1816         } else {
1817                 idsrc = rc_vdup(iph2->id);
1818         }
1819         if (idsrc == NULL) {
1820                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1821                         "failed to set ID for source.\n");
1822                 goto end;
1823         }
1824 
1825         if (iph2->id_p == NULL) {
1826                 struct sockaddr *sa;
1827 
1828                 switch (iph2->dst->sa_family) {
1829                 case AF_INET:
1830                         prefixlen = sizeof(struct in_addr) << 3;
1831                         break;
1832                 case AF_INET6:
1833                         prefixlen = sizeof(struct in6_addr) << 3;
1834                         break;
1835                 default:
1836                         plog(PLOG_PROTOERR, PLOGLOC, NULL,
1837                                 "invalid family: %d\n", iph2->dst->sa_family);
1838                         goto end;
1839                 }
1840                 sa = rcs_sadup(iph2->dst);
1841                 set_port(sa, 0);
1842                 iddst = ipsecdoi_sockaddr2id(sa, prefixlen,
1843                                         IPSEC_ULPROTO_ANY);
1844                 rc_free(sa);
1845         } else {
1846                 iddst = rc_vdup(iph2->id_p);
1847         }
1848         if (iddst == NULL) {
1849                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1850                         "failed to set ID for destination.\n");
1851                 goto end;
1852         }
1853 
1854         iph2->selector = ike_conf_find_ikev1sel_by_id(idsrc, iddst);
1855         if (! iph2->selector) {
1856                 plog(PLOG_INTERR, PLOGLOC, 0,
1857                      "can't find matching selector\n");
1858                 goto end;
1859         }
1860 
1861 #if 0
1862         iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p);
1863         if (iph2->sainfo == NULL) {
1864                 plog(PLOG_INTERR, PLOGLOC, NULL,
1865                         "failed to get sainfo.\n");
1866                 goto end;
1867         }
1868 
1869         plog(PLOG_DEBUG, PLOGLOC, NULL,
1870                 "get sa info: %s\n", sainfo2str(iph2->sainfo));
1871 #endif
1872 
1873         error = 0;
1874 end:
1875         if (idsrc)
1876                 rc_vfree(idsrc);
1877         if (iddst)
1878                 rc_vfree(iddst);
1879 
1880         return error;
1881 }
1882 
1883 
1884 /*
1885  * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
1886  * are IP address and same address family.
1887  * Then get remote's policy from SPD copied from kernel.
1888  * If the type of ID payload is address or subnet type, then the index is
1889  * made from the payload.  If there is no ID payload, or the type of ID
1890  * payload is NOT address type, then the index is made from the address
1891  * pair of phase 1.
1892  * NOTE: This function is only for responder.
1893  */
1894 static int
1895 get_proposal_r(struct ph2handle *iph2)
1896 {
1897         struct rcf_selector *selector;
1898         struct rcf_policy *p;
1899 
1900         /* check the existence of ID payload */
1901         if ((iph2->id_p != NULL && iph2->id == NULL)
1902          || (iph2->id_p == NULL && iph2->id != NULL)) {
1903                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1904                         "Both IDs wasn't found in payload.\n");
1905                 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1906         }
1907 
1908         if (iph2->src_id || iph2->dst_id) {
1909                 plog(PLOG_INTERR, PLOGLOC, 0,
1910                      "ph2handle has ID[src, dst] already\n");
1911                 return ISAKMP_INTERNAL_ERROR;
1912         }
1913 
1914         selector = iph2->selector;
1915         p = selector->pl;
1916         if (!p) {
1917                 plog(PLOG_INTERR, PLOGLOC, 0,
1918                      "selector (index %s) does not have policy\n",
1919                      rc_vmem2str(selector->sl_index));
1920                 return ISAKMP_INTERNAL_ERROR;
1921         }
1922 
1923         if (set_proposal_from_policy(iph2, iph2->ph1->rmconf, p)) {
1924                 plog(PLOG_INTERR, PLOGLOC, 0,
1925                      "failed to create saprop.\n");
1926                 return ISAKMP_INTERNAL_ERROR;
1927         }
1928 
1929         return 0;
1930 #if 0
1931         struct policyindex spidx;
1932         struct secpolicy *sp_in, *sp_out;
1933         int idi2type = 0;       /* switch whether copy IDs into id[src,dst]. */
1934         int error = ISAKMP_INTERNAL_ERROR;
1935 
1936         /* check the existence of ID payload */
1937         if ((iph2->id_p != NULL && iph2->id == NULL)
1938          || (iph2->id_p == NULL && iph2->id != NULL)) {
1939                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1940                         "Both IDs wasn't found in payload.\n");
1941                 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1942         }
1943 
1944         /* make sure if id[src,dst] is null. */
1945         if (iph2->src_id || iph2->dst_id) {
1946                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1947                         "Why do ID[src,dst] exist already.\n");
1948                 return ISAKMP_INTERNAL_ERROR;
1949         }
1950 
1951         memset(&spidx, 0, sizeof(spidx));
1952 
1953 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
1954 
1955         /* make a spidx; a key to search SPD */
1956         spidx.dir = IPSEC_DIR_INBOUND;
1957         spidx.ul_proto = 0;
1958 
1959         /*
1960          * make destination address in spidx from either ID payload
1961          * or phase 1 address into a address in spidx.
1962          */
1963         if (iph2->id != NULL
1964          && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
1965           || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
1966           || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
1967           || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
1968                 /* get a destination address of a policy */
1969                 error = ipsecdoi_id2sockaddr(iph2->id,
1970                                 (struct sockaddr *)&spidx.dst,
1971                                 &spidx.prefd, &spidx.ul_proto);
1972                 if (error)
1973                         return error;
1974 
1975 #ifdef INET6
1976                 /*
1977                  * get scopeid from the SA address.
1978                  * note that the phase 1 source address is used as
1979                  * a destination address to search for a inbound policy entry
1980                  * because rcoon is responder.
1981                  */
1982                 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
1983                         error = setscopeid((struct sockaddr *)&spidx.dst,
1984                                             iph2->src);
1985                         if (error)
1986                                 return error;
1987                 }
1988 #endif
1989 
1990                 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
1991                  || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
1992                         idi2type = _XIDT(iph2->id);
1993 
1994         } else {
1995 
1996                 plog(PLOG_DEBUG, PLOGLOC, NULL,
1997                         "get a destination address of SP index "
1998                         "from phase1 address "
1999                         "due to no ID payloads found "
2000                         "OR because ID type is not address.\n");
2001 
2002                 /*
2003                  * copy the SOURCE address of IKE into the DESTINATION address
2004                  * of the key to search the SPD because the direction of policy
2005                  * is inbound.
2006                  */
2007                 memcpy(&spidx.dst, iph2->src, iph2->src->sa_len);
2008                 switch (spidx.dst.ss_family) {
2009                 case AF_INET:
2010                         spidx.prefd = sizeof(struct in_addr) << 3;
2011                         break;
2012 #ifdef INET6
2013                 case AF_INET6:
2014                         spidx.prefd = sizeof(struct in6_addr) << 3;
2015                         break;
2016 #endif
2017                 default:
2018                         spidx.prefd = 0;
2019                         break;
2020                 }
2021         }
2022 
2023         /* make source address in spidx */
2024         if (iph2->id_p != NULL
2025          && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
2026           || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
2027           || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2028           || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
2029                 /* get a source address of inbound SA */
2030                 error = ipsecdoi_id2sockaddr(iph2->id_p,
2031                                 (struct sockaddr *)&spidx.src,
2032                                 &spidx.prefs, &spidx.ul_proto);
2033                 if (error)
2034                         return error;
2035 
2036 #ifdef INET6
2037                 /*
2038                  * get scopeid from the SA address.
2039                  * for more detail, see above of this function.
2040                  */
2041                 if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
2042                         error = setscopeid((struct sockaddr *)&spidx.src,
2043                                             iph2->dst);
2044                         if (error)
2045                                 return error;
2046                 }
2047 #endif
2048 
2049                 /* make id[src,dst] if both ID types are IP address and same */
2050                 if (_XIDT(iph2->id_p) == idi2type
2051                  && spidx.dst.ss_family == spidx.src.ss_family) {
2052                         iph2->src_id = rcs_sadup((struct sockaddr *)&spidx.dst);
2053                         iph2->dst_id = rcs_sadup((struct sockaddr *)&spidx.src);
2054                 }
2055 
2056         } else {
2057                 plog(PLOG_DEBUG, PLOGLOC, NULL,
2058                         "get a source address of SP index "
2059                         "from phase1 address "
2060                         "due to no ID payloads found "
2061                         "OR because ID type is not address.\n");
2062 
2063                 /* see above comment. */
2064                 memcpy(&spidx.src, iph2->dst, iph2->dst->sa_len);
2065                 switch (spidx.src.ss_family) {
2066                 case AF_INET:
2067                         spidx.prefs = sizeof(struct in_addr) << 3;
2068                         break;
2069 #ifdef INET6
2070                 case AF_INET6:
2071                         spidx.prefs = sizeof(struct in6_addr) << 3;
2072                         break;
2073 #endif
2074                 default:
2075                         spidx.prefs = 0;
2076                         break;
2077                 }
2078         }
2079 
2080 #undef _XIDT
2081 
2082         plog(PLOG_DEBUG, PLOGLOC, NULL,
2083                 "get a src address from ID payload "
2084                 "%s prefixlen=%u ul_proto=%u\n",
2085              rcs_sa2str((struct sockaddr *)&spidx.src),
2086                 spidx.prefs, spidx.ul_proto);
2087         plog(PLOG_DEBUG, PLOGLOC, NULL,
2088                 "get dst address from ID payload "
2089                 "%s prefixlen=%u ul_proto=%u\n",
2090                 rcs_sa2str((struct sockaddr *)&spidx.dst),
2091                 spidx.prefd, spidx.ul_proto);
2092 
2093         /*
2094          * convert the ul_proto if it is 0
2095          * because 0 in ID payload means a wild card.
2096          */
2097         if (spidx.ul_proto == 0)
2098                 spidx.ul_proto = IPSEC_ULPROTO_ANY;
2099 
2100         /* get inbound policy */
2101         sp_in = getsp_r(&spidx);
2102         if (sp_in == NULL) {
2103                 if (iph2->ph1->rmconf->gen_policy) {
2104                         plog(PLOG_INFO, PLOGLOC, NULL,
2105                                 "no policy found, "
2106                                 "try to generate the policy : %s\n",
2107                                 spidx2str(&spidx));
2108                         iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2109                         if (!iph2->spidx_gen) {
2110                                 plog(PLOG_INTERR, PLOGLOC, NULL,
2111                                         "buffer allocation failed.\n");
2112                                 return ISAKMP_INTERNAL_ERROR;
2113                         }
2114                         memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2115                         return -2;      /* special value */
2116                 }
2117                 plog(PLOG_INTERR, PLOGLOC, NULL,
2118                         "no policy found: %s\n", spidx2str(&spidx));
2119                 return ISAKMP_INTERNAL_ERROR;
2120         }
2121         /* Refresh existing generated policies
2122          */
2123         if (iph2->ph1->rmconf->gen_policy) {
2124                 plog(LLV_INFO, LOCATION, NULL,
2125                          "Update the generated policy : %s\n",
2126                          spidx2str(&spidx));
2127                 iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2128                 if (!iph2->spidx_gen) {
2129                         plog(LLV_ERROR, LOCATION, NULL,
2130                                  "buffer allocation failed.\n");
2131                         return ISAKMP_INTERNAL_ERROR;
2132                 }
2133                 memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2134         }
2135 
2136         /* get outbound policy */
2137     {
2138         struct sockaddr_storage addr;
2139         uint8_t pref;
2140 
2141         spidx.dir = IPSEC_DIR_OUTBOUND;
2142         addr = spidx.src;
2143         spidx.src = spidx.dst;
2144         spidx.dst = addr;
2145         pref = spidx.prefs;
2146         spidx.prefs = spidx.prefd;
2147         spidx.prefd = pref;
2148 
2149         sp_out = getsp_r(&spidx);
2150         if (!sp_out) {
2151                 plog(PLOG_INTWARN, PLOGLOC, NULL,
2152                         "no outbound policy found: %s\n",
2153                         spidx2str(&spidx));
2154         }
2155     }
2156 
2157         plog(PLOG_DEBUG, PLOGLOC, NULL,
2158                 "suitable SP found:%s\n", spidx2str(&spidx));
2159 
2160         /*
2161          * In the responder side, the inbound policy should be using IPsec.
2162          * outbound policy is not checked currently.
2163          */
2164         if (sp_in->policy != IPSEC_POLICY_IPSEC) {
2165                 plog(PLOG_INTERR, PLOGLOC, NULL,
2166                         "policy found, but no IPsec required: %s\n",
2167                         spidx2str(&spidx));
2168                 return ISAKMP_INTERNAL_ERROR;
2169         }
2170 
2171         /* set new proposal derived from a policy into the iph2->proposal. */
2172         if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) {
2173                 plog(PLOG_INTERR, PLOGLOC, NULL,
2174                         "failed to create saprop.\n");
2175                 return ISAKMP_INTERNAL_ERROR;
2176         }
2177 
2178         return 0;
2179 #endif
2180 }
2181 
2182 #ifdef INET6
2183 static uint32_t
2184 setscopeid(struct sockaddr *sp_addr0, struct sockaddr *sa_addr0)
2185 {
2186         struct sockaddr_in6 *sp_addr, *sa_addr;
2187     
2188         sp_addr = (struct sockaddr_in6 *)sp_addr0;
2189         sa_addr = (struct sockaddr_in6 *)sa_addr0;
2190 
2191         if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr)
2192          && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr)
2193          && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr))
2194                 return 0;
2195 
2196         /* this check should not be here ? */
2197         if (sa_addr->sin6_family != AF_INET6) {
2198                 plog(PLOG_INTERR, PLOGLOC, NULL,
2199                         "can't get scope ID: family mismatch\n");
2200                 return -1;
2201         }
2202 
2203         if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) {
2204                 plog(PLOG_INTERR, PLOGLOC, NULL,
2205                         "scope ID is not supported except of lladdr.\n");
2206                 return -1;
2207         }
2208 
2209         sp_addr->sin6_scope_id = sa_addr->sin6_scope_id;
2210 
2211         return 0;
2212 }
2213 #endif