X-Git-Url: https://git.saurik.com/apple/ipsec.git/blobdiff_plain/52b7d2ce06d68d0a9160d16f6e7c08c21c149d0d..7685aad60c1b188a3f84904e9b609a7438e833c9:/ipsec-tools/racoon/isakmp_agg.c diff --git a/ipsec-tools/racoon/isakmp_agg.c b/ipsec-tools/racoon/isakmp_agg.c index eea7726..13bf4d3 100644 --- a/ipsec-tools/racoon/isakmp_agg.c +++ b/ipsec-tools/racoon/isakmp_agg.c @@ -1,4 +1,6 @@ -/* $Id: isakmp_agg.c,v 1.20.2.5 2005/11/21 09:46:23 vanhu Exp $ */ +/* $NetBSD: isakmp_agg.c,v 1.9 2006/09/30 21:49:37 manu Exp $ */ + +/* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -59,11 +61,11 @@ #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" @@ -85,12 +87,13 @@ #include "nattraversal.h" #endif -#ifdef HAVE_GSSAPI -#include "gssapi.h" -#endif - #include "vpn_control.h" #include "vpn_control_var.h" +#include "ipsecSessionTracer.h" +#include "ipsecMessageTracer.h" +#ifndef HAVE_OPENSSL +#include +#endif /* * begin Aggressive Mode as initiator. @@ -106,12 +109,12 @@ */ int agg_i1send(iph1, msg) - struct ph1handle *iph1; + phase1_handle_t *iph1; vchar_t *msg; /* must be null */ { struct payload_list *plist = NULL; int need_cr = 0; - vchar_t *cr = NULL, *gsstoken = NULL; + vchar_t *cr = NULL; int error = -1; #ifdef ENABLE_NATT vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL }; @@ -124,66 +127,84 @@ agg_i1send(iph1, msg) #ifdef ENABLE_FRAG vchar_t *vid_frag = NULL; #endif -#ifdef HAVE_GSSAPI - int len; -#endif #ifdef ENABLE_DPD vchar_t *vid_dpd = NULL; #endif + /* validity check */ + if (iph1->status != IKEV1_STATE_AGG_I_START) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); + goto end; + } /* validity check */ if (msg != NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "msg has to be NULL in this function.\n"); goto end; } - if (iph1->status != PHASE1ST_START) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); - goto end; - } /* create isakmp index */ memset(&iph1->index, 0, sizeof(iph1->index)); isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); /* 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; + } /* 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; + } /* consistency check of proposals */ if (iph1->rmconf->dhgrp == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "configuration failure about DH group.\n"); goto end; } /* generate DH public value */ +#ifdef HAVE_OPENSSL if (oakley_dh_generate(iph1->rmconf->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { +#else + if (oakley_dh_generate(iph1->rmconf->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 ENABLE_HYBRID /* Do we need Xauth VID? */ - switch (iph1->rmconf->proposal->authmethod) { - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + 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(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "Xauth vendor ID generation failed\n"); if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "Unity vendor ID generation failed\n"); break; default: @@ -198,32 +219,25 @@ agg_i1send(iph1, msg) vid_frag = isakmp_frag_addcap(vid_frag, VENDORID_FRAG_AGG); if (vid_frag == NULL) - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "Frag vendorID construction failed\n"); } #endif /* create CR if need */ if (iph1->rmconf->send_cr - && oakley_needcr(iph1->rmconf->proposal->authmethod) - && iph1->rmconf->peerscertfile == NULL) { + && oakley_needcr(iph1->rmconf->proposal->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; } } - plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n", + plog(ASL_LEVEL_DEBUG, "authmethod is %s\n", s_oakley_attr_method(iph1->rmconf->proposal->authmethod)); -#ifdef HAVE_GSSAPI - if (iph1->rmconf->proposal->authmethod == - OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { - gssapi_get_itoken(iph1, &len); - } -#endif /* set SA payload to propose */ plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA); @@ -237,13 +251,6 @@ agg_i1send(iph1, msg) /* create isakmp ID payload */ plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); -#ifdef HAVE_GSSAPI - if (iph1->rmconf->proposal->authmethod == - OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { - gssapi_get_token_to_send(iph1, &gsstoken); - plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); - } else -#endif /* create isakmp CR payload */ if (need_cr) plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR); @@ -284,18 +291,30 @@ agg_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_AGG_I_MSG1SENT); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Aggressive-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 1"), + CONSTSTR("Failed to transmit Aggressive-Mode Message 1")); + } if (cr) vfree(cr); - if (gsstoken) - vfree(gsstoken); #ifdef ENABLE_FRAG if (vid_frag) vfree(vid_frag); @@ -304,16 +323,16 @@ end: for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++) vfree(vid_natt[i]); #endif -#ifdef ENABLE_DPD - if (vid_dpd != NULL) - vfree(vid_dpd); -#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 return error; } @@ -328,7 +347,7 @@ end: */ int agg_i2recv(iph1, msg) - struct ph1handle *iph1; + phase1_handle_t *iph1; vchar_t *msg; { vchar_t *pbuf = NULL; @@ -337,13 +356,7 @@ agg_i2recv(iph1, msg) int error = -1; int vid_numeric; int ptype; -#ifdef ENABLE_HYBRID - vchar_t *unity_vid; - vchar_t *xauth_vid; -#endif -#ifdef HAVE_GSSAPI - vchar_t *gsstoken = NULL; -#endif + int received_cert = 0; #ifdef ENABLE_NATT int natd_seq = 0; @@ -356,32 +369,38 @@ agg_i2recv(iph1, msg) TAILQ_INIT(&natd_tree); #endif - /* 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_AGG_I_MSG1SENT) { + 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; - pa = (struct isakmp_parse_t *)pbuf->v; + } + pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; iph1->pl_hash = NULL; /* 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*/; @@ -390,31 +409,50 @@ agg_i2recv(iph1, msg) 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_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) + if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process SIG payload"); goto end; + } break; case ISAKMP_NPTYPE_VID: vid_numeric = check_vendorid(pa->ptr); @@ -441,39 +479,45 @@ agg_i2recv(iph1, msg) #ifdef ENABLE_DPD if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) { iph1->dpd_support=1; - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_DEBUG, "remote supports DPD\n"); } +#endif +#ifdef ENABLE_FRAG + if ((vid_numeric == VENDORID_FRAG) && + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG)) { + plog(ASL_LEVEL_DEBUG, + "remote supports FRAGMENTATION\n"); + iph1->frag = 1; + } #endif break; case ISAKMP_NPTYPE_N: isakmp_check_notify(pa->ptr, iph1); 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) { struct natd_payload *natd; natd = (struct natd_payload *)racoon_malloc(sizeof(*natd)); - if (!natd) + if (!natd) { + plog(ASL_LEVEL_ERR, + "failed to pre-process NATD payload"); goto end; + } natd->payload = NULL; - if (isakmp_p2ph (&natd->payload, pa->ptr) < 0) + if (isakmp_p2ph (&natd->payload, pa->ptr) < 0) { + plog(ASL_LEVEL_ERR, + "failed to process NATD payload"); + racoon_free(natd); goto end; + } natd->seq = natd_seq++; @@ -487,7 +531,7 @@ agg_i2recv(iph1, msg) default: /* don't send information, see isakmp_ident_r1() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -495,23 +539,27 @@ agg_i2recv(iph1, msg) } } + if (received_cert) { + oakley_verify_certid(iph1); + } + /* 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; } /* verify identifier */ if (ipsecdoi_checkid1(iph1) != 0) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "invalid ID payload.\n"); goto end; } /* 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; @@ -527,7 +575,7 @@ agg_i2recv(iph1, msg) struct natd_payload *natd = NULL; int natd_verified; - plog(LLV_INFO, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "Selected NAT-T version: %s\n", vid_string_by_id(iph1->natt_options->version)); @@ -541,7 +589,7 @@ agg_i2recv(iph1, msg) natd_verified = natt_compare_addr_hash (iph1, natd->payload, 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"); @@ -551,7 +599,7 @@ agg_i2recv(iph1, msg) racoon_free (natd); } - 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 " : "", @@ -559,44 +607,70 @@ agg_i2recv(iph1, msg) if (iph1->natt_flags & NAT_DETECTED) natt_float_ports (iph1); + ike_session_update_natt_version(iph1); } #endif /* compute sharing secret of DH */ +#ifdef HAVE_OPENSSL if (oakley_dh_compute(iph1->rmconf->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->rmconf->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; + } /* validate authentication value */ ptype = oakley_validate_auth(iph1); if (ptype != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 2"), + CONSTSTR("Failed to authenticate, Aggressive-Mode Message 2")); if (ptype == -1) { /* message printed inner oakley_validate_auth() */ goto end; } - EVT_PUSH(iph1->local, iph1->remote, - EVTT_PEERPH1AUTH_FAILED, NULL); isakmp_info_send_n1(iph1, ptype, NULL); goto end; } - + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Initiator, Aggressive-Mode Message 2"), + CONSTSTR(NULL)); + if (oakley_checkcr(iph1) < 0) { /* Ignore this error in order to be interoperability. */ ; } /* change status of isakmp status entry */ - iph1->status = PHASE1ST_MSG2RECEIVED; + fsm_set_state(&iph1->status, IKEV1_STATE_AGG_I_MSG2RCVD); #ifdef ENABLE_VPNCONTROL_PORT vpncontrol_notify_phase_change(1, FROM_REMOTE, iph1, NULL); @@ -604,7 +678,19 @@ agg_i2recv(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Initiator, Aggressive-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 2"), + CONSTSTR("Failure processing Aggressive-Mode Message 2")); + } + if (pbuf) vfree(pbuf); if (satmp) @@ -634,61 +720,70 @@ end: * rev: HDR, HASH_I */ int -agg_i2send(iph1, msg) - struct ph1handle *iph1; +agg_i3send(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { struct payload_list *plist = NULL; int need_cert = 0; int error = -1; vchar_t *gsshash = NULL; +#ifdef ENABLE_NATT + vchar_t *natd[2] = { NULL, NULL }; +#endif + vchar_t *notp_unity = NULL; + vchar_t *notp_ini = NULL; - /* 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_AGG_I_MSG2RCVD) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } /* generate HASH to send */ - plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n"); + plog(ASL_LEVEL_DEBUG, "generate HASH_I\n"); iph1->hash = oakley_ph1hash_common(iph1, GENERATE); if (iph1->hash == NULL) { -#ifdef HAVE_GSSAPI - if (gssapi_more_tokens(iph1)) - isakmp_info_send_n1(iph1, - ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); -#endif + plog(ASL_LEVEL_ERR, + "failed to generate HASH"); goto end; } - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: + case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: #endif /* set HASH payload */ - plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); + plist = isakmp_plist_append(plist, + iph1->hash, ISAKMP_NPTYPE_HASH); break; - case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: + case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: -#endif + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: +#endif /* XXX if there is CR or not ? */ - if (oakley_getmycert(iph1) < 0) + 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; + } if (iph1->cert != NULL && iph1->rmconf->send_cert) need_cert = 1; /* 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); @@ -698,54 +793,33 @@ agg_i2send(iph1, msg) case OAKLEY_ATTR_AUTH_METHOD_RSAENC: case OAKLEY_ATTR_AUTH_METHOD_RSAREV: - break; -#ifdef HAVE_GSSAPI - case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: - gsshash = gssapi_wraphash(iph1); - if (gsshash == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to wrap hash\n"); - isakmp_info_send_n1(iph1, - ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); - goto end; - } - - plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); - break; +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: #endif - default: - plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; break; } #ifdef ENABLE_NATT /* generate NAT-D payloads */ - if (NATT_AVAILABLE(iph1)) - { - vchar_t *natd[2] = { NULL, NULL }; - - plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); + if (NATT_AVAILABLE(iph1)) { + plog (ASL_LEVEL_NOTICE, "Adding remote and local NAT-D payloads.\n"); 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; } - -#ifdef __APPLE__ /* 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); @@ -753,19 +827,25 @@ agg_i2send(iph1, msg) } #endif - iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + iph1->sendbuf = isakmp_plist_set_all (&plist, iph1); + #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); #endif + /* send 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; } @@ -773,11 +853,37 @@ agg_i2send(iph1, msg) /* set encryption flag */ iph1->flags |= ISAKMP_FLAG_E; - iph1->status = PHASE1ST_ESTABLISHED; + fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_ESTABLISHED); + + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_INIT_SUCC, + CONSTSTR("Initiator, Aggressive-Mode"), + CONSTSTR(NULL)); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Initiator, Aggressive-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Initiator, Aggressive-Mode Message 3"), + CONSTSTR("Failed to transmit Aggressive-Mode Message 3")); + } +#ifdef ENABLE_NATT + if (natd[0]) + vfree(natd[0]); + if (natd[1]) + vfree(natd[1]); +#endif + if (notp_unity) + vfree(notp_unity); + if (notp_ini) + vfree(notp_ini); if (gsshash) vfree(gsshash); return error; @@ -794,62 +900,74 @@ end: */ int agg_r1recv(iph1, msg) - struct ph1handle *iph1; + phase1_handle_t *iph1; vchar_t *msg; { int error = -1; vchar_t *pbuf = NULL; struct isakmp_parse_t *pa; int vid_numeric; -#ifdef HAVE_GSSAPI - vchar_t *gsstoken = NULL; -#endif - /* validity check */ - if (iph1->status != PHASE1ST_START) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_AGG_R_START) { + 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; - 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(&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*/; pa->type != ISAKMP_NPTYPE_NONE; pa++) { - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_DEBUG, "received payload of type %s\n", s_isakmp_nptype(pa->type)); 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_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_VID: vid_numeric = check_vendorid(pa->ptr); @@ -879,32 +997,31 @@ agg_r1recv(iph1, msg) #ifdef ENABLE_DPD if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) { iph1->dpd_support=1; - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_DEBUG, "remote supports DPD\n"); } #endif #ifdef ENABLE_FRAG if ((vid_numeric == VENDORID_FRAG) && - (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG)) + (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG)) { + plog(ASL_LEVEL_DEBUG, + "remote supports FRAGMENTATION\n"); iph1->frag = 1; + } #endif 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; -#ifdef HAVE_GSSAPI - case ISAKMP_NPTYPE_GSS: - if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) - goto end; - gssapi_save_received_token(iph1, gsstoken); - break; -#endif default: /* don't send information, see isakmp_ident_r1() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -914,28 +1031,30 @@ agg_r1recv(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; } /* verify identifier */ if (ipsecdoi_checkid1(iph1) != 0) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "invalid ID payload.\n"); goto end; } #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; @@ -946,11 +1065,23 @@ agg_r1recv(iph1, msg) ; } - iph1->status = PHASE1ST_MSG1RECEIVED; + fsm_set_state(&iph1->status, IKEV1_STATE_AGG_R_MSG1RCVD); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Aggressive-Mode message 1"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 1"), + CONSTSTR("Failed to process Aggressive-Mode Message 1")); + } + if (pbuf) vfree(pbuf); if (error) { @@ -974,15 +1105,14 @@ end: * rev: HDR, SA, PubKey_i, Ke_r, Ke_r, HASH_R */ int -agg_r1send(iph1, msg) - struct ph1handle *iph1; +agg_r2send(iph1, msg) + phase1_handle_t *iph1; vchar_t *msg; { struct payload_list *plist = NULL; int need_cr = 0; int need_cert = 0; vchar_t *cr = NULL; - vchar_t *vid = NULL; int error = -1; #ifdef ENABLE_HYBRID vchar_t *xauth_vid = NULL; @@ -995,17 +1125,14 @@ agg_r1send(iph1, msg) #ifdef ENABLE_DPD vchar_t *vid_dpd = NULL; #endif - -#ifdef HAVE_GSSAPI - int gsslen; - vchar_t *gsstoken = NULL, *gsshash = NULL; - vchar_t *gss_sa = NULL; +#ifdef ENABLE_FRAG + vchar_t *vid_frag = NULL; #endif - /* validity check */ - if (iph1->status != PHASE1ST_MSG1RECEIVED) { - plog(LLV_ERROR, LOCATION, NULL, - "status mismatched %d.\n", iph1->status); + /* validity check */ + if (iph1->status != IKEV1_STATE_AGG_R_MSG1RCVD) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } @@ -1013,61 +1140,84 @@ agg_r1send(iph1, msg) isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); /* 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; + } /* generate DH public value */ +#ifdef HAVE_OPENSSL if (oakley_dh_generate(iph1->rmconf->dhgrp, - &iph1->dhpub, &iph1->dhpriv) < 0) + &iph1->dhpub, &iph1->dhpriv) < 0) { +#else + if (oakley_dh_generate(iph1->rmconf->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; + } /* 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; - -#ifdef HAVE_GSSAPI - if (iph1->rmconf->proposal->authmethod == - OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) - gssapi_get_rtoken(iph1, &gsslen); -#endif + } /* 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) { -#ifdef HAVE_GSSAPI - if (gssapi_more_tokens(iph1)) - isakmp_info_send_n1(iph1, - ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); -#endif + plog(ASL_LEVEL_ERR, + "failed to generate GSS HASH"); goto end; } /* create CR if need */ if (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.\n"); goto end; } } @@ -1079,16 +1229,16 @@ agg_r1send(iph1, msg) vid_natt = set_vendorid(iph1->natt_options->version); /* generate NAT-D payloads */ - plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n"); + plog (ASL_LEVEL_NOTICE, "Adding remote and local NAT-D payloads.\n"); 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; } } @@ -1098,9 +1248,23 @@ agg_r1send(iph1, msg) if (iph1->dpd_support && iph1->rmconf->dpd) vid_dpd = set_vendorid(VENDORID_DPD); #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_AGG); + if (vid_frag == NULL) + plog(ASL_LEVEL_ERR, + "Frag vendorID construction failed\n"); + } +#endif - switch (iph1->approval->authmethod) { + switch (AUTHMETHOD(iph1)) { case OAKLEY_ATTR_AUTH_METHOD_PSKEY: +#ifdef ENABLE_HYBRID + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: +#endif /* set SA payload to reply */ plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA); @@ -1114,29 +1278,31 @@ agg_r1send(iph1, msg) plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); /* create isakmp HASH payload */ - plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH); - - /* append vendor id, if needed */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); + plist = isakmp_plist_append(plist, + iph1->hash, ISAKMP_NPTYPE_HASH); /* create isakmp CR payload if needed */ if (need_cr) plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR); break; - case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: case OAKLEY_ATTR_AUTH_METHOD_RSASIG: #ifdef ENABLE_HYBRID - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: - case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: + case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: + case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: #endif /* XXX if there is CR or not ? */ - if (oakley_getmycert(iph1) < 0) + 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; + } if (iph1->cert != NULL && iph1->rmconf->send_cert) need_cert = 1; @@ -1160,14 +1326,26 @@ agg_r1send(iph1, msg) /* add SIG payload */ plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG); - /* append vendor id, if needed */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); + /* create isakmp CR payload if needed */ + if (need_cr) + plist = isakmp_plist_append(plist, + cr, ISAKMP_NPTYPE_CR); + 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 + break; + } #ifdef ENABLE_HYBRID if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) { + plog (ASL_LEVEL_NOTICE, "Adding xauth VID payload.\n"); if ((xauth_vid = set_vendorid(VENDORID_XAUTH)) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "Cannot create Xauth vendor ID\n"); goto end; } @@ -1177,7 +1355,7 @@ agg_r1send(iph1, msg) if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) { if ((unity_vid = set_vendorid(VENDORID_UNITY)) == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "Cannot create Unity vendor ID\n"); goto end; } @@ -1186,87 +1364,29 @@ agg_r1send(iph1, msg) } #endif - /* create isakmp CR payload if needed */ - if (need_cr) - plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR); - break; - - case OAKLEY_ATTR_AUTH_METHOD_RSAENC: - case OAKLEY_ATTR_AUTH_METHOD_RSAREV: - break; -#ifdef HAVE_GSSAPI - case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: - /* create buffer to send isakmp payload */ - gsshash = gssapi_wraphash(iph1); - if (gsshash == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to wrap hash\n"); - /* - * This is probably due to the GSS roundtrips not - * being finished yet. Return this error in - * the hope that a fallback to main mode will - * be done. - */ - isakmp_info_send_n1(iph1, - ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); - goto end; - } - if (iph1->approval->gssid != NULL) - gss_sa = ipsecdoi_setph1proposal(iph1->approval); - else - gss_sa = iph1->sa_ret; - - /* set SA payload to reply */ - plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA); - - /* 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); - - /* create isakmp ID payload */ - plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID); - - /* create GSS payload */ - gssapi_get_token_to_send(iph1, &gsstoken); - plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS); - - /* create isakmp HASH payload */ - plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH); - - /* append vendor id, if needed */ - if (vid) - plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID); - - break; -#endif - default: - plog(LLV_ERROR, LOCATION, NULL, "Invalid authmethod %d\n", - iph1->approval->authmethod); - goto end; - break; - } - #ifdef ENABLE_NATT /* append NAT-T payloads */ if (vid_natt) { /* chosen VID */ plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID); /* NAT-D */ -#ifdef __APPLE__ /* 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); } } #endif + +#ifdef ENABLE_FRAG + if (vid_frag) + plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID); +#endif + #ifdef ENABLE_DPD if (vid_dpd) plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID); @@ -1280,17 +1400,21 @@ agg_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_AGG_R_MSG2SENT); #ifdef ENABLE_VPNCONTROL_PORT vpncontrol_notify_phase_change(1, FROM_LOCAL, iph1, NULL); @@ -1298,29 +1422,42 @@ agg_r1send(iph1, msg) error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, + CONSTSTR("Responder, Aggressive-Mode message 2"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 2"), + CONSTSTR("Failed to process Aggressive-Mode Message 2")); + } if (cr) vfree(cr); - if (vid) - vfree(vid); #ifdef ENABLE_HYBRID if (xauth_vid) vfree(xauth_vid); if (unity_vid) vfree(unity_vid); #endif -#ifdef HAVE_GSSAPI - if (gsstoken) - vfree(gsstoken); - if (gsshash) - vfree(gsshash); - if (gss_sa != iph1->sa_ret) - vfree(gss_sa); +#ifdef ENABLE_NATT + if (vid_natt) + vfree(vid_natt); + if (natd[0]) + vfree(natd[0]); + if (natd[1]) + vfree(natd[1]); #endif #ifdef ENABLE_DPD if (vid_dpd) vfree(vid_dpd); #endif +#ifdef ENABLE_FRAG + if (vid_frag) + vfree(vid_frag); +#endif return error; } @@ -1334,8 +1471,8 @@ end: * rev: HDR, HASH_I */ int -agg_r2recv(iph1, msg0) - struct ph1handle *iph1; +agg_r3recv(iph1, msg0) + phase1_handle_t *iph1; vchar_t *msg0; { vchar_t *msg = NULL; @@ -1347,11 +1484,12 @@ agg_r2recv(iph1, msg0) #ifdef ENABLE_NATT int natd_seq = 0; #endif + int received_cert = 0; - /* 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_AGG_R_MSG2SENT) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } @@ -1360,19 +1498,25 @@ agg_r2recv(iph1, msg0) if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 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 msg"); goto end; + } } else msg = vdup(msg0); /* 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++) { @@ -1384,12 +1528,19 @@ agg_r2recv(iph1, msg0) (void)check_vendorid(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; case ISAKMP_NPTYPE_N: isakmp_check_notify(pa->ptr, iph1); @@ -1398,17 +1549,17 @@ agg_r2recv(iph1, msg0) #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; @@ -1416,7 +1567,7 @@ agg_r2recv(iph1, msg0) 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"); @@ -1430,7 +1581,7 @@ agg_r2recv(iph1, msg0) default: /* don't send information, see isakmp_ident_r1() */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore the packet, " "received unexpecting payload type %d.\n", pa->type); @@ -1440,31 +1591,52 @@ agg_r2recv(iph1, msg0) #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 " : "", iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : ""); #endif + if (received_cert) { + oakley_verify_certid(iph1); + } + /* validate authentication value */ ptype = oakley_validate_auth(iph1); if (ptype != 0) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 3"), + CONSTSTR("Failed to authenticate Aggressive-Mode Message 3")); if (ptype == -1) { /* message printed inner oakley_validate_auth() */ goto end; } - EVT_PUSH(iph1->local, iph1->remote, - EVTT_PEERPH1AUTH_FAILED, NULL); isakmp_info_send_n1(iph1, ptype, NULL); goto end; } + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_AUTH_SUCC, + CONSTSTR("Responder, Aggressive-Mode Message 3"), + CONSTSTR(NULL)); - iph1->status = PHASE1ST_MSG2RECEIVED; + fsm_set_state(&iph1->status, IKEV1_STATE_AGG_R_MSG3RCVD); error = 0; + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, + CONSTSTR("Responder, Aggressive-Mode message 3"), + CONSTSTR(NULL)); + end: + if (error) { + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, + CONSTSTR("Responder, Aggressive-Mode Message 3"), + CONSTSTR("Failed to process Aggressive-Mode Message 3")); + } if (pbuf) vfree(pbuf); if (msg) @@ -1484,16 +1656,16 @@ end: * status update and establish isakmp sa. */ int -agg_r2send(iph1, msg) - struct ph1handle *iph1; +agg_rfinalize(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_AGG_R_MSG3RCVD) { + plog(ASL_LEVEL_ERR, + "status mismatched %d.\n", iph1->status); goto end; } @@ -1505,8 +1677,13 @@ agg_r2send(iph1, msg) /* set encryption flag */ iph1->flags |= ISAKMP_FLAG_E; - iph1->status = PHASE1ST_ESTABLISHED; + fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_ESTABLISHED); + IPSECSESSIONTRACEREVENT(iph1->parent_session, + IPSECSESSIONEVENTCODE_IKEV1_PH1_RESP_SUCC, + CONSTSTR("Responder, Aggressive-Mode"), + CONSTSTR(NULL)); + error = 0; end: