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)