X-Git-Url: https://git.saurik.com/apple/network_cmds.git/blobdiff_plain/7ba0088d6898d7fd2873f736f1f556673a8be855..f47db663cb3ae4d2fc391bb3acf9d0c2b38a41b7:/racoon.tproj/isakmp_ident.c diff --git a/racoon.tproj/isakmp_ident.c b/racoon.tproj/isakmp_ident.c index 4e15a47..e5c46c2 100644 --- a/racoon.tproj/isakmp_ident.c +++ b/racoon.tproj/isakmp_ident.c @@ -1,4 +1,4 @@ -/* $KAME: isakmp_ident.c,v 1.62 2001/12/12 15:29:13 sakane Exp $ */ +/* $KAME: isakmp_ident.c,v 1.63 2001/12/12 17:57:26 sakane Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -38,6 +38,7 @@ #include #include #include +#include #if TIME_WITH_SYS_TIME # include # include @@ -68,6 +69,7 @@ #include "pfkey.h" #include "isakmp_ident.h" #include "isakmp_inf.h" +#include "isakmp_natd.h" #include "vendorid.h" #ifdef HAVE_GSSAPI @@ -96,6 +98,10 @@ ident_i1send(iph1, msg) caddr_t p; int tlen; int error = -1; + vchar_t *vid_natt_rfc = NULL; + vchar_t *vid_natt_apple = NULL; + vchar_t *vid_natt_02 = NULL; + vchar_t *vid_natt_02N = NULL; /* validity check */ if (msg != NULL) { @@ -122,6 +128,26 @@ ident_i1send(iph1, msg) tlen = sizeof(struct isakmp) + sizeof(*gen) + iph1->sa->l; +#ifdef IKE_NAT_T + vid_natt_rfc = set_vendorid(VENDORID_NATT_RFC); + vid_natt_apple = set_vendorid(VENDORID_NATT_APPLE); + vid_natt_02 = set_vendorid(VENDORID_NATT_02); + vid_natt_02N = set_vendorid(VENDORID_NATT_02N); + + if (vid_natt_rfc == NULL || + vid_natt_apple == NULL || + vid_natt_02 == NULL || + vid_natt_02N == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to get vendor ID buffer.\n"); + goto end; + } + tlen += sizeof(*gen) + vid_natt_rfc->l; + tlen += sizeof(*gen) + vid_natt_apple->l; + tlen += sizeof(*gen) + vid_natt_02->l; + tlen += sizeof(*gen) + vid_natt_02N->l; +#endif + iph1->sendbuf = vmalloc(tlen); if (iph1->sendbuf == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -135,7 +161,14 @@ ident_i1send(iph1, msg) goto end; /* set SA payload to propose */ - p = set_isakmp_payload(p, iph1->sa, ISAKMP_NPTYPE_NONE); + p = set_isakmp_payload(p, iph1->sa, vid_natt_rfc ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE); + + if (vid_natt_rfc) { + p = set_isakmp_payload(p, vid_natt_rfc, ISAKMP_NPTYPE_VID); + p = set_isakmp_payload(p, vid_natt_apple, ISAKMP_NPTYPE_VID); + p = set_isakmp_payload(p, vid_natt_02, ISAKMP_NPTYPE_VID); + p = set_isakmp_payload(p, vid_natt_02N, ISAKMP_NPTYPE_NONE); + } #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -151,6 +184,14 @@ ident_i1send(iph1, msg) error = 0; end: + if (vid_natt_rfc) + vfree(vid_natt_rfc); + if (vid_natt_apple) + vfree(vid_natt_apple); + if (vid_natt_02) + vfree(vid_natt_02); + if (vid_natt_02N) + vfree(vid_natt_02N); return error; } @@ -212,7 +253,19 @@ ident_i2recv(iph1, msg) switch (pa->type) { case ISAKMP_NPTYPE_VID: - (void)check_vendorid(pa->ptr); +#ifdef IKE_NAT_T + { + int vid = check_vendorid(pa->ptr); + if (vid == VENDORID_NATT_RFC) + iph1->natt_flags |= natt_type_rfc; + else if (vid == VENDORID_NATT_APPLE) + iph1->natt_flags |= natt_type_apple; + else if (vid == VENDORID_NATT_02) + iph1->natt_flags |= natt_type_02; + else if (vid == VENDORID_NATT_02N) + iph1->natt_flags |= natt_type_02N; + } +#endif break; default: /* don't send information, see ident_r1recv() */ @@ -224,6 +277,9 @@ ident_i2recv(iph1, msg) } } + /* if natt vid(s) received - select type to use */ + natt_select_type(iph1); + /* check SA payload and set approval SA for use */ if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) { plog(LLV_ERROR, LOCATION, iph1->remote, @@ -381,6 +437,21 @@ ident_i3recv(iph1, msg) gssapi_save_received_token(iph1, gsstoken); break; #endif + case ISAKMP_NPTYPE_NATD_RFC: + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_BADDRAFT: +#ifdef IKE_NAT_T + + if (pa->type == iph1->natd_payload_type) { + natd_match_t match = natd_matches(iph1, pa->ptr); + iph1->natt_flags |= natt_natd_received; + if ((match & natd_match_local) != 0) + iph1->natt_flags |= natt_no_local_nat; + if ((match & natd_match_remote) != 0) + iph1->natt_flags |= natt_no_remote_nat; + } +#endif + break; default: /* don't send information, see ident_r1recv() */ plog(LLV_ERROR, LOCATION, iph1->remote, @@ -390,6 +461,24 @@ ident_i3recv(iph1, msg) goto end; } } + +#ifdef IKE_NAT_T + /* Determine if we need to switch to port 4500 */ + if (natd_hasnat(iph1)) + { + /* There is a NAT between us! Switch to port 4500. */ + if (iph1->remote->sa_family == AF_INET) + { + struct sockaddr_in *sin = (struct sockaddr_in*)iph1->remote; + plog(LLV_INFO, LOCATION, NULL, + "detected NAT, switching to port %d for %s", + PORT_ISAKMP_NATT, saddr2str(iph1->remote)); + sin->sin_port = htons(PORT_ISAKMP_NATT); + sin = (struct sockaddr_in*)iph1->local; + sin->sin_port = htons(PORT_ISAKMP_NATT); + } + } +#endif /* payload existency check */ if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { @@ -759,7 +848,19 @@ ident_r1recv(iph1, msg) switch (pa->type) { case ISAKMP_NPTYPE_VID: - (void)check_vendorid(pa->ptr); + { + int vid = check_vendorid(pa->ptr); +#if IKE_NAT_T + if (vid == VENDORID_NATT_RFC) + iph1->natt_flags |= natt_type_rfc; + else if (vid == VENDORID_NATT_APPLE) + iph1->natt_flags |= natt_type_apple; + else if (vid == VENDORID_NATT_02) + iph1->natt_flags |= natt_type_02; + else + iph1->natt_flags |= natt_type_02N; +#endif + } break; default: /* @@ -777,6 +878,9 @@ ident_r1recv(iph1, msg) } } + /* if natt vid(s) received - select type to use */ + natt_select_type(iph1); + /* check SA payload and set approval SA for use */ if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) { plog(LLV_ERROR, LOCATION, iph1->remote, @@ -817,6 +921,9 @@ ident_r1send(iph1, msg) int error = -1; vchar_t *gss_sa = NULL; vchar_t *vid = NULL; +#ifdef IKE_NAT_T + vchar_t *nattvid = NULL; +#endif /* validity check */ if (iph1->status != PHASE1ST_MSG1RECEIVED) { @@ -842,6 +949,26 @@ ident_r1send(iph1, msg) if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL) tlen += sizeof(*gen) + vid->l; +#ifdef IKE_NAT_T + { + int natt_type = iph1->natt_flags & NATT_TYPE_MASK; + + if (natt_type != 0) { + if (natt_type == natt_type_rfc) + nattvid = set_vendorid(VENDORID_NATT_RFC); + else if (natt_type == natt_type_apple) + nattvid = set_vendorid(VENDORID_NATT_APPLE); + else if (natt_type == natt_type_02) + nattvid = set_vendorid(VENDORID_NATT_02); + else if (natt_type == natt_type_02N) + nattvid = set_vendorid(VENDORID_NATT_02N); + + if (nattvid != NULL) + tlen += sizeof(*gen) + nattvid->l; + } + } +#endif + iph1->sendbuf = vmalloc(tlen); if (iph1->sendbuf == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -856,12 +983,15 @@ ident_r1send(iph1, msg) /* set SA payload to reply */ p = set_isakmp_payload(p, gss_sa, - vid ? ISAKMP_NPTYPE_VID + (vid || nattvid) ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE); /* Set Vendor ID, if necessary. */ if (vid) - p = set_isakmp_payload(p, vid, ISAKMP_NPTYPE_NONE); + p = set_isakmp_payload(p, vid, nattvid ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE); + + if (nattvid) + p = set_isakmp_payload(p, nattvid, ISAKMP_NPTYPE_NONE); #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -890,6 +1020,8 @@ end: #endif if (vid) vfree(vid); + if (nattvid) + vfree(nattvid); return error; } @@ -954,6 +1086,20 @@ ident_r2recv(iph1, msg) gssapi_save_received_token(iph1, gsstoken); break; #endif + case ISAKMP_NPTYPE_NATD_RFC: + case ISAKMP_NPTYPE_NATD_DRAFT: + case ISAKMP_NPTYPE_NATD_BADDRAFT: +#ifdef IKE_NAT_T + if (pa->type == iph1->natd_payload_type) { + natd_match_t match = natd_matches(iph1, pa->ptr); + iph1->natt_flags |= natt_natd_received; + if ((match & natd_match_local) != 0) + iph1->natt_flags |= natt_no_local_nat; + if ((match & natd_match_remote) != 0) + iph1->natt_flags |= natt_no_remote_nat; + } +#endif + break; default: /* don't send information, see ident_r1recv() */ plog(LLV_ERROR, LOCATION, iph1->remote, @@ -1392,6 +1538,7 @@ ident_ir2mx(iph1) #ifdef HAVE_GSSAPI vchar_t *gsstoken = NULL; #endif + int natd_type = 0; #ifdef HAVE_SIGNING_C /* create CR if need */ @@ -1427,6 +1574,17 @@ ident_ir2mx(iph1) tlen += sizeof(*gen) + gsstoken->l; #endif +#ifdef IKE_NAT_T + if ((iph1->natt_flags & NATT_TYPE_MASK) != 0) { + natd_type = iph1->natd_payload_type; + natd_create(iph1); + if (iph1->local_natd) + tlen += sizeof(*gen) + iph1->local_natd->l; + if (iph1->remote_natd) + tlen += sizeof(*gen) + iph1->remote_natd->l; + } +#endif + buf = vmalloc(tlen); if (buf == NULL) { plog(LLV_ERROR, LOCATION, NULL, @@ -1449,7 +1607,8 @@ ident_ir2mx(iph1) else #endif nptype = vid ? ISAKMP_NPTYPE_VID : - (need_cr ? ISAKMP_NPTYPE_CR : ISAKMP_NPTYPE_NONE); + (need_cr ? ISAKMP_NPTYPE_CR : + (natd_type ? natd_type : ISAKMP_NPTYPE_NONE)); p = set_isakmp_payload(p, iph1->nonce, nptype); #ifdef HAVE_GSSAPI @@ -1457,7 +1616,7 @@ ident_ir2mx(iph1) p = set_isakmp_payload(p, gsstoken, vid ? ISAKMP_NPTYPE_VID : (need_cr ? ISAKMP_NPTYPE_CR - : ISAKMP_NPTYPE_NONE)); + : (natd_type ? natd_type : ISAKMP_NPTYPE_NONE))); } #endif @@ -1465,12 +1624,27 @@ ident_ir2mx(iph1) if (vid) p = set_isakmp_payload(p, vid, need_cr ? ISAKMP_NPTYPE_CR - : ISAKMP_NPTYPE_NONE); + : (natd_type ? natd_type : ISAKMP_NPTYPE_NONE)); /* create isakmp CR payload if needed */ if (need_cr) - p = set_isakmp_payload(p, cr, ISAKMP_NPTYPE_NONE); - + p = set_isakmp_payload(p, cr, natd_type ? natd_type : ISAKMP_NPTYPE_NONE); + +#ifdef IKE_NAT_T + if (natd_type) { + if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) { + if (iph1->local_natd) + p = set_isakmp_payload(p, iph1->local_natd, natd_type); + if (iph1->remote_natd) + p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE); + } else { + if (iph1->remote_natd) + p = set_isakmp_payload(p, iph1->remote_natd, natd_type); + if (iph1->local_natd) + p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE); + } + } +#endif error = 0; end: