X-Git-Url: https://git.saurik.com/apple/ipsec.git/blobdiff_plain/52b7d2ce06d68d0a9160d16f6e7c08c21c149d0d..e627a751fc4d26304657fc20440abb72632b1e6e:/ipsec-tools/racoon/isakmp_ident.c diff --git a/ipsec-tools/racoon/isakmp_ident.c b/ipsec-tools/racoon/isakmp_ident.c index d9e6cf9..6c1a293 100644 --- a/ipsec-tools/racoon/isakmp_ident.c +++ b/ipsec-tools/racoon/isakmp_ident.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_ident.c,v 1.13.2.2 2005/11/21 09:46:23 vanhu Exp $ */ +/* $NetBSD: isakmp_ident.c,v 1.6 2006/10/02 21:41:59 manu Exp $ */ + +/* Id: isakmp_ident.c,v 1.21 2006/04/06 16:46:08 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -58,12 +60,12 @@ #include "sockmisc.h" #include "schedule.h" #include "debug.h" +#include "fsm.h" #include "localconf.h" #include "remoteconf.h" #include "isakmp_var.h" #include "isakmp.h" -#include "evt.h" #include "oakley.h" #include "handler.h" #include "ipsec_doi.h" @@ -76,15 +78,24 @@ #ifdef ENABLE_NATT #include "nattraversal.h" #endif -#ifdef HAVE_GSSAPI -#include "gssapi.h" +#ifdef ENABLE_HYBRID +#include "isakmp_xauth.h" +#include "isakmp_cfg.h" +#endif +#ifdef ENABLE_FRAG +#include "isakmp_frag.h" #endif #include "vpn_control.h" #include "vpn_control_var.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" +#ifndef HAVE_OPENSSL +#include +#endif -static vchar_t *ident_ir2mx __P((struct ph1handle *)); -static vchar_t *ident_ir3mx __P((struct ph1handle *)); +static vchar_t *ident_ir2mx (phase1_handle_t *); +static vchar_t *ident_ir3mx (phase1_handle_t *); /* %%% * begin Identity Protection Mode as initiator. @@ -98,7 +109,7 @@ static vchar_t *ident_ir3mx __P((struct ph1handle *)); */ int ident_i1send(iph1, msg) - struct ph1handle *iph1; + phase1_handle_t *iph1; vchar_t *msg; /* must be null */ { struct payload_list *plist = NULL; @@ -107,18 +118,28 @@ ident_i1send(iph1, msg) vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; int i; #endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif #ifdef ENABLE_DPD vchar_t *vid_dpd = NULL; #endif - /* validity check */ - if (msg != NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "msg has to be NULL in this function.\n"); + + /* validity check */ + if (iph1->status != IKEV1_STATE_IDENT_I_START) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } - if (iph1->status != PHASE1ST_START) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + + /* validity check */ + if (msg != NULL) { + plog(ASL_LEVEL_ERR, + "msg has to be NULL in this function.\n"); goto end; } @@ -127,9 +148,12 @@ ident_i1send(iph1, msg) isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); /* create SA payload for my proposal */ - iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal); - if (iph1->sa == NULL) + iph1->sa = ipsecdoi_setph1proposal(iph1); + if (iph1->sa == NULL) { + plog(ASL_LEVEL_ERR, + "failed to set proposal"); goto end; + } /* set SA payload to propose */ plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA); @@ -139,12 +163,51 @@ ident_i1send(iph1, msg) if (iph1->rmconf->nat_traversal) plist = isakmp_plist_append_natt_vids(plist, vid_natt); #endif +#ifdef ENABLE_HYBRID + /* Do we need Xauth VID? */ + switch (RMAUTHMETHOD(iph1)) { + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) + plog(ASL_LEVEL_ERR, + "Xauth vendor ID generation failed\n"); + else + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) + plog(ASL_LEVEL_ERR, + "Unity vendor ID generation failed\n"); + else + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + break; + default: + break; + } +#endif +#ifdef ENABLE_FRAG + if (iph1->rmconf->ike_frag) { + if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) { + plog(ASL_LEVEL_ERR, + "Frag vendorID construction failed\n"); + } else { + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_IDENT); + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } + } +#endif #ifdef ENABLE_DPD if(iph1->rmconf->dpd){ vid_dpd = set_vendorid(VENDORID_DPD); if (vid_dpd != NULL) plist = isakmp_plist_append(plist, vid_dpd, - ISAKMP_NPTYPE_VID); + ISAKMP_NPTYPE_VID); } #endif @@ -156,18 +219,42 @@ ident_i1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(ASL_LEVEL_ERR, + "failed to send packet"); goto end; + } - iph1->status = PHASE1ST_MSG1SENT; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_MSG1SENT); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Main-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 1"), + CONSTSTR("Failed to transmit Main-Mode Message 1")); + } +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif #ifdef ENABLE_NATT for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) vfree(vid_natt[i]); #endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif #ifdef ENABLE_DPD if (vid_dpd != NULL) vfree(vid_dpd); @@ -185,7 +272,7 @@ end: */ int ident_i2recv(iph1, msg) - struct ph1handle *iph1; + phase1_handle_t *iph1; vchar_t *msg; { vchar_t *pbuf = NULL; @@ -194,10 +281,10 @@ ident_i2recv(iph1, msg) int error = -1; int vid_numeric; - /* validity check */ - if (iph1->status != PHASE1ST_MSG1SENT) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_IDENT_I_MSG1SENT) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } @@ -212,20 +299,26 @@ ident_i2recv(iph1, msg) * NOTE: even if there's multiple VID/N, we'll ignore them. */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to parse msg"); goto end; - pa = (struct isakmp_parse_t *)pbuf->v; + } + pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; /* SA payload is fixed postion */ if (pa->type != ISAKMP_NPTYPE_SA) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "received invalid next payload type %d, " "expecting %d.\n", pa->type, ISAKMP_NPTYPE_SA); goto end; } - if (isakmp_p2ph(&satmp, pa->ptr) < 0) + if (isakmp_p2ph(&satmp, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process SA payload"); goto end; + } pa++; for (/*nothing*/; @@ -239,14 +332,38 @@ ident_i2recv(iph1, msg) if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric)) natt_handle_vendorid(iph1, vid_numeric); #endif +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif #ifdef ENABLE_DPD if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) iph1->dpd_support=1; +#endif +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT)) { + plog(ASL_LEVEL_DEBUG, + "remote supports FRAGMENTATION\n"); + iph1->frag = 1; + } #endif break; default: /* don't send information, see ident_r1recv() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -255,22 +372,24 @@ ident_i2recv(iph1, msg) } #ifdef ENABLE_NATT - if (NATT_AVAILABLE(iph1)) - plog(LLV_INFO, LOCATION, iph1->remote, + if (NATT_AVAILABLE(iph1)) { + plog(ASL_LEVEL_NOTICE, "Selected NAT-T version: %s\n", vid_string_by_id(iph1->natt_options->version)); + ike_session_update_natt_version(iph1); + } #endif /* check SA payload and set approval SA for use */ if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "failed to get valid proposal.\n"); /* XXX send information */ goto end; } VPTRINIT(iph1->sa_ret); - iph1->status = PHASE1ST_MSG2RECEIVED; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_MSG2RCVD); #ifdef ENABLE_VPNCONTROL_PORT vpncontrol_notify_phase_change(1, FROM_REMOTE, iph1, NULL); @@ -278,7 +397,18 @@ ident_i2recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Main-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 2"), + CONSTSTR("Failed to process Main-Mode Message 2")); + } if (pbuf) vfree(pbuf); if (satmp) @@ -296,16 +426,16 @@ end: * Ke_i, [<Ke_i] */ int -ident_i2send(iph1, msg) - struct ph1handle *iph1; +ident_i3send(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { int error = -1; - /* validity check */ - if (iph1->status != PHASE1ST_MSG2RECEIVED) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_IDENT_I_MSG2RCVD) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } @@ -314,25 +444,33 @@ ident_i2send(iph1, msg) sizeof(cookie_t)); /* generate DH public value */ +#ifdef HAVE_OPENSSL if (oakley_dh_generate(iph1->approval->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { +#else + if (oakley_dh_generate(iph1->approval->dhgrp, + &iph1->dhpub, &iph1->publicKeySize, &iph1->dhC) < 0) { +#endif + plog(ASL_LEVEL_ERR, + "failed to generate DH"); goto end; + } /* generate NONCE value */ iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); - if (iph1->nonce == NULL) - goto end; - -#ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && - gssapi_get_itoken(iph1, NULL) < 0) + if (iph1->nonce == NULL) { + plog(ASL_LEVEL_ERR, + "failed to generate NONCE"); goto end; -#endif + } /* create buffer to send isakmp payload */ iph1->sendbuf = ident_ir2mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to create send buffer"); goto end; + } #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -340,21 +478,36 @@ ident_i2send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(ASL_LEVEL_ERR, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { - plog(LLV_ERROR , LOCATION, NULL, + if (ike_session_add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1, iph1->sendbuf), PH1_FRAG_FLAGS(iph1)) == -1) { + plog(ASL_LEVEL_ERR , "failed to add a response packet to the tree.\n"); goto end; } - iph1->status = PHASE1ST_MSG2SENT; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_MSG3SENT); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Main-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 3"), + CONSTSTR("Failed to transmit Main-Mode Message 3")); + } return error; } @@ -367,72 +520,97 @@ end: * rev: HDR, PubKey_i, Ke_r, Ke_r, */ int -ident_i3recv(iph1, msg) - struct ph1handle *iph1; +ident_i4recv(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { vchar_t *pbuf = NULL; struct isakmp_parse_t *pa; int error = -1; -#ifdef HAVE_GSSAPI - vchar_t *gsstoken = NULL; -#endif + int vid_numeric; #ifdef ENABLE_NATT vchar_t *natd_received; int natd_seq = 0, natd_verified; #endif - /* validity check */ - if (iph1->status != PHASE1ST_MSG2SENT) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_IDENT_I_MSG3SENT) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to parse msg"); goto end; + } - for (pa = (struct isakmp_parse_t *)pbuf->v; + for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; pa++) { switch (pa->type) { case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_VID: - (void)check_vendorid(pa->ptr); + vid_numeric = check_vendorid(pa->ptr); +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif +#ifdef ENABLE_DPD + if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) + iph1->dpd_support=1; +#endif + break; case ISAKMP_NPTYPE_CR: - if (oakley_savecr(iph1, pa->ptr) < 0) - goto end; - break; -#ifdef HAVE_GSSAPI - case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (oakley_savecr(iph1, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process CR payload"); goto end; - gssapi_save_received_token(iph1, gsstoken); + } break; -#endif #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATD_DRAFT: case ISAKMP_NPTYPE_NATD_RFC: -#ifdef __APPLE__ case ISAKMP_NPTYPE_NATD_BADDRAFT: -#endif if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && pa->type == iph1->natt_options->payload_nat_d) { natd_received = NULL; - if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process NATD payload"); goto end; + } /* set both bits first so that we can clear them upon verifying hashes */ @@ -444,7 +622,7 @@ ident_i3recv(iph1, msg) natd_verified = natt_compare_addr_hash (iph1, natd_received, natd_seq++); - plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + plog (ASL_LEVEL_NOTICE, "NAT-D payload #%d %s\n", natd_seq - 1, natd_verified ? "verified" : "doesn't match"); @@ -458,7 +636,7 @@ ident_i3recv(iph1, msg) default: /* don't send information, see ident_r1recv() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -468,7 +646,7 @@ ident_i3recv(iph1, msg) #ifdef ENABLE_NATT if (NATT_AVAILABLE(iph1)) { - plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + plog (ASL_LEVEL_NOTICE, "NAT %s %s%s\n", iph1->natt_flags & NAT_DETECTED ? "detected:" : "not detected", iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", @@ -480,7 +658,7 @@ ident_i3recv(iph1, msg) /* payload existency check */ if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "few isakmp message received.\n"); goto end; } @@ -490,11 +668,22 @@ ident_i3recv(iph1, msg) ; } - iph1->status = PHASE1ST_MSG3RECEIVED; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_MSG4RCVD); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Main-Mode message 4"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 4"), + CONSTSTR("Failed to process Main-Mode Message 4")); + } if (pbuf) vfree(pbuf); if (error) { @@ -517,58 +706,69 @@ end: * rev: HDR*, HASH_I */ int -ident_i3send(iph1, msg0) - struct ph1handle *iph1; +ident_i5send(iph1, msg0) + phase1_handle_t *iph1; vchar_t *msg0; { int error = -1; int dohash = 1; -#ifdef HAVE_GSSAPI - int len; -#endif - /* validity check */ - if (iph1->status != PHASE1ST_MSG3RECEIVED) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_IDENT_I_MSG4RCVD) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } /* compute sharing secret of DH */ +#ifdef HAVE_OPENSSL if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, - iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) { +#else + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub_p, iph1->publicKeySize, &iph1->dhgxy, &iph1->dhC) < 0) { +#endif + plog(ASL_LEVEL_ERR, + "failed to compute DH"); goto end; + } /* generate SKEYIDs & IV & final cipher key */ - if (oakley_skeyid(iph1) < 0) + if (oakley_skeyid(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate SKEYID"); goto end; - if (oakley_skeyid_dae(iph1) < 0) + } + if (oakley_skeyid_dae(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate SKEYID-DAE"); goto end; - if (oakley_compute_enckey(iph1) < 0) + } + if (oakley_compute_enckey(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate ENCKEY"); goto end; - if (oakley_newiv(iph1) < 0) + } + if (oakley_newiv(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate IV"); goto end; + } /* make ID payload into isakmp status */ - if (ipsecdoi_setid1(iph1) < 0) + if (ipsecdoi_setid1(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to set ID"); goto end; - -#ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && - gssapi_more_tokens(iph1)) { - plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n"); - if (gssapi_get_itoken(iph1, &len) < 0) - goto end; - if (len != 0) - dohash = 0; } -#endif /* generate HASH to send */ if (dohash) { iph1->hash = oakley_ph1hash_common(iph1, GENERATE); - if (iph1->hash == NULL) + if (iph1->hash == NULL) { + plog(ASL_LEVEL_ERR, + "failed to generate HASH"); goto end; + } } else iph1->hash = NULL; @@ -577,17 +777,24 @@ ident_i3send(iph1, msg0) /* create HDR;ID;HASH payload */ iph1->sendbuf = ident_ir3mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to allocate send buffer"); goto end; + } /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(ASL_LEVEL_ERR, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) { - plog(LLV_ERROR , LOCATION, NULL, + if (ike_session_add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0, + PH1_NON_ESP_EXTRA_LEN(iph1, iph1->sendbuf), PH1_FRAG_FLAGS(iph1)) == -1) { + plog(ASL_LEVEL_ERR , "failed to add a response packet to the tree.\n"); goto end; } @@ -595,11 +802,22 @@ ident_i3send(iph1, msg0) /* see handler.h about IV synchronization. */ memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l); - iph1->status = PHASE1ST_MSG3SENT; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_MSG5SENT); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Main-Mode message 5"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 5"), + CONSTSTR("Failed to transmit Main-Mode Message 5")); + } return error; } @@ -612,8 +830,8 @@ end: * rev: HDR*, HASH_R */ int -ident_i4recv(iph1, msg0) - struct ph1handle *iph1; +ident_i6recv(iph1, msg0) + phase1_handle_t *iph1; vchar_t *msg0; { vchar_t *pbuf = NULL; @@ -621,71 +839,84 @@ ident_i4recv(iph1, msg0) vchar_t *msg = NULL; int error = -1; int type; -#ifdef HAVE_GSSAPI - vchar_t *gsstoken = NULL; -#endif + int vid_numeric; + int received_cert = 0; - /* validity check */ - if (iph1->status != PHASE1ST_MSG3SENT) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_IDENT_I_MSG5SENT) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } /* decrypting */ if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "expecting the packet encrypted.\n"); goto end; } msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(ASL_LEVEL_ERR, + "failed to decrypt"); goto end; + } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to parse msg"); goto end; + } iph1->pl_hash = NULL; - for (pa = (struct isakmp_parse_t *)pbuf->v; + for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; pa++) { switch (pa->type) { case ISAKMP_NPTYPE_ID: - if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process ID payload"); goto end; + } break; case ISAKMP_NPTYPE_HASH: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; break; case ISAKMP_NPTYPE_CERT: - if (oakley_savecert(iph1, pa->ptr) < 0) + if (oakley_savecert(iph1, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process CERT payload"); goto end; + } + received_cert = 1; break; case ISAKMP_NPTYPE_SIG: - if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process SIG payload"); goto end; + } break; -#ifdef HAVE_GSSAPI - case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) - goto end; - gssapi_save_received_token(iph1, gsstoken); - break; -#endif + case ISAKMP_NPTYPE_VID: - (void)check_vendorid(pa->ptr); - break; + vid_numeric = check_vendorid(pa->ptr); +#ifdef ENABLE_DPD + if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) + iph1->dpd_support=1; +#endif + break; case ISAKMP_NPTYPE_N: isakmp_check_notify(pa->ptr, iph1); break; default: /* don't send information, see ident_r1recv() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -693,41 +924,45 @@ ident_i4recv(iph1, msg0) } } + if (received_cert) { + oakley_verify_certid(iph1); + } + /* payload existency check */ /* verify identifier */ if (ipsecdoi_checkid1(iph1) != 0) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "invalid ID payload.\n"); goto end; } /* validate authentication value */ -#ifdef HAVE_GSSAPI - if (gsstoken == NULL) { -#endif - type = oakley_validate_auth(iph1); - if (type != 0) { - if (type == -1) { - /* msg printed inner oakley_validate_auth() */ - goto end; - } - EVT_PUSH(iph1->local, iph1->remote, - EVTT_PEERPH1AUTH_FAILED, NULL); - isakmp_info_send_n1(iph1, type, NULL); - goto end; - } -#ifdef HAVE_GSSAPI - } -#endif + type = oakley_validate_auth(iph1); + if (type != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Initiator, Main-Mode Message 6"), + CONSTSTR("Failed to authenticate Main-Mode Message 6")); + if (type == -1) { + /* msg printed inner oakley_validate_auth() */ + goto end; + } + isakmp_info_send_n1(iph1, type, NULL); + goto end; + } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Initiator, Main-Mode Message 6"), + CONSTSTR(NULL)); + /* * XXX: Should we do compare two addresses, ph1handle's and ID * payload's. */ - plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID:"); - plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l); + plogdump(ASL_LEVEL_DEBUG, iph1->id_p->v, iph1->id_p->l, "peer's ID:"); /* see handler.h about IV synchronization. */ memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l); @@ -735,24 +970,26 @@ ident_i4recv(iph1, msg0) /* * If we got a GSS token, we need to this roundtrip again. */ -#ifdef HAVE_GSSAPI - iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED : - PHASE1ST_MSG4RECEIVED; -#else - iph1->status = PHASE1ST_MSG4RECEIVED; -#endif + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_MSG6RCVD); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Main-Mode message 6"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Main-Mode Message 6"), + CONSTSTR("Failed to transmit Main-Mode Message 6")); + } if (pbuf) vfree(pbuf); if (msg) vfree(msg); -#ifdef HAVE_GSSAPI - if (gsstoken) - vfree(gsstoken); -#endif if (error) { VPTRINIT(iph1->id_p); @@ -770,24 +1007,29 @@ end: * status update and establish isakmp sa. */ int -ident_i4send(iph1, msg) - struct ph1handle *iph1; +ident_ifinalize(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { int error = -1; - /* validity check */ - if (iph1->status != PHASE1ST_MSG4RECEIVED) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_IDENT_I_MSG6RCVD) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } /* see handler.h about IV synchronization. */ memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l); - iph1->status = PHASE1ST_ESTABLISHED; + fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_ESTABLISHED); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC, + CONSTSTR("Initiator, Main-Mode"), + CONSTSTR(NULL)); + error = 0; end: @@ -803,7 +1045,7 @@ end: */ int ident_r1recv(iph1, msg) - struct ph1handle *iph1; + phase1_handle_t *iph1; vchar_t *msg; { vchar_t *pbuf = NULL; @@ -812,8 +1054,8 @@ ident_r1recv(iph1, msg) int vid_numeric; /* validity check */ - if (iph1->status != PHASE1ST_START) { - plog(LLV_ERROR, LOCATION, NULL, + if (iph1->status != IKEV1_STATE_IDENT_R_START) { + plog(ASL_LEVEL_ERR, "status mismatched %d.\n", iph1->status); goto end; } @@ -823,20 +1065,26 @@ ident_r1recv(iph1, msg) * NOTE: XXX even if multiple VID, we'll silently ignore those. */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to parse msg"); goto end; - pa = (struct isakmp_parse_t *)pbuf->v; + } + pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; /* check the position of SA payload */ if (pa->type != ISAKMP_NPTYPE_SA) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "received invalid next payload type %d, " "expecting %d.\n", pa->type, ISAKMP_NPTYPE_SA); goto end; } - if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process SA payload"); goto end; + } pa++; for (/*nothing*/; @@ -850,9 +1098,33 @@ ident_r1recv(iph1, msg) if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric)) natt_handle_vendorid(iph1, vid_numeric); #endif +#ifdef ENABLE_HYBRID + switch (vid_numeric) { + case VENDORID_XAUTH: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_XAUTH; + break; + + case VENDORID_UNITY: + iph1->mode_cfg->flags |= + ISAKMP_CFG_VENDORID_UNITY; + break; + + default: + break; + } +#endif #ifdef ENABLE_DPD if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) iph1->dpd_support=1; +#endif +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT)) { + plog(ASL_LEVEL_DEBUG, + "remote supports FRAGMENTATION\n"); + iph1->frag = 1; + } #endif break; default: @@ -863,7 +1135,7 @@ ident_r1recv(iph1, msg) * the re-sent packet. And we do same behavior * when we expect encrypted packet. */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -872,25 +1144,38 @@ ident_r1recv(iph1, msg) } #ifdef ENABLE_NATT - if (NATT_AVAILABLE(iph1)) - plog(LLV_INFO, LOCATION, iph1->remote, + if (NATT_AVAILABLE(iph1)) { + plog(ASL_LEVEL_NOTICE, "Selected NAT-T version: %s\n", vid_string_by_id(iph1->natt_options->version)); + ike_session_update_natt_version(iph1); + } #endif /* check SA payload and set approval SA for use */ if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "failed to get valid proposal.\n"); /* XXX send information */ goto end; } - iph1->status = PHASE1ST_MSG1RECEIVED; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_R_MSG1RCVD); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Main-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Main-Mode Message 1"), + CONSTSTR("Failed to process Main-Mode Message 1")); + } if (pbuf) vfree(pbuf); if (error) { @@ -908,45 +1193,63 @@ end: * rev: HDR, SA */ int -ident_r1send(iph1, msg) - struct ph1handle *iph1; +ident_r2send(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { struct payload_list *plist = NULL; int error = -1; vchar_t *gss_sa = NULL; - vchar_t *vid = NULL; #ifdef ENABLE_NATT vchar_t *vid_natt = NULL; #endif +#ifdef ENABLE_HYBRID + vchar_t *vid_xauth = NULL; + vchar_t *vid_unity = NULL; +#endif #ifdef ENABLE_DPD vchar_t *vid_dpd = NULL; #endif +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; +#endif /* validity check */ - if (iph1->status != PHASE1ST_MSG1RECEIVED) { - plog(LLV_ERROR, LOCATION, NULL, + if (iph1->status != IKEV1_STATE_IDENT_R_MSG1RCVD) { + plog(ASL_LEVEL_ERR, "status mismatched %d.\n", iph1->status); goto end; } /* set responder's cookie */ isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); - -#ifdef HAVE_GSSAPI - if (iph1->approval->gssid != NULL) - gss_sa = ipsecdoi_setph1proposal(iph1->approval); - else -#endif - gss_sa = iph1->sa_ret; + gss_sa = iph1->sa_ret; /* set SA payload to reply */ plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA); - /* Set Vendor ID, if necessary. */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); +#ifdef ENABLE_HYBRID + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (ASL_LEVEL_NOTICE, "Adding xauth VID payload.\n"); + if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) { + plog(ASL_LEVEL_ERR, + "Cannot create Xauth vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_xauth, ISAKMP_NPTYPE_VID); + } + if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { + if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) { + plog(ASL_LEVEL_ERR, + "Cannot create Unity vendor ID\n"); + goto end; + } + plist = isakmp_plist_append(plist, + vid_unity, ISAKMP_NPTYPE_VID); + } +#endif #ifdef ENABLE_NATT /* Has the peer announced NAT-T? */ if (NATT_AVAILABLE(iph1)) @@ -963,6 +1266,20 @@ ident_r1send(iph1, msg) plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); } #endif +#ifdef ENABLE_FRAG + if (iph1->frag) { + vid_frag = set_vendorid(VENDORID_FRAG); + if (vid_frag != NULL) + vid_frag = isakmp_frag_addcap(vid_frag, + VENDORID_FRAG_IDENT); + if (vid_frag == NULL) + plog(ASL_LEVEL_ERR, + "Frag vendorID construction failed\n"); + else + plist = isakmp_plist_append(plist, + vid_frag, ISAKMP_NPTYPE_VID); + } +#endif iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); @@ -972,17 +1289,21 @@ ident_r1send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(ASL_LEVEL_ERR, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { - plog(LLV_ERROR , LOCATION, NULL, + if (ike_session_add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1, iph1->sendbuf), PH1_FRAG_FLAGS(iph1)) == -1) { + plog(ASL_LEVEL_ERR , "failed to add a response packet to the tree.\n"); goto end; } - iph1->status = PHASE1ST_MSG1SENT; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_R_MSG2SENT); #ifdef ENABLE_VPNCONTROL_PORT vpncontrol_notify_phase_change(1, FROM_LOCAL, iph1, NULL); @@ -990,22 +1311,36 @@ ident_r1send(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Main-Mode message 2"), + CONSTSTR(NULL)); + end: -#ifdef HAVE_GSSAPI - if (gss_sa != iph1->sa_ret) - vfree(gss_sa); -#endif - if (vid) - vfree(vid); - + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Main-Mode Message 2"), + CONSTSTR("Failed to transmit Main-Mode Message 2")); + } #ifdef ENABLE_NATT if (vid_natt) vfree(vid_natt); #endif +#ifdef ENABLE_HYBRID + if (vid_xauth != NULL) + vfree(vid_xauth); + if (vid_unity != NULL) + vfree(vid_unity); +#endif #ifdef ENABLE_DPD if (vid_dpd != NULL) vfree(vid_dpd); #endif +#ifdef ENABLE_FRAG + if (vid_frag != NULL) + vfree(vid_frag); +#endif return error; } @@ -1020,74 +1355,74 @@ end: * Ke_i, [<Ke_i] */ int -ident_r2recv(iph1, msg) - struct ph1handle *iph1; +ident_r3recv(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { vchar_t *pbuf = NULL; struct isakmp_parse_t *pa; int error = -1; -#ifdef HAVE_GSSAPI - vchar_t *gsstoken = NULL; -#endif #ifdef ENABLE_NATT int natd_seq = 0; #endif /* validity check */ - if (iph1->status != PHASE1ST_MSG1SENT) { - plog(LLV_ERROR, LOCATION, NULL, + if (iph1->status != IKEV1_STATE_IDENT_R_MSG2SENT) { + plog(ASL_LEVEL_ERR, "status mismatched %d.\n", iph1->status); goto end; } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to parse msg"); goto end; + } - for (pa = (struct isakmp_parse_t *)pbuf->v; + for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; pa++) { switch (pa->type) { case ISAKMP_NPTYPE_KE: - if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process KE payload"); goto end; + } break; case ISAKMP_NPTYPE_NONCE: - if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process NONCE payload"); goto end; + } break; case ISAKMP_NPTYPE_VID: (void)check_vendorid(pa->ptr); break; case ISAKMP_NPTYPE_CR: - plog(LLV_WARNING, LOCATION, iph1->remote, + plog(ASL_LEVEL_WARNING, "CR received, ignore it. " "It should be in other exchange.\n"); break; -#ifdef HAVE_GSSAPI - case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) - goto end; - gssapi_save_received_token(iph1, gsstoken); - break; -#endif #ifdef ENABLE_NATT case ISAKMP_NPTYPE_NATD_DRAFT: case ISAKMP_NPTYPE_NATD_RFC: -#ifdef __APPLE__ case ISAKMP_NPTYPE_NATD_BADDRAFT: -#endif if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL && pa->type == iph1->natt_options->payload_nat_d) { vchar_t *natd_received = NULL; int natd_verified; - if (isakmp_p2ph (&natd_received, pa->ptr) < 0) + if (isakmp_p2ph (&natd_received, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process NATD payload"); goto end; + } if (natd_seq == 0) iph1->natt_flags |= NAT_DETECTED; @@ -1095,7 +1430,7 @@ ident_r2recv(iph1, msg) natd_verified = natt_compare_addr_hash (iph1, natd_received, natd_seq++); - plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n", + plog (ASL_LEVEL_NOTICE, "NAT-D payload #%d %s\n", natd_seq - 1, natd_verified ? "verified" : "doesn't match"); @@ -1109,7 +1444,7 @@ ident_r2recv(iph1, msg) default: /* don't send information, see ident_r1recv() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -1119,7 +1454,7 @@ ident_r2recv(iph1, msg) #ifdef ENABLE_NATT if (NATT_AVAILABLE(iph1)) - plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n", + plog (ASL_LEVEL_NOTICE, "NAT %s %s%s\n", iph1->natt_flags & NAT_DETECTED ? "detected:" : "not detected", iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "", @@ -1128,22 +1463,29 @@ ident_r2recv(iph1, msg) /* payload existency check */ if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "few isakmp message received.\n"); goto end; } - iph1->status = PHASE1ST_MSG2RECEIVED; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_R_MSG3RCVD); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Main-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Main-Mode Message 3"), + CONSTSTR("Failed to process Main-Mode Message 3")); + } if (pbuf) vfree(pbuf); -#ifdef HAVE_GSSAPI - if (gsstoken) - vfree(gsstoken); -#endif if (error) { VPTRINIT(iph1->dhpub_p); @@ -1163,38 +1505,47 @@ end: * rev: HDR, PubKey_i, Ke_r, Ke_r, */ int -ident_r2send(iph1, msg) - struct ph1handle *iph1; +ident_r4send(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { int error = -1; /* validity check */ - if (iph1->status != PHASE1ST_MSG2RECEIVED) { - plog(LLV_ERROR, LOCATION, NULL, + if (iph1->status != IKEV1_STATE_IDENT_R_MSG3RCVD) { + plog(ASL_LEVEL_ERR, "status mismatched %d.\n", iph1->status); goto end; } /* generate DH public value */ +#ifdef HAVE_OPENSSL if (oakley_dh_generate(iph1->approval->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { +#else + if (oakley_dh_generate(iph1->approval->dhgrp, + &iph1->dhpub, &iph1->publicKeySize, &iph1->dhC) < 0) { +#endif + plog(ASL_LEVEL_ERR, + "failed to generate DH"); goto end; + } /* generate NONCE value */ iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); - if (iph1->nonce == NULL) + if (iph1->nonce == NULL) { + plog(ASL_LEVEL_ERR, + "failed to generate NONCE"); goto end; - -#ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) - gssapi_get_rtoken(iph1, NULL); -#endif + } /* create HDR;KE;NONCE payload */ iph1->sendbuf = ident_ir2mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to allocate send buffer"); goto end; + } #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); @@ -1202,36 +1553,70 @@ ident_r2send(iph1, msg) /* send the packet, add to the schedule to resend */ iph1->retry_counter = iph1->rmconf->retry_counter; - if (isakmp_ph1resend(iph1) == -1) + if (isakmp_ph1resend(iph1) == -1) { + plog(ASL_LEVEL_ERR, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { - plog(LLV_ERROR , LOCATION, NULL, + if (ike_session_add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1, iph1->sendbuf), PH1_FRAG_FLAGS(iph1)) == -1) { + plog(ASL_LEVEL_ERR , "failed to add a response packet to the tree.\n"); goto end; } /* compute sharing secret of DH */ - if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, - iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) +#ifdef HAVE_OPENSSL + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, + iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) { +#else + if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub_p, iph1->publicKeySize, &iph1->dhgxy, &iph1->dhC) < 0) { +#endif + plog(ASL_LEVEL_ERR, + "failed to compute DH"); goto end; + } /* generate SKEYIDs & IV & final cipher key */ - if (oakley_skeyid(iph1) < 0) + if (oakley_skeyid(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate SKEYID"); goto end; - if (oakley_skeyid_dae(iph1) < 0) + } + if (oakley_skeyid_dae(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate SKEYID-DAE"); goto end; - if (oakley_compute_enckey(iph1) < 0) + } + if (oakley_compute_enckey(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate ENCKEY"); goto end; - if (oakley_newiv(iph1) < 0) + } + if (oakley_newiv(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to generate IV"); goto end; + } - iph1->status = PHASE1ST_MSG2SENT; + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_R_MSG4SENT); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Main-Mode message 4"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Main-Mode Message 4"), + CONSTSTR("Failed to transmit Main-Mode Message 4")); + } return error; } @@ -1244,8 +1629,8 @@ end: * rev: HDR*, HASH_I */ int -ident_r3recv(iph1, msg0) - struct ph1handle *iph1; +ident_r5recv(iph1, msg0) + phase1_handle_t *iph1; vchar_t *msg0; { vchar_t *msg = NULL; @@ -1253,66 +1638,76 @@ ident_r3recv(iph1, msg0) struct isakmp_parse_t *pa; int error = -1; int type; -#ifdef HAVE_GSSAPI - vchar_t *gsstoken = NULL; -#endif + int received_cert = 0; /* validity check */ - if (iph1->status != PHASE1ST_MSG2SENT) { - plog(LLV_ERROR, LOCATION, NULL, + if (iph1->status != IKEV1_STATE_IDENT_R_MSG4SENT) { + plog(ASL_LEVEL_ERR, "status mismatched %d.\n", iph1->status); goto end; } /* decrypting */ if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "reject the packet, " "expecting the packet encrypted.\n"); goto end; } msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive); - if (msg == NULL) + if (msg == NULL) { + plog(ASL_LEVEL_ERR, + "failed to decrypt"); goto end; + } /* validate the type of next payload */ pbuf = isakmp_parse(msg); - if (pbuf == NULL) + if (pbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to parse msg"); goto end; + } iph1->pl_hash = NULL; - for (pa = (struct isakmp_parse_t *)pbuf->v; + for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; pa->type != ISAKMP_NPTYPE_NONE; pa++) { switch (pa->type) { case ISAKMP_NPTYPE_ID: - if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process ID payload"); goto end; + } break; case ISAKMP_NPTYPE_HASH: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; break; case ISAKMP_NPTYPE_CR: - if (oakley_savecr(iph1, pa->ptr) < 0) + if (oakley_savecr(iph1, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process CR payload"); goto end; + } break; case ISAKMP_NPTYPE_CERT: - if (oakley_savecert(iph1, pa->ptr) < 0) + if (oakley_savecert(iph1, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process CERT payload"); goto end; + } + received_cert = 1; break; case ISAKMP_NPTYPE_SIG: - if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) - goto end; - break; -#ifdef HAVE_GSSAPI - case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process SIG payload"); goto end; - gssapi_save_received_token(iph1, gsstoken); + } break; -#endif case ISAKMP_NPTYPE_VID: (void)check_vendorid(pa->ptr); break; @@ -1321,7 +1716,7 @@ ident_r3recv(iph1, msg0) break; default: /* don't send information, see ident_r1recv() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -1329,40 +1724,48 @@ ident_r3recv(iph1, msg0) } } + if (received_cert) { + oakley_verify_certid(iph1); + } + /* payload existency check */ /* XXX same as ident_i4recv(), should be merged. */ { int ng = 0; - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: +#endif if (iph1->id_p == NULL || iph1->pl_hash == NULL) ng++; break; - case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: +#endif if (iph1->id_p == NULL || iph1->sig_p == NULL) ng++; break; case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif if (iph1->pl_hash == NULL) ng++; break; -#ifdef HAVE_GSSAPI - case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: - if (gsstoken == NULL && iph1->pl_hash == NULL) - ng++; - break; -#endif default: - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "invalid authmethod %d why ?\n", iph1->approval->authmethod); goto end; } if (ng) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "few isakmp message received.\n"); goto end; } @@ -1370,29 +1773,30 @@ ident_r3recv(iph1, msg0) /* verify identifier */ if (ipsecdoi_checkid1(iph1) != 0) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "invalid ID payload.\n"); goto end; } /* validate authentication value */ -#ifdef HAVE_GSSAPI - if (gsstoken == NULL) { -#endif - type = oakley_validate_auth(iph1); - if (type != 0) { - if (type == -1) { - /* msg printed inner oakley_validate_auth() */ - goto end; - } - EVT_PUSH(iph1->local, iph1->remote, - EVTT_PEERPH1AUTH_FAILED, NULL); - isakmp_info_send_n1(iph1, type, NULL); - goto end; - } -#ifdef HAVE_GSSAPI - } -#endif + + type = oakley_validate_auth(iph1); + if (type != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Responder, Main-Mode Message 5"), + CONSTSTR("Failed to authenticate Main-Mode Message 5")); + if (type == -1) { + /* msg printed inner oakley_validate_auth() */ + goto end; + } + isakmp_info_send_n1(iph1, type, NULL); + goto end; + } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Responder, Main-Mode Message 5"), + CONSTSTR(NULL)); if (oakley_checkcr(iph1) < 0) { /* Ignore this error in order to be interoperability. */ @@ -1404,30 +1808,30 @@ ident_r3recv(iph1, msg0) * payload's. */ - plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID\n"); - plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l); + plogdump(ASL_LEVEL_DEBUG, iph1->id_p->v, iph1->id_p->l, "peer's ID\n"); /* see handler.h about IV synchronization. */ memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l); -#ifdef HAVE_GSSAPI - iph1->status = gsstoken != NULL ? PHASE1ST_MSG2RECEIVED : - PHASE1ST_MSG3RECEIVED; -#else - iph1->status = PHASE1ST_MSG3RECEIVED; -#endif - + fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_R_MSG5RCVD); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Main-Mode message 5"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Main-Mode Message 5"), + CONSTSTR("Failed to process Main-Mode Message 5")); + } if (pbuf) vfree(pbuf); if (msg) vfree(msg); -#ifdef HAVE_GSSAPI - if (gsstoken) - vfree(gsstoken); -#endif if (error) { VPTRINIT(iph1->id_p); @@ -1452,42 +1856,36 @@ end: * rev: HDR*, HASH_R */ int -ident_r3send(iph1, msg) - struct ph1handle *iph1; +ident_r6send(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { int error = -1; int dohash = 1; -#ifdef HAVE_GSSAPI - int len; -#endif /* validity check */ - if (iph1->status != PHASE1ST_MSG3RECEIVED) { - plog(LLV_ERROR, LOCATION, NULL, + if (iph1->status != IKEV1_STATE_IDENT_R_MSG5RCVD) { + plog(ASL_LEVEL_ERR, "status mismatched %d.\n", iph1->status); goto end; } /* make ID payload into isakmp status */ - if (ipsecdoi_setid1(iph1) < 0) + if (ipsecdoi_setid1(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to set ID"); goto end; - -#ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB && - gssapi_more_tokens(iph1)) { - gssapi_get_rtoken(iph1, &len); - if (len != 0) - dohash = 0; } -#endif if (dohash) { /* generate HASH to send */ - plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n"); + plog(ASL_LEVEL_DEBUG, "generate HASH_R\n"); iph1->hash = oakley_ph1hash_common(iph1, GENERATE); - if (iph1->hash == NULL) + if (iph1->hash == NULL) { + plog(ASL_LEVEL_ERR, + "failed to generate HASH"); goto end; + } } else iph1->hash = NULL; @@ -1496,16 +1894,23 @@ ident_r3send(iph1, msg) /* create HDR;ID;HASH payload */ iph1->sendbuf = ident_ir3mx(iph1); - if (iph1->sendbuf == NULL) + if (iph1->sendbuf == NULL) { + plog(ASL_LEVEL_ERR, + "failed to create send buffer"); goto end; + } /* send HDR;ID;HASH to responder */ - if (isakmp_send(iph1, iph1->sendbuf) < 0) + if (isakmp_send(iph1, iph1->sendbuf) < 0) { + plog(ASL_LEVEL_ERR, + "failed to send packet"); goto end; + } /* the sending message is added to the received-list. */ - if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { - plog(LLV_ERROR , LOCATION, NULL, + if (ike_session_add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg, + PH1_NON_ESP_EXTRA_LEN(iph1, iph1->sendbuf), PH1_FRAG_FLAGS(iph1)) == -1) { + plog(ASL_LEVEL_ERR , "failed to add a response packet to the tree.\n"); goto end; } @@ -1513,11 +1918,27 @@ ident_r3send(iph1, msg) /* see handler.h about IV synchronization. */ memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l); - iph1->status = PHASE1ST_ESTABLISHED; + fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_ESTABLISHED); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC, + CONSTSTR("Responder, Main-Mode"), + CONSTSTR(NULL)); + error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Main-Mode message 6"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Main-Mode Message 6"), + CONSTSTR("Failed to process Main-Mode Message 6")); + } return error; } @@ -1538,7 +1959,7 @@ end: */ static vchar_t * ident_ir2mx(iph1) - struct ph1handle *iph1; + phase1_handle_t *iph1; { vchar_t *buf = 0; struct payload_list *plist = NULL; @@ -1546,9 +1967,6 @@ ident_ir2mx(iph1) vchar_t *cr = NULL; vchar_t *vid = NULL; int error = -1; -#ifdef HAVE_GSSAPI - vchar_t *gsstoken = NULL; -#endif #ifdef ENABLE_NATT vchar_t *natd[2] = { NULL, NULL }; #endif @@ -1556,33 +1974,22 @@ ident_ir2mx(iph1) /* create CR if need */ if (iph1->side == RESPONDER && iph1->rmconf->send_cr - && oakley_needcr(iph1->approval->authmethod) - && iph1->rmconf->peerscertfile == NULL) { + && oakley_needcr(iph1->approval->authmethod)) { need_cr = 1; cr = oakley_getcr(iph1); if (cr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get cr buffer.\n"); goto end; } } -#ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) - gssapi_get_token_to_send(iph1, &gsstoken); -#endif - /* create isakmp KE payload */ plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE); /* create isakmp NONCE payload */ plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE); -#ifdef HAVE_GSSAPI - if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) - plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); -#endif - /* append vendor id, if needed */ if (vid) plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); @@ -1593,28 +2000,26 @@ ident_ir2mx(iph1) #ifdef ENABLE_NATT /* generate and append NAT-D payloads */ - if (NATT_AVAILABLE(iph1) && iph1->status == PHASE1ST_MSG2RECEIVED) + if (NATT_AVAILABLE(iph1)) { if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "NAT-D hashing failed for %s\n", saddr2str(iph1->remote)); + plog(ASL_LEVEL_ERR, + "NAT-D hashing failed for %s\n", saddr2str((struct sockaddr *)iph1->remote)); goto end; } if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "NAT-D hashing failed for %s\n", saddr2str(iph1->local)); + plog(ASL_LEVEL_ERR, + "NAT-D hashing failed for %s\n", saddr2str((struct sockaddr *)iph1->local)); goto end; } - plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); -#ifdef __APPLE__ + plog (ASL_LEVEL_NOTICE, "Adding remote and local NAT-D payloads.\n"); /* old Apple version sends natd payloads in the wrong order */ if (iph1->natt_options->version == VENDORID_NATT_APPLE) { plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d); plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d); } else -#endif { plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d); plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d); @@ -1633,10 +2038,6 @@ end: } if (cr) vfree(cr); -#ifdef HAVE_GSSAPI - if (gsstoken) - vfree(gsstoken); -#endif if (vid) vfree(vid); @@ -1667,7 +2068,7 @@ end: */ static vchar_t * ident_ir3mx(iph1) - struct ph1handle *iph1; + phase1_handle_t *iph1; { struct payload_list *plist = NULL; vchar_t *buf = NULL, *new = NULL; @@ -1675,38 +2076,48 @@ ident_ir3mx(iph1) int need_cert = 0; vchar_t *cr = NULL; int error = -1; -#ifdef HAVE_GSSAPI - int nptype; - vchar_t *gsstoken = NULL; - vchar_t *gsshash = NULL; -#endif + vchar_t *notp_ini = NULL; - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: +#endif /* create isakmp ID payload */ plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); /* create isakmp HASH payload */ plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); break; - case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: - if (oakley_getmycert(iph1) < 0) +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: +#endif + if (oakley_getmycert(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to get mycert"); goto end; + } - if (oakley_getsign(iph1) < 0) + if (oakley_getsign(iph1) < 0) { + plog(ASL_LEVEL_ERR, + "failed to get sign"); goto end; + } /* create CR if need */ if (iph1->side == INITIATOR && iph1->rmconf->send_cr - && oakley_needcr(iph1->approval->authmethod) - && iph1->rmconf->peerscertfile == NULL) { + && oakley_needcr(iph1->approval->authmethod)) { need_cr = 1; cr = oakley_getcr(iph1); if (cr == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to get cr buffer.\n"); + plog(ASL_LEVEL_ERR, + "failed to get CR"); goto end; } } @@ -1718,6 +2129,7 @@ ident_ir3mx(iph1) plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); /* add CERT payload if there */ + // we don't support sending of certchains if (need_cert) plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT); /* add SIG payload */ @@ -1727,42 +2139,30 @@ ident_ir3mx(iph1) if (need_cr) plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR); break; -#ifdef HAVE_GSSAPI - case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: - if (iph1->hash != NULL) { - gsshash = gssapi_wraphash(iph1); - if (gsshash == NULL) - goto end; - } else { - gssapi_get_token_to_send(iph1, &gsstoken); - } - if (!gssapi_id_sent(iph1)) { - /* create isakmp ID payload */ - plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); - gssapi_set_id_sent(iph1); - } - - if (iph1->hash != NULL) - /* create isakmp HASH payload */ - plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); - else - plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); - break; -#endif case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: - plog(LLV_ERROR, LOCATION, NULL, +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: +#endif + plog(ASL_LEVEL_ERR, "not supported authentication type %d\n", iph1->approval->authmethod); goto end; default: - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "invalid authentication type %d\n", iph1->approval->authmethod); goto end; } + if (iph1->side == INITIATOR) { + notp_ini = isakmp_plist_append_initial_contact(iph1, plist); + } + buf = isakmp_plist_set_all (&plist, iph1); #ifdef HAVE_PRINT_ISAKMP_C @@ -1771,8 +2171,11 @@ ident_ir3mx(iph1) /* encoding */ new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv); - if (new == NULL) + if (new == NULL) { + plog(ASL_LEVEL_ERR, + "failed to encrypt"); goto end; + } vfree(buf); @@ -1787,6 +2190,8 @@ end: vfree(buf); buf = NULL; } + if (notp_ini) + vfree(notp_ini); return buf; }