Print this page
Current snapshot of OpenSolaris port.
Checkpoint
Checkpoint
Merge from parent.
Merge with WIDE update.
Pull from WIDE.
Pull from WIDE.
Checkpoint
Re-update.
blah
WIDE update
Update from WIDE.

*** 61,74 **** --- 61,80 ---- # include <netinet6/ipsec.h> #else # ifdef HAVE_NETIPSEC_IPSEC_H # include <netipsec/ipsec.h> # else + # ifndef sun /* XXX KEBE SAYS OpenSolaris */ # include <linux/ipsec.h> # endif + # endif #endif + #ifdef sun /* XXX KEBE SAYS OpenSolaris */ + #define IPSEC_ULPROTO_ANY 0 + #endif + #include "racoon.h" #include "var.h" /* #include "vmbuf.h" */ /* #include "schedule.h" */
*** 95,104 **** --- 101,115 ---- #include "proposal.h" /* #include "sainfo.h" */ /* #include "admin.h" */ #include "strnames.h" + #ifdef sun + #include "ikev1_natt.h" + #define IPSECDOI_PREFIX_HOST 32 /* Hack for port of NAT-OA from ipsec-tools. */ + #endif + #include "ike_conf.h" /* quick mode */ static rc_vchar_t *quick_ir1mx (struct ph2handle *, rc_vchar_t *, rc_vchar_t *); static int get_sainfo_r (struct ph2handle *);
*** 185,195 **** return error; } /* * send to responder ! * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] */ int quick_i1send(struct ph2handle *iph2, rc_vchar_t *msg /* must be null pointer */) { rc_vchar_t *body = NULL; --- 196,206 ---- return error; } /* * send to responder ! * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_i1send(struct ph2handle *iph2, rc_vchar_t *msg /* must be null pointer */) { rc_vchar_t *body = NULL;
*** 199,208 **** --- 210,224 ---- int tlen; int error = ISAKMP_INTERNAL_ERROR; int pfsgroup, idci, idcr; int np; struct ipsecdoi_id_b *id, *id_p; + #ifdef sun + int natoa = ISAKMP_NPTYPE_NONE; + rc_vchar_t *nat_oai = NULL; + rc_vchar_t *nat_oar = NULL; + #endif /* validity check */ if (msg != NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "msg has to be NULL in this function.\n");
*** 273,291 **** --- 289,349 ---- && ipsecdoi_transportmode(iph2->proposal)) { idci = idcr = 0; } else idci = idcr = 1; + #ifdef sun + /* + * RFC3947 5.2. if we propose UDP-Encapsulated-Transport + * we should send NAT-OA + * + * XXX KEBE ASKS if we should send it for tunnel mode anyway, like + * we do with in.iked? + */ + if (ipsecdoi_transportmode(iph2->proposal) + && (iph2->ph1->natt_flags & NAT_DETECTED)) { + natoa = iph2->ph1->natt_options->payload_nat_oa; + + nat_oai = ipsecdoi_sockaddr2id(iph2->src, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + nat_oar = ipsecdoi_sockaddr2id(iph2->dst, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + + if (nat_oai == NULL || nat_oar == NULL) { + plog(PLOG_INTERR, PLOGLOC, NULL, + "failed to generate NAT-OA payload.\n"); + goto end; + } + + plog(PLOG_INFO, PLOGLOC, NULL, "Using NAT-OA.\n"); + plog(PLOG_DEBUG, PLOGLOC, NULL, "NAT-OAi:\n"); + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oai->v, nat_oai->l); + plog(PLOG_DEBUG, PLOGLOC, NULL, "NAT-OAr:\n"); + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oar->v, nat_oar->l); + } else { + plog(PLOG_INFO, PLOGLOC, NULL, "Not using NAT-OA.\n"); + plog(PLOG_INFO, PLOGLOC, NULL, "transportmode == %d, " + "natt_flags == 0x%x\n", + ipsecdoi_transportmode(iph2->proposal), + iph2->ph1->natt_flags & NAT_DETECTED); + natoa = ISAKMP_NPTYPE_NONE; + } + #endif + /* create SA;NONCE payload, and KE if need, and IDii, IDir. */ tlen = + sizeof(*gen) + iph2->sa->l + sizeof(*gen) + iph2->nonce->l; if (pfsgroup) tlen += (sizeof(*gen) + iph2->dhpub->l); if (idci) tlen += sizeof(*gen) + iph2->id->l; if (idcr) tlen += sizeof(*gen) + iph2->id_p->l; + #ifdef sun + if (natoa != ISAKMP_NPTYPE_NONE) + tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l; + #endif body = rc_vmalloc(tlen); if (body == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer to send.\n");
*** 301,327 **** if (pfsgroup) np = ISAKMP_NPTYPE_KE; else if (idci || idcr) np = ISAKMP_NPTYPE_ID; else ! np = ISAKMP_NPTYPE_NONE; p = set_isakmp_payload(p, iph2->nonce, np); /* add KE payload if need. */ ! np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; if (pfsgroup) p = set_isakmp_payload(p, iph2->dhpub, np); /* IDci */ ! np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; if (idci) p = set_isakmp_payload(p, iph2->id, np); /* IDcr */ if (idcr) ! p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE); /* generate HASH(1) */ hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body); if (hash == NULL) goto end; --- 359,393 ---- if (pfsgroup) np = ISAKMP_NPTYPE_KE; else if (idci || idcr) np = ISAKMP_NPTYPE_ID; else ! np = natoa; p = set_isakmp_payload(p, iph2->nonce, np); /* add KE payload if need. */ ! np = (idci || idcr) ? ISAKMP_NPTYPE_ID : natoa; if (pfsgroup) p = set_isakmp_payload(p, iph2->dhpub, np); /* IDci */ ! np = (idcr) ? ISAKMP_NPTYPE_ID : natoa; if (idci) p = set_isakmp_payload(p, iph2->id, np); /* IDcr */ if (idcr) ! p = set_isakmp_payload(p, iph2->id_p, natoa); + #ifdef sun + /* NAT-OA */ + if (natoa != ISAKMP_NPTYPE_NONE) { + p = set_isakmp_payload(p, nat_oai, natoa); + p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE); + } + #endif + /* generate HASH(1) */ hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body); if (hash == NULL) goto end;
*** 343,370 **** end: if (body != NULL) rc_vfree(body); if (hash != NULL) rc_vfree(hash); return error; } /* * receive from responder ! * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] */ int quick_i2recv(struct ph2handle *iph2, rc_vchar_t *msg0) { rc_vchar_t *msg = NULL; rc_vchar_t *hbuf = NULL; /* for hash computing. */ rc_vchar_t *pbuf = NULL; /* for payload parsing */ struct isakmp_parse_t *pa; struct isakmp *isakmp = (struct isakmp *)msg0->v; struct isakmp_pl_hash *hash = NULL; - int f_id; char *p; int tlen; int error = ISAKMP_INTERNAL_ERROR; /* validity check */ --- 409,441 ---- end: if (body != NULL) rc_vfree(body); if (hash != NULL) rc_vfree(hash); + if (nat_oai != NULL) + rc_vfree(nat_oai); + if (nat_oar != NULL) + rc_vfree(nat_oar); return error; } /* * receive from responder ! * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_i2recv(struct ph2handle *iph2, rc_vchar_t *msg0) { rc_vchar_t *msg = NULL; rc_vchar_t *hbuf = NULL; /* for hash computing. */ rc_vchar_t *pbuf = NULL; /* for payload parsing */ + rc_vchar_t *idci = NULL; + rc_vchar_t *idcr = NULL; struct isakmp_parse_t *pa; struct isakmp *isakmp = (struct isakmp *)msg0->v; struct isakmp_pl_hash *hash = NULL; char *p; int tlen; int error = ISAKMP_INTERNAL_ERROR; /* validity check */
*** 437,447 **** /* * parse the payloads. * copy non-HASH payloads into hbuf, so that we can validate HASH. */ iph2->sa_ret = NULL; - f_id = 0; /* flag to use checking ID */ tlen = 0; /* count payload length except of HASH payload. */ for (; pa->type; pa++) { /* copy to buffer for HASH */ /* Don't modify the payload */ --- 508,517 ----
*** 468,508 **** if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) goto end; break; case ISAKMP_NPTYPE_ID: ! { ! rc_vchar_t *vp; ! ! /* check ID value */ ! if (f_id == 0) { ! /* for IDci */ ! f_id = 1; ! vp = iph2->id; } else { - /* for IDcr */ - vp = iph2->id_p; } - - if (memcmp(vp->v, (caddr_t)pa->ptr + sizeof(struct isakmp_gen), vp->l)) { - - plog(PLOG_PROTOERR, PLOGLOC, NULL, - "mismatched ID was returned.\n"); - error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; - goto end; - } - } break; case ISAKMP_NPTYPE_N: isakmp_check_notify(pa->ptr, iph2->ph1); break; #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATOA_DRAFT: case ISAKMP_NPTYPE_NATOA_RFC: /* Ignore original source/destination messages */ break; #endif default: /* don't send information, see ident_r1recv() */ --- 538,601 ---- if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) goto end; break; case ISAKMP_NPTYPE_ID: ! if (idci == NULL) { ! if (isakmp_p2ph(&idci, pa->ptr) < 0) ! goto end; ! } else if (idcr == NULL) { ! if (isakmp_p2ph(&idcr, pa->ptr) < 0) ! goto end; } else { } break; case ISAKMP_NPTYPE_N: isakmp_check_notify(pa->ptr, iph2->ph1); break; #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATOA_DRAFT: case ISAKMP_NPTYPE_NATOA_RFC: + #ifdef sun + /* DON'T ignore original source/destination. */ + { + struct sockaddr_storage addr; + struct sockaddr *daddr; + uint8_t prefix; + uint16_t ul_proto; + rc_vchar_t *vp = NULL; + + if (isakmp_p2ph(&vp, pa->ptr) < 0) + goto end; + + error = ipsecdoi_id2sockaddr(vp, + (struct sockaddr *) &addr, + &prefix, &ul_proto); + + rc_vfree(vp); + + if (error) + goto end; + + daddr = rcs_sadup((struct sockaddr *) &addr); + if (daddr == NULL) + goto end; + + if (iph2->natoa_src == NULL) + iph2->natoa_src = daddr; + else if (iph2->natoa_dst == NULL) + iph2->natoa_dst = daddr; + else { + racoon_free(daddr); + goto end; + } + } + #else /* Ignore original source/destination messages */ + #endif break; #endif default: /* don't send information, see ident_r1recv() */
*** 526,535 **** --- 619,720 ---- PLOG_PROTOERR, PLOGLOC, "few isakmp message received.\n"); goto end; } + /* identity check */ + if (idci != NULL) { + struct sockaddr_storage proposed_addr, got_addr; + uint8_t proposed_prefix, got_prefix; + uint16_t proposed_ulproto, got_ulproto; + + error = ipsecdoi_id2sockaddr(iph2->id, + (struct sockaddr *) &proposed_addr, + &proposed_prefix, &proposed_ulproto); + if (error) + goto end; + + error = ipsecdoi_id2sockaddr(idci, + (struct sockaddr *) &got_addr, + &got_prefix, &got_ulproto); + if (error) + goto end; + + if (proposed_prefix != got_prefix + || proposed_ulproto != got_ulproto) { + plog(PLOG_DEBUG, PLOGLOC, NULL, + "IDci prefix/ulproto does not match proposal.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } + + if (rcs_cmpsa((struct sockaddr *) &proposed_addr, + (struct sockaddr *) &got_addr) == 0) { + plog(PLOG_DEBUG, PLOGLOC, NULL, + "IDci matches proposal.\n"); + #ifdef ENABLE_NATT + } else if (iph2->natoa_src != NULL + && rcs_cmpsa_wop(iph2->natoa_src, + (struct sockaddr *) &got_addr) == 0 + && extract_port((struct sockaddr *) &proposed_addr) == + extract_port((struct sockaddr *) &got_addr)) { + plog(PLOG_DEBUG, PLOGLOC, NULL, + "IDci matches NAT-OAi.\n"); + #endif + } else { + plog(PLOG_INTERR, PLOGLOC, NULL, + "mismatched IDci was returned.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } + } + if (idcr != NULL) { + struct sockaddr_storage proposed_addr, got_addr; + uint8_t proposed_prefix, got_prefix; + uint16_t proposed_ulproto, got_ulproto; + + error = ipsecdoi_id2sockaddr(iph2->id_p, + (struct sockaddr *) &proposed_addr, + &proposed_prefix, &proposed_ulproto); + if (error) + goto end; + + error = ipsecdoi_id2sockaddr(idcr, + (struct sockaddr *) &got_addr, + &got_prefix, &got_ulproto); + if (error) + goto end; + + if (proposed_prefix != got_prefix + || proposed_ulproto != got_ulproto) { + plog(PLOG_DEBUG, PLOGLOC, NULL, + "IDcr prefix/ulproto does not match proposal.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } + + if (rcs_cmpsa((struct sockaddr *) &proposed_addr, + (struct sockaddr *) &got_addr) == 0) { + plog(PLOG_DEBUG, PLOGLOC, NULL, + "IDcr matches proposal.\n"); + #ifdef ENABLE_NATT + } else if (iph2->natoa_dst != NULL + && rcs_cmpsa_wop(iph2->natoa_dst, + (struct sockaddr *) &got_addr) == 0 + && extract_port((struct sockaddr *) &proposed_addr) == + extract_port((struct sockaddr *) &got_addr)) { + plog(PLOG_DEBUG, PLOGLOC, NULL, + "IDcr matches NAT-OAr.\n"); + #endif + } else { + plog(PLOG_INTERR, PLOGLOC, NULL, + "mismatched IDcr was returned.\n"); + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } + } + /* Fixed buffer for calculating HASH */ memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l); plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH allocated:hbuf->l=%d actual:tlen=%d\n", hbuf->l, tlen + iph2->nonce->l);
*** 579,600 **** --- 764,830 ---- rc_vfree(hbuf); if (pbuf) rc_vfree(pbuf); if (msg) rc_vfree(msg); + if (idci) + rc_vfree(idci); + if (idcr) + rc_vfree(idcr); if (error) { VPTRINIT(iph2->sa_ret); VPTRINIT(iph2->nonce_p); VPTRINIT(iph2->dhpub_p); VPTRINIT(iph2->id); VPTRINIT(iph2->id_p); + #ifdef ENABLE_NATT + if (iph2->natoa_src) { + racoon_free(iph2->natoa_src); + iph2->natoa_src = NULL; } + if (iph2->natoa_dst) { + racoon_free(iph2->natoa_dst); + iph2->natoa_dst = NULL; + } + #endif + } return error; } + static int + fill_in_ipsec_sas(struct ph2handle *iph2) + { + /* + * NOTE: The OpenSolaris kernel can queue up packets on a larval SA + * such that when the SA is filled-in via SADB_UPDATE, these packets + * can be immediately processed. If the reply packet is generated + * in-kernel (e.g. ICMP_ECHO processing), an additonal ACQUIRE can + * be sent if there is not a corresponding outbound SA waiting in + * the wings. We therefore perform SADB_ADD first so that if an + * outbound SA is needed immediately during SADB_UPDATE processing, + * it is ready. + */ + + plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendadd\n"); + if (pk_sendadd(iph2) < 0) { + plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n"); + return (-1); + } + plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n"); + + plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n"); + if (pk_sendupdate(iph2) < 0) { + plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n"); + return (-1); + } + plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n"); + + return (0); + } + /* * send to responder * HDR*, HASH(3) */ int
*** 702,728 **** iph2->status = PHASE2ST_COMMIT; error = 0; goto end; } ! /* Do UPDATE for initiator */ ! plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n"); ! if (pk_sendupdate(iph2) < 0) { ! plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n"); ! goto end; ! } ! plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n"); - /* Do ADD for responder */ - if (pk_sendadd(iph2) < 0) { - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n"); - goto end; - } - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n"); - - error = 0; - end: if (buf != NULL) rc_vfree(buf); if (msg != NULL) rc_vfree(msg); --- 932,944 ---- iph2->status = PHASE2ST_COMMIT; error = 0; goto end; } ! plog(PLOG_DEBUG, PLOGLOC, NULL, "call fill_in_ipsec_sas"); ! error = fill_in_ipsec_sas(iph2); end: if (buf != NULL) rc_vfree(buf); if (msg != NULL) rc_vfree(msg);
*** 849,875 **** error = 0; goto end; } #endif ! /* Do UPDATE for initiator */ ! plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n"); ! if (pk_sendupdate(iph2) < 0) { ! plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n"); ! goto end; ! } ! plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n"); - /* Do ADD for responder */ - if (pk_sendadd(iph2) < 0) { - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n"); - goto end; - } - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n"); - - error = 0; - end: if (msg != NULL) rc_vfree(msg); if (pbuf != NULL) rc_vfree(pbuf); --- 1065,1077 ---- error = 0; goto end; } #endif ! plog(PLOG_DEBUG, PLOGLOC, NULL, "call fill_in_ipsec_sas"); ! error = fill_in_ipsec_sas(iph2); end: if (msg != NULL) rc_vfree(msg); if (pbuf != NULL) rc_vfree(pbuf);
*** 879,889 **** return error; } /* * receive from initiator ! * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] */ int quick_r1recv(struct ph2handle *iph2, rc_vchar_t *msg0) { rc_vchar_t *msg = NULL; --- 1081,1091 ---- return error; } /* * receive from initiator ! * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_r1recv(struct ph2handle *iph2, rc_vchar_t *msg0) { rc_vchar_t *msg = NULL;
*** 1049,1059 **** --- 1251,1296 ---- break; #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATOA_DRAFT: case ISAKMP_NPTYPE_NATOA_RFC: + #ifdef sun + { + struct sockaddr_storage addr; + struct sockaddr *daddr; + uint8_t prefix; + uint16_t ul_proto; + rc_vchar_t *vp = NULL; + + if (isakmp_p2ph(&vp, pa->ptr) < 0) + goto end; + + error = ipsecdoi_id2sockaddr(vp, + (struct sockaddr *) &addr, + &prefix, &ul_proto); + + rc_vfree(vp); + + if (error) + goto end; + + daddr = rcs_sadup((struct sockaddr *) &addr); + if (daddr == NULL) + goto end; + + if (iph2->natoa_dst == NULL) + iph2->natoa_dst = daddr; + else if (iph2->natoa_src == NULL) + iph2->natoa_src = daddr; + else { + racoon_free(daddr); + goto end; + } + } + #else /* Ignore original source/destination messages */ + #endif break; #endif default: isakmp_log(0, 0, iph2->ph1->remote, 0,
*** 1117,1126 **** --- 1354,1364 ---- error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; goto end; } } + #ifndef sun /* get sainfo */ error = get_sainfo_r(iph2); if (error) { plog(PLOG_PROTOERR, PLOGLOC, NULL, "failed to get sainfo.\n");
*** 1165,1184 **** plog(PLOG_PROTOERR, PLOGLOC, NULL, "PFS is specified, but peer doesn't sends KE.\n"); error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; goto end; } /* * save the packet from the initiator in order to resend the * responder's first packet against this packet. */ iph2->msg1 = rc_vdup(msg0); - /* change status of isakmp status entry */ - iph2->status = PHASE2ST_STATUS2; - error = 0; end: if (hbuf) rc_vfree(hbuf); --- 1403,1423 ---- plog(PLOG_PROTOERR, PLOGLOC, NULL, "PFS is specified, but peer doesn't sends KE.\n"); error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; goto end; } + /* change status of isakmp status entry */ + iph2->status = PHASE2ST_STATUS2; + #endif /* sun/OpenSolaris */ + /* * save the packet from the initiator in order to resend the * responder's first packet against this packet. */ iph2->msg1 = rc_vdup(msg0); error = 0; end: if (hbuf) rc_vfree(hbuf);
*** 1191,1201 **** --- 1430,1450 ---- VPTRINIT(iph2->sa); VPTRINIT(iph2->nonce_p); VPTRINIT(iph2->dhpub_p); VPTRINIT(iph2->id); VPTRINIT(iph2->id_p); + #ifdef ENABLE_NATT + if (iph2->natoa_src) { + racoon_free(iph2->natoa_src); + iph2->natoa_src = NULL; } + if (iph2->natoa_dst) { + racoon_free(iph2->natoa_dst); + iph2->natoa_dst = NULL; + } + #endif + } return error; } /*
*** 1230,1240 **** return error; } /* * send to initiator ! * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] */ int quick_r2send(struct ph2handle *iph2, rc_vchar_t *msg) { rc_vchar_t *body = NULL; --- 1479,1489 ---- return error; } /* * send to initiator ! * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ] */ int quick_r2send(struct ph2handle *iph2, rc_vchar_t *msg) { rc_vchar_t *body = NULL;
*** 1241,1252 **** --- 1490,1506 ---- rc_vchar_t *hash = NULL; struct isakmp_gen *gen; char *p; int tlen; int error = ISAKMP_INTERNAL_ERROR; + int natoa = ISAKMP_NPTYPE_NONE; int pfsgroup; uint8_t *np_p = NULL; + #ifdef ENABLE_NATT + rc_vchar_t *nat_oai = NULL; + rc_vchar_t *nat_oar = NULL; + #endif /* validity check */ if (msg != NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "msg has to be NULL in this function.\n");
*** 1283,1301 **** --- 1537,1587 ---- &iph2->dhpub, &iph2->dhpriv) < 0) { goto end; } } + #ifdef ENABLE_NATT + /* + * RFC3947 5.2. if we chose UDP-Encapsulated-Transport + * we should send NAT-OA + */ + if (ipsecdoi_transportmode(iph2->proposal) + && (iph2->ph1->natt_flags & NAT_DETECTED)) { + natoa = iph2->ph1->natt_options->payload_nat_oa; + + nat_oai = ipsecdoi_sockaddr2id(iph2->dst, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + nat_oar = ipsecdoi_sockaddr2id(iph2->src, + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY); + + if (nat_oai == NULL || nat_oar == NULL) { + plog(PLOG_INTERR, PLOGLOC, NULL, + "failed to generate NAT-OA payload.\n"); + goto end; + } + + plog(PLOG_DEBUG, PLOGLOC, NULL, "NAT-OAi:\n"); + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oai->v, nat_oai->l); + plog(PLOG_DEBUG, PLOGLOC, 0, NULL, "NAT-OAr:\n"); + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oar->v, nat_oar->l); + } + #endif + /* create SA;NONCE payload, and KE and ID if need */ tlen = sizeof(*gen) + iph2->sa_ret->l + sizeof(*gen) + iph2->nonce->l; if (iph2->dhpub_p != NULL && pfsgroup != 0) tlen += (sizeof(*gen) + iph2->dhpub->l); if (iph2->id_p != NULL) tlen += (sizeof(*gen) + iph2->id_p->l + sizeof(*gen) + iph2->id->l); + #ifdef ENABLE_NATT + if (natoa != ISAKMP_NPTYPE_NONE) + tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l; + #endif + body = rc_vmalloc(tlen); if (body == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer to send.\n"); goto end;
*** 1310,1338 **** p = set_isakmp_payload(p, iph2->nonce, (iph2->dhpub_p != NULL && pfsgroup != 0) ? ISAKMP_NPTYPE_KE : (iph2->id_p != NULL ? ISAKMP_NPTYPE_ID ! : ISAKMP_NPTYPE_NONE)); /* add KE payload if need. */ if (iph2->dhpub_p != NULL && pfsgroup != 0) { np_p = &((struct isakmp_gen *)p)->np; /* XXX */ p = set_isakmp_payload(p, iph2->dhpub, (iph2->id_p == NULL) ! ? ISAKMP_NPTYPE_NONE : ISAKMP_NPTYPE_ID); } /* add ID payloads received. */ if (iph2->id_p != NULL) { /* IDci */ p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID); /* IDcr */ np_p = &((struct isakmp_gen *)p)->np; /* XXX */ ! p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE); } /* add a RESPONDER-LIFETIME notify payload if needed */ { rc_vchar_t *data = NULL; struct saprop *pp = iph2->approval; --- 1596,1631 ---- p = set_isakmp_payload(p, iph2->nonce, (iph2->dhpub_p != NULL && pfsgroup != 0) ? ISAKMP_NPTYPE_KE : (iph2->id_p != NULL ? ISAKMP_NPTYPE_ID ! : natoa)); /* add KE payload if need. */ if (iph2->dhpub_p != NULL && pfsgroup != 0) { np_p = &((struct isakmp_gen *)p)->np; /* XXX */ p = set_isakmp_payload(p, iph2->dhpub, (iph2->id_p == NULL) ! ? natoa : ISAKMP_NPTYPE_ID); } /* add ID payloads received. */ if (iph2->id_p != NULL) { /* IDci */ p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID); /* IDcr */ np_p = &((struct isakmp_gen *)p)->np; /* XXX */ ! p = set_isakmp_payload(p, iph2->id, natoa); } + #ifdef ENABLE_NATT + /* NAT-OA */ + if (natoa != ISAKMP_NPTYPE_NONE) { + p = set_isakmp_payload(p, nat_oai, natoa); + p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE); + } + #endif /* add a RESPONDER-LIFETIME notify payload if needed */ { rc_vchar_t *data = NULL; struct saprop *pp = iph2->approval;
*** 1423,1432 **** --- 1716,1731 ---- end: if (body != NULL) rc_vfree(body); if (hash != NULL) rc_vfree(hash); + #ifdef ENABLE_NATT + if (nat_oai != NULL) + rc_vfree(nat_oai); + if (nat_oar != NULL) + rc_vfree(nat_oar); + #endif return error; } /*
*** 1692,1718 **** "generate policy failed.\n"); goto end; } } ! /* Do UPDATE as responder */ ! plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n"); ! if (pk_sendupdate(iph2) < 0) { ! plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n"); ! goto end; ! } ! plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n"); - /* Do ADD for responder */ - if (pk_sendadd(iph2) < 0) { - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n"); - goto end; - } - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n"); - - error = 0; - end: if (msg != NULL) rc_vfree(msg); return error; --- 1991,2003 ---- "generate policy failed.\n"); goto end; } } ! plog(PLOG_DEBUG, PLOGLOC, NULL, "call fill_in_ipsec_sas"); ! error = fill_in_ipsec_sas(iph2); end: if (msg != NULL) rc_vfree(msg); return error;
*** 2124,2134 **** plog(LLV_INFO, LOCATION, NULL, "Update the generated policy : %s\n", spidx2str(&spidx)); iph2->spidx_gen = racoon_malloc(sizeof(spidx)); if (!iph2->spidx_gen) { ! plog(LLV_ERROR, LOCATION, NULL, "buffer allocation failed.\n"); return ISAKMP_INTERNAL_ERROR; } memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); } --- 2409,2419 ---- plog(LLV_INFO, LOCATION, NULL, "Update the generated policy : %s\n", spidx2str(&spidx)); iph2->spidx_gen = racoon_malloc(sizeof(spidx)); if (!iph2->spidx_gen) { ! plog(PLOG_INTERR, PLOGLOC, NULL, "buffer allocation failed.\n"); return ISAKMP_INTERNAL_ERROR; } memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); }
*** 2174,2184 **** "failed to create saprop.\n"); return ISAKMP_INTERNAL_ERROR; } return 0; ! #endif } #ifdef INET6 static uint32_t setscopeid(struct sockaddr *sp_addr0, struct sockaddr *sa_addr0) --- 2459,2469 ---- "failed to create saprop.\n"); return ISAKMP_INTERNAL_ERROR; } return 0; ! #endif /* 0 */ } #ifdef INET6 static uint32_t setscopeid(struct sockaddr *sp_addr0, struct sockaddr *sa_addr0)