X-Git-Url: https://git.saurik.com/apple/ipsec.git/blobdiff_plain/fce29cd989a6ce7aa0e28bd9ade0752be16cb893..7685aad60c1b188a3f84904e9b609a7438e833c9:/ipsec-tools/racoon/isakmp_inf.c diff --git a/ipsec-tools/racoon/isakmp_inf.c b/ipsec-tools/racoon/isakmp_inf.c index 44fa30f..0f1ed28 100644 --- a/ipsec-tools/racoon/isakmp_inf.c +++ b/ipsec-tools/racoon/isakmp_inf.c @@ -32,16 +32,13 @@ */ #include "config.h" +#include "racoon_types.h" #include #include #include -#ifdef __APPLE__ -#include -#else #include -#endif #include #include #ifndef HAVE_NETINET6_IPSEC @@ -64,9 +61,6 @@ # include # endif #endif -#ifdef ENABLE_HYBRID -#include -#endif #include "libpfkey.h" @@ -77,6 +71,9 @@ #include "misc.h" #include "plog.h" #include "debug.h" +#include "fsm.h" +#include "session.h" +#include "ike_session.h" #include "localconf.h" #include "remoteconf.h" @@ -85,7 +82,6 @@ #include "policy.h" #include "proposal.h" #include "isakmp_var.h" -#include "evt.h" #include "isakmp.h" #ifdef ENABLE_HYBRID #include "isakmp_xauth.h" @@ -100,7 +96,6 @@ #include "policy.h" #include "algorithm.h" #include "proposal.h" -#include "admin.h" #include "strnames.h" #ifdef ENABLE_NATT #include "nattraversal.h" @@ -112,37 +107,31 @@ #include "ipsecMessageTracer.h" /* information exchange */ -static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int); -static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int); +static int isakmp_info_recv_n (phase1_handle_t *, struct isakmp_pl_n *, u_int32_t, int); +static int isakmp_info_recv_d (phase1_handle_t *, struct isakmp_pl_d *, u_int32_t, int); #ifdef ENABLE_DPD -static int isakmp_info_recv_r_u __P((struct ph1handle *, - struct isakmp_pl_ru *, u_int32_t)); -static int isakmp_info_recv_r_u_ack __P((struct ph1handle *, - struct isakmp_pl_ru *, u_int32_t)); +static int isakmp_info_recv_r_u (phase1_handle_t *, struct isakmp_pl_ru *, u_int32_t); +static int isakmp_info_recv_r_u_ack (phase1_handle_t *, struct isakmp_pl_ru *, u_int32_t); #endif #ifdef ENABLE_VPNCONTROL_PORT -static int isakmp_info_recv_lb __P((struct ph1handle *, struct isakmp_pl_lb *lb, int)); +static int isakmp_info_recv_lb (phase1_handle_t *, struct isakmp_pl_lb *lb, int); #endif -static void purge_isakmp_spi __P((int, isakmp_index *, size_t)); -static void info_recv_initialcontact __P((struct ph1handle *)); - static int -isakmp_ph1_responder_lifetime (struct ph1handle *iph1, - struct isakmp_pl_resp_lifetime *notify) +isakmp_ph1_responder_lifetime (phase1_handle_t *iph1, struct isakmp_pl_resp_lifetime *notify) { char *spi; if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "invalid spi_size in notification payload.\n"); return -1; } spi = val2str((char *)(notify + 1), notify->spi_size); - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "notification message ISAKMP-SA RESPONDER-LIFETIME, " "doi=%d proto_id=%d spi=%s(size=%d).\n", ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); @@ -162,19 +151,18 @@ isakmp_ph1_responder_lifetime (struct ph1handle *iph1, } static int -isakmp_ph2_responder_lifetime (struct ph2handle *iph2, - struct isakmp_pl_resp_lifetime *notify) +isakmp_ph2_responder_lifetime (phase2_handle_t *iph2, struct isakmp_pl_resp_lifetime *notify) { char *spi; if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { - plog(LLV_ERROR, LOCATION, iph2->dst, + plog(ASL_LEVEL_ERR, "invalid spi_size in notification payload.\n"); return -1; } spi = val2str((char *)(notify + 1), notify->spi_size); - plog(LLV_DEBUG, LOCATION, iph2->dst, + plog(ASL_LEVEL_NOTICE, "notification message IPSEC-SA RESPONDER-LIFETIME, " "doi=%d proto_id=%d spi=%s(size=%d).\n", ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); @@ -192,9 +180,7 @@ isakmp_ph2_responder_lifetime (struct ph2handle *iph2, * receive Information */ int -isakmp_info_recv(iph1, msg0) - struct ph1handle *iph1; - vchar_t *msg0; +isakmp_info_recv(phase1_handle_t *iph1, vchar_t *msg0) { vchar_t *msg = NULL; vchar_t *pbuf = NULL; @@ -202,15 +188,16 @@ isakmp_info_recv(iph1, msg0) int error = -1; struct isakmp *isakmp; struct isakmp_gen *gen; - struct isakmp_parse_t *pa, *pap; + struct isakmp_parse_t *pa; void *p; vchar_t *hash, *payload; struct isakmp_gen *nd; u_int8_t np; int encrypted; - int flag; + int flag = 0; + int disconnect = 0; - plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n"); + plog(ASL_LEVEL_NOTICE, "receive Information.\n"); encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E); msgid = ((struct isakmp *)msg0->v)->msgid; @@ -220,7 +207,7 @@ isakmp_info_recv(iph1, msg0) struct isakmp_ivm *ivm; if (iph1->ivm == NULL) { - plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n"); + plog(ASL_LEVEL_ERR, "iph1->ivm == NULL\n"); IPSECSESSIONTRACEREVENT(iph1->parent_session, IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, CONSTSTR("Information message"), @@ -231,8 +218,8 @@ isakmp_info_recv(iph1, msg0) /* compute IV */ ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid); if (ivm == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to compute IV"); + plog(ASL_LEVEL_ERR, + "failed to compute IV\n"); IPSECSESSIONTRACEREVENT(iph1->parent_session, IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, CONSTSTR("Information message"), @@ -243,8 +230,8 @@ isakmp_info_recv(iph1, msg0) msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive); oakley_delivm(ivm); if (msg == NULL) { - plog(LLV_ERROR, LOCATION, NULL, - "failed to decrypt packet"); + plog(ASL_LEVEL_ERR, + "failed to decrypt packet\n"); IPSECSESSIONTRACEREVENT(iph1->parent_session, IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, CONSTSTR("Information message"), @@ -257,7 +244,7 @@ isakmp_info_recv(iph1, msg0) /* Safety check */ if (msg->l < sizeof(*isakmp) + sizeof(*gen)) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "ignore information because the " "message is way too short\n"); goto end; @@ -269,15 +256,15 @@ isakmp_info_recv(iph1, msg0) if (encrypted) { if (isakmp->np != ISAKMP_NPTYPE_HASH) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "ignore information because the " "message has no hash payload.\n"); goto end; } - if (iph1->status != PHASE1ST_ESTABLISHED && + if (!FSM_STATE_IS_ESTABLISHED(iph1->status) && (!iph1->approval || !iph1->skeyid_a)) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "ignore information because ISAKMP-SA " "has not been established yet.\n"); goto end; @@ -285,7 +272,7 @@ isakmp_info_recv(iph1, msg0) /* Safety check */ if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "ignore information because the " "message is too short\n"); goto end; @@ -297,20 +284,20 @@ isakmp_info_recv(iph1, msg0) /* nd length check */ if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) + ntohs(gen->len))) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "too long payload length (broken message?)\n"); goto end; } if (ntohs(nd->len) < sizeof(*nd)) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "too short payload length (broken message?)\n"); goto end; } payload = vmalloc(ntohs(nd->len)); if (payload == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "cannot allocate memory\n"); goto end; } @@ -320,7 +307,7 @@ isakmp_info_recv(iph1, msg0) /* compute HASH */ hash = oakley_compute_hash1(iph1, isakmp->msgid, payload); if (hash == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "cannot compute hash\n"); vfree(payload); @@ -328,7 +315,7 @@ isakmp_info_recv(iph1, msg0) } if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "ignore information due to hash length mismatch\n"); vfree(hash); @@ -336,8 +323,8 @@ isakmp_info_recv(iph1, msg0) goto end; } - if (memcmp(p, hash->v, hash->l) != 0) { - plog(LLV_ERROR, LOCATION, NULL, + if (timingsafe_bcmp(p, hash->v, hash->l) != 0) { + plog(ASL_LEVEL_ERR, "ignore information due to hash mismatch\n"); vfree(hash); @@ -345,44 +332,69 @@ isakmp_info_recv(iph1, msg0) goto end; } - plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n"); + plog(ASL_LEVEL_DEBUG, "hash validated.\n"); vfree(hash); vfree(payload); } else { - /* make sure the packet was encrypted after the beginning of phase 1. */ + /* make sure phase 1 was not yet at encrypted state */ switch (iph1->etype) { case ISAKMP_ETYPE_AGG: - case ISAKMP_ETYPE_BASE: + // %%%%% should also check for unity/mode cfg - last pkt is encrypted in such cases + if (!FSM_STATE_IS_ESTABLISHED(iph1->status) && + ((iph1->side == INITIATOR && iph1->status == IKEV1_STATE_AGG_I_MSG3SENT) || + (iph1->side == RESPONDER && iph1->status == IKEV1_STATE_AGG_R_MSG3RCVD))) { + break; + } + /*FALLTHRU*/ case ISAKMP_ETYPE_IDENT: - if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT) - || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) { + if (!FSM_STATE_IS_ESTABLISHED(iph1->status) && + ((iph1->side == INITIATOR && (iph1->status == IKEV1_STATE_IDENT_I_MSG5SENT + || iph1->status == IKEV1_STATE_IDENT_I_MSG6RCVD)) || + (iph1->side == RESPONDER && (iph1->status == IKEV1_STATE_IDENT_R_MSG5RCVD)))) { break; } /*FALLTHRU*/ default: - plog(LLV_ERROR, LOCATION, iph1->remote, - "%s message must be encrypted\n", - s_isakmp_nptype(np)); + if ((np == ISAKMP_NPTYPE_NONE) && + !FSM_STATE_IS_ESTABLISHED(iph1->status) && + (iph1->side == INITIATOR && (iph1->status == IKEV1_STATE_AGG_I_MSG1SENT))) { + // proposal rejected by peer, terminate now. + disconnect = 1; + } + + plog(ASL_LEVEL_ERR, + "%s message must be encrypted, status 0x%x, side %d\n", + s_isakmp_nptype(np), iph1->status, iph1->side); error = 0; goto end; } } if (!(pbuf = isakmp_parse(msg))) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to parse msg"); error = -1; goto end; } error = 0; - for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { + for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { // Wcast-align fix (void*) - aligned buffer of aligned (unpacked) structs switch (pa->type) { case ISAKMP_NPTYPE_HASH: /* Handled above */ break; case ISAKMP_NPTYPE_N: + if ((ntohs(((struct isakmp_pl_n *)pa->ptr)->type) == ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN) && + !FSM_STATE_IS_ESTABLISHED(iph1->status) && + (iph1->side == INITIATOR && (iph1->status == IKEV1_STATE_AGG_I_MSG1SENT))) { + // proposal rejected by peer, terminate now. + disconnect = 1; + plog(ASL_LEVEL_ERR, + "%s message with %s notification receveid, status 0x%x, side %d\n", + s_isakmp_nptype(np), s_isakmp_notify_msg(ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN), iph1->status, iph1->side); + break; + } error = isakmp_info_recv_n(iph1, (struct isakmp_pl_n *)pa->ptr, msgid, encrypted); @@ -395,13 +407,13 @@ isakmp_info_recv(iph1, msg0) case ISAKMP_NPTYPE_NONCE: /* XXX to be 6.4.2 ike-01.txt */ /* XXX IV is to be synchronized. */ - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "ignore Acknowledged Informational\n"); break; default: /* don't send information, see isakmp_ident_r1() */ error = 0; - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "reject the packet, " "received unexpected payload type %s.\n", s_isakmp_nptype(gen->np)); @@ -428,6 +440,17 @@ end: vfree(msg); if (pbuf != NULL) vfree(pbuf); + if (disconnect) { + ike_session_t *session = NULL; + + if (session = iph1->parent_session) { + gettimeofday(&session->stop_timestamp, NULL); + if (!session->term_reason) { + session->term_reason = ike_session_stopped_by_peer; + } + ike_session_purge_ph1s_by_session(session); + } + } return error; } @@ -435,14 +458,9 @@ end: * handling of Notification payload */ static int -isakmp_info_recv_n(iph1, notify, msgid, encrypted) - struct ph1handle *iph1; - struct isakmp_pl_n *notify; - u_int32_t msgid; - int encrypted; +isakmp_info_recv_n(phase1_handle_t *iph1, struct isakmp_pl_n *notify, u_int32_t msgid, int encrypted) { u_int type; - vchar_t *pbuf; vchar_t *ndata; char *nraw; size_t l; @@ -465,9 +483,10 @@ isakmp_info_recv_n(iph1, notify, msgid, encrypted) } break; case ISAKMP_NTYPE_INITIAL_CONTACT: - if (encrypted) + if (encrypted) { info_recv_initialcontact(iph1); return 0; + } break; #ifdef ENABLE_DPD case ISAKMP_NTYPE_R_U_THERE: @@ -494,26 +513,26 @@ isakmp_info_recv_n(iph1, notify, msgid, encrypted) type <= ISAKMP_NTYPE_MAXERROR) { if (msgid == 0) { /* don't think this realy deletes ph1 ? */ - plog(LLV_ERROR, LOCATION, iph1->remote, - "delete phase1 handle.\n"); + plog(ASL_LEVEL_ERR, + "Delete Phase 1 handle.\n"); return -1; } else { - if (getph2bymsgid(iph1, msgid) == NULL) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "fatal %s notify messsage, " - "phase1 should be deleted.\n", + if (ike_session_getph2bymsgid(iph1, msgid) == NULL) { + plog(ASL_LEVEL_ERR, + "Fatal %s notify messsage, " + "Phase 1 should be deleted.\n", s_isakmp_notify_msg(type)); } else { - plog(LLV_ERROR, LOCATION, iph1->remote, - "fatal %s notify messsage, " - "phase2 should be deleted.\n", + plog(ASL_LEVEL_ERR, + "Fatal %s notify messsage, " + "Phase 2 should be deleted.\n", s_isakmp_notify_msg(type)); } } } else { - plog(LLV_ERROR, LOCATION, iph1->remote, - "unhandled notify message %s, " - "no phase2 handle found.\n", + plog(ASL_LEVEL_ERR, + "Unhandled notify message %s, " + "no Phase 2 handle found.\n", s_isakmp_notify_msg(type)); } } @@ -523,14 +542,14 @@ isakmp_info_recv_n(iph1, notify, msgid, encrypted) /* get spi if specified and allocate */ if(notify->spi_size > 0) { if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { - plog(LLV_ERROR, LOCATION, iph1->remote, - "invalid spi_size in notification payload.\n"); + plog(ASL_LEVEL_ERR, + "Invalid spi_size in notification payload.\n"); return -1; } spi = val2str((char *)(notify + 1), notify->spi_size); - plog(LLV_DEBUG, LOCATION, iph1->remote, - "notification message %d:%s, " + plog(ASL_LEVEL_NOTICE, + "Notification message %d:%s, " "doi=%d proto_id=%d spi=%s(size=%d).\n", type, s_isakmp_notify_msg(type), ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); @@ -547,12 +566,12 @@ isakmp_info_recv_n(iph1, notify, msgid, encrypted) nraw += sizeof(*notify) + notify->spi_size; if ((ndata = vmalloc(l)) != NULL) { memcpy(ndata->v, nraw, ndata->l); - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "Message: '%s'.\n", binsanitize(ndata->v, ndata->l)); vfree(ndata); } else { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "Cannot allocate memory\n"); } } @@ -560,28 +579,77 @@ isakmp_info_recv_n(iph1, notify, msgid, encrypted) return 0; } +#ifdef ENABLE_VPNCONTROL_PORT +static void +isakmp_info_vpncontrol_notify_ike_failed (phase1_handle_t *iph1, int isakmp_info_initiator, int type, vchar_t *data) +{ + u_int32_t address = iph1_get_remote_v4_address(iph1); + u_int32_t fail_reason; + + /* notify the API that we have received the delete */ + + if (isakmp_info_initiator == FROM_REMOTE) { + int premature = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_PREMATURE); + int expired = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_EXPIRED); + + if (premature) { + fail_reason = VPNCTL_NTYPE_LOCAL_CERT_PREMATURE; + plog(ASL_LEVEL_NOTICE, ">>> Server reports client's certificate is pre-mature\n"); + } else if (expired) { + fail_reason = VPNCTL_NTYPE_LOCAL_CERT_EXPIRED; + plog(ASL_LEVEL_NOTICE, ">>> Server reports client's certificate is expired\n"); + } else { + fail_reason = type; + } + vpncontrol_notify_ike_failed(fail_reason, isakmp_info_initiator, address, 0, NULL); + return; + } else { + /* FROM_LOCAL */ + if (type == ISAKMP_INTERNAL_ERROR || + type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) { + int premature = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_PREMATURE); + int expired = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_EXPIRED); + int subjname = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_INVALID_SUBJNAME); + int subjaltname = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_INVALID_SUBJALTNAME); + + if (premature) { + fail_reason = VPNCTL_NTYPE_PEER_CERT_PREMATURE; + plog(ASL_LEVEL_NOTICE, ">>> Server's certificate is pre-mature\n"); + } else if (expired) { + fail_reason = VPNCTL_NTYPE_PEER_CERT_EXPIRED; + plog(ASL_LEVEL_NOTICE, ">>> Server's certificate is expired\n"); + } else if (subjname) { + fail_reason = VPNCTL_NTYPE_PEER_CERT_INVALID_SUBJNAME; + plog(ASL_LEVEL_NOTICE, ">>> Server's certificate subject name not valid\n"); + } else if (subjaltname) { + fail_reason = VPNCTL_NTYPE_PEER_CERT_INVALID_SUBJALTNAME; + plog(ASL_LEVEL_NOTICE, ">>> Server's certificate subject alternate name not valid\n"); + } else { + fail_reason = type; + } + (void)vpncontrol_notify_ike_failed(fail_reason, isakmp_info_initiator, address, + (data ? data->l : 0), (u_int8_t *)(data ? data->v : NULL)); + return; + } + } +} +#endif /* ENABLE_VPNCONTROL_PORT */ + /* * handling of Deletion payload */ static int -isakmp_info_recv_d(iph1, delete, msgid, encrypted) - struct ph1handle *iph1; - struct isakmp_pl_d *delete; - u_int32_t msgid; - int encrypted; +isakmp_info_recv_d(phase1_handle_t *iph1, struct isakmp_pl_d *delete, u_int32_t msgid, int encrypted) { int tlen, num_spi; - vchar_t *pbuf; - int protected = 0; - struct ph1handle *del_ph1; - struct ph2handle *iph2; + phase1_handle_t *del_ph1; union { u_int32_t spi32; u_int16_t spi16[2]; } spi; if (ntohl(delete->doi) != IPSEC_DOI) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "delete payload with invalid doi:%d.\n", ntohl(delete->doi)); #ifdef ENABLE_HYBRID @@ -601,17 +669,17 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted) tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d); if (tlen != num_spi * delete->spi_size) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "deletion payload with invalid length.\n"); return 0; } - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "delete payload for protocol %s\n", s_ipsecdoi_proto(delete->proto_id)); if(!iph1->rmconf->weak_phase1_check && !encrypted) { - plog(LLV_WARNING, LOCATION, iph1->remote, + plog(ASL_LEVEL_WARNING, "Ignoring unencrypted delete payload " "(check the weak_phase1_check option)\n"); return 0; @@ -620,26 +688,26 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted) switch (delete->proto_id) { case IPSECDOI_PROTO_ISAKMP: if (delete->spi_size != sizeof(isakmp_index)) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "delete payload with strange spi " "size %d(proto_id:%d)\n", delete->spi_size, delete->proto_id); return 0; } - del_ph1=getph1byindex((isakmp_index *)(delete + 1)); + del_ph1 = ike_session_getph1byindex(iph1->parent_session, (isakmp_index *)(delete + 1)); if(del_ph1 != NULL){ // hack: start a rekey now, if one was pending (only for client). if (del_ph1->sce_rekey && del_ph1->parent_session && del_ph1->parent_session->is_client && - del_ph1->parent_session->established) { + del_ph1->parent_session->established && + !(del_ph1->rmconf->natt_multiple_user && + del_ph1->parent_session->is_l2tpvpn_ipsec)) { isakmp_ph1rekeyexpire(del_ph1, FALSE); } - EVT_PUSH(del_ph1->local, del_ph1->remote, - EVTT_PEERPH1_NOPROP, NULL); if (del_ph1->scr) SCHED_KILL(del_ph1->scr); @@ -648,23 +716,17 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted) * Just delete the IKE SA. */ #ifdef ENABLE_VPNCONTROL_PORT - - if (del_ph1->started_by_api) - if (islast_ph1(del_ph1)) { - u_int32_t address; - - /* notify the API that we have received the delete */ - if (iph1->remote->sa_family == AF_INET) - address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr; - else - address = 0; - if (iph1->cert && IS_CERT_STATUS_ERROR(iph1->cert->status)) { - vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE_CERT_ERROR + iph1->cert->status, FROM_REMOTE, address, 0, NULL); - } else { - vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE, FROM_REMOTE, address, 0, NULL); - } + if (del_ph1->started_by_api || (del_ph1->is_rekey && del_ph1->parent_session && del_ph1->parent_session->is_client)) { + if (ike_session_islast_ph1(del_ph1)) { + isakmp_info_vpncontrol_notify_ike_failed(del_ph1, FROM_REMOTE, VPNCTL_NTYPE_PH1_DELETE, NULL); } + } #endif + if (del_ph1->rmconf->natt_multiple_user && + del_ph1->parent_session->is_l2tpvpn_ipsec) { + plog(ASL_LEVEL_NOTICE, "Ignoring IKE delete from peer for L2TP server\n"); + break; + } isakmp_ph1expire(del_ph1); } break; @@ -672,16 +734,25 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted) case IPSECDOI_PROTO_IPSEC_AH: case IPSECDOI_PROTO_IPSEC_ESP: if (delete->spi_size != sizeof(u_int32_t)) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "delete payload with strange spi " "size %d(proto_id:%d)\n", delete->spi_size, delete->proto_id); return 0; } - EVT_PUSH(iph1->local, iph1->remote, - EVTT_PEER_DELETE, NULL); + if (iph1->rmconf->natt_multiple_user && + iph1->parent_session->is_l2tpvpn_ipsec) { + uint32_t *ph2_spi = ALIGNED_CAST(u_int32_t *)(delete + 1); + phase2_handle_t *iph2 = ike_session_getph2bysaidx(iph1->local, iph1->remote, delete->proto_id, ph2_spi[0]); + + if (iph2 != NULL) { + iph2->is_defunct = 1; + plog(ASL_LEVEL_NOTICE, "Ignoring SA delete from peer for L2TP server\n"); + break; + } + } purge_ipsec_spi(iph1->remote, delete->proto_id, - (u_int32_t *)(delete + 1), num_spi); + ALIGNED_CAST(u_int32_t *)(delete + 1), num_spi, NULL, NULL); // Wcast-align fix (void*) - delete payload is aligned break; case IPSECDOI_PROTO_IPCOMP: @@ -693,25 +764,25 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted) } else if (delete->spi_size == sizeof(spi.spi32)) memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32)); else { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "delete payload with strange spi " "size %d(proto_id:%d)\n", delete->spi_size, delete->proto_id); return 0; } purge_ipsec_spi(iph1->remote, delete->proto_id, - &spi.spi32, num_spi); + &spi.spi32, num_spi, NULL, NULL); break; default: - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "deletion message received, " "invalid proto_id: %d\n", delete->proto_id); return 0; } - plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); + plog(ASL_LEVEL_NOTICE, "purged SAs.\n"); return 0; } @@ -720,15 +791,14 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted) * send Delete payload (for ISAKMP SA) in Informational exchange. */ int -isakmp_info_send_d1(iph1) - struct ph1handle *iph1; +isakmp_info_send_d1(phase1_handle_t *iph1) { struct isakmp_pl_d *d; vchar_t *payload = NULL; int tlen; int error = 0; - if (iph1->status != PHASE2ST_ESTABLISHED) + if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) return 0; /* create delete payload */ @@ -738,7 +808,7 @@ isakmp_info_send_d1(iph1) tlen = sizeof(*d) + sizeof(isakmp_index); payload = vmalloc(tlen); if (payload == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer for payload.\n"); return errno; } @@ -775,10 +845,9 @@ isakmp_info_send_d1(iph1) * pfkey msg. It sends always single SPI. */ int -isakmp_info_send_d2(iph2) - struct ph2handle *iph2; +isakmp_info_send_d2(phase2_handle_t *iph2) { - struct ph1handle *iph1; + phase1_handle_t *iph1; struct saproto *pr; struct isakmp_pl_d *d; vchar_t *payload = NULL; @@ -786,16 +855,16 @@ isakmp_info_send_d2(iph2) int error = 0; u_int8_t *spi; - if (iph2->status != PHASE2ST_ESTABLISHED) + if (!FSM_STATE_IS_ESTABLISHED(iph2->status)) return 0; - + /* * don't send delete information if there is no phase 1 handler. * It's nonsensical to negotiate phase 1 to send the information. */ iph1 = ike_session_get_established_ph1(iph2->parent_session); if (!iph1) { - iph1 = getph1byaddr(iph2->src, iph2->dst); + iph1 = ike_session_getph1byaddr(iph2->parent_session, iph2->src, iph2->dst); } if (iph1 == NULL){ IPSECSESSIONTRACEREVENT(iph2->parent_session, @@ -806,7 +875,7 @@ isakmp_info_send_d2(iph2) IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, CONSTSTR("Delete IPSEC-SA"), CONSTSTR("Failed to transmit Delete-IPSEC-SA message")); - plog(LLV_DEBUG2, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "No ph1 handler found, could not send DELETE_SA\n"); return 0; } @@ -832,7 +901,7 @@ isakmp_info_send_d2(iph2) IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, CONSTSTR("Delete IPSEC-SA"), CONSTSTR("Failed to transmit Delete-IPSEC-SA message")); - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer for payload.\n"); return errno; } @@ -873,23 +942,20 @@ isakmp_info_send_d2(iph2) } /* - * send Notification payload (for without ISAKMP SA) in Informational exchange + * send Notification payload (without ISAKMP SA) in an Informational exchange */ int -isakmp_info_send_nx(isakmp, remote, local, type, data) - struct isakmp *isakmp; - struct sockaddr *remote, *local; - int type; - vchar_t *data; +isakmp_info_send_nx(struct isakmp *isakmp, struct sockaddr_storage *remote, struct sockaddr_storage *local, + int type, vchar_t *data) { - struct ph1handle *iph1 = NULL; + phase1_handle_t *iph1 = NULL; struct remoteconf *rmconf; vchar_t *payload = NULL; int tlen; int error = -1; struct isakmp_pl_n *n; int spisiz = 0; /* see below */ - ike_session_t *sess = ike_session_get_session(local, remote, FALSE); + ike_session_t *sess = ike_session_get_session(local, remote, FALSE, NULL); /* search appropreate configuration */ rmconf = getrmconf(remote); @@ -898,41 +964,28 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, CONSTSTR("Information message"), CONSTSTR("Failed to transmit Information message (no remote configuration)")); - plog(LLV_ERROR, LOCATION, remote, + plog(ASL_LEVEL_ERR, "no configuration found for peer address.\n"); goto end; } /* add new entry to isakmp status table. */ - iph1 = newph1(); + iph1 = ike_session_newph1(ISAKMP_VERSION_NUMBER_IKEV1); if (iph1 == NULL) { IPSECSESSIONTRACEREVENT(sess, IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, CONSTSTR("Information message"), - CONSTSTR("Failed to transmit Information message (no new phase1)")); - plog(LLV_ERROR, LOCATION, NULL, + CONSTSTR("Failed to transmit Information message (no new Phase 1)")); + plog(ASL_LEVEL_ERR, "failed to allocate ph1"); return -1; } memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t)); isakmp_newcookie((char *)&iph1->index.r_ck, remote, local); - iph1->status = PHASE1ST_START; + fsm_set_state(&iph1->status, IKEV1_STATE_INFO); iph1->rmconf = rmconf; -#ifdef __APPLE__ - if (link_rmconf_to_ph1(rmconf) < 0) { - IPSECSESSIONTRACEREVENT(sess, - IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, - CONSTSTR("Information message"), - CONSTSTR("Failed to transmit Information message (can't link remote configuration to phase1)")); - plog(LLV_ERROR, LOCATION, remote, - "couldn't link " - "configuration.\n"); - iph1->rmconf = NULL; - error = -1; - goto end; - } -#endif + retain_rmconf(iph1->rmconf); iph1->side = INITIATOR; iph1->version = isakmp->v; iph1->flags = 0; @@ -953,8 +1006,8 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) IPSECSESSIONTRACEREVENT(sess, IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, CONSTSTR("Information message"), - CONSTSTR("Failed to transmit Information Message (can't copy phase1 addresses)")); - plog(LLV_ERROR, LOCATION, NULL, + CONSTSTR("Failed to transmit Information Message (can't copy Phase 1 addresses)")); + plog(ASL_LEVEL_ERR, "failed to copy ph1 addresses"); error = -1; iph1 = NULL; /* deleted in copy_ph1addresses */ @@ -970,7 +1023,7 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, CONSTSTR("Information message"), CONSTSTR("Failed to transmit Information Message (can't allocate payload)")); - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer to send.\n"); error = -1; goto end; @@ -989,20 +1042,11 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); #ifdef ENABLE_VPNCONTROL_PORT - { - u_int32_t address; - if (type == ISAKMP_INTERNAL_ERROR || - type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) { - if (remote->sa_family == AF_INET) - address = ((struct sockaddr_in *)remote)->sin_addr.s_addr; - else - address = 0; - (void)vpncontrol_notify_ike_failed(type, FROM_LOCAL, address, - (data ? data->l : 0), (data ? data->v : NULL)); - } - } + isakmp_info_vpncontrol_notify_ike_failed(iph1, FROM_LOCAL, type, data); #endif - + if (ike_session_link_phase1(sess, iph1)) + fatal_error(-1); + error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); vfree(payload); if (error) { @@ -1019,19 +1063,16 @@ isakmp_info_send_nx(isakmp, remote, local, type, data) end: if (iph1 != NULL) - delph1(iph1); + ike_session_unlink_phase1(iph1); return error; } /* - * send Notification payload (for ISAKMP SA) in Informational exchange + * send Notification payload (with ISAKMP SA) in an Informational exchange */ int -isakmp_info_send_n1(iph1, type, data) - struct ph1handle *iph1; - int type; - vchar_t *data; +isakmp_info_send_n1(phase1_handle_t *iph1, int type, vchar_t *data) { vchar_t *payload = NULL; int tlen; @@ -1064,7 +1105,7 @@ isakmp_info_send_n1(iph1, type, data) IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, CONSTSTR("ISAKMP-SA"), CONSTSTR("Failed to transmit ISAKMP-SA message (can't allocate payload)")); - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer to send.\n"); return errno; } @@ -1082,19 +1123,7 @@ isakmp_info_send_n1(iph1, type, data) memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); #ifdef ENABLE_VPNCONTROL_PORT - { - u_int32_t address; - - if (type == ISAKMP_INTERNAL_ERROR || - type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) { - if (iph1->remote->sa_family == AF_INET) - address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; - else - address = 0; - (void)vpncontrol_notify_ike_failed(type, FROM_LOCAL, address, - (data ? data->l : 0), (data ? data->v : NULL)); - } - } + isakmp_info_vpncontrol_notify_ike_failed(iph1, FROM_LOCAL, type, data); #endif error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags); @@ -1115,15 +1144,12 @@ isakmp_info_send_n1(iph1, type, data) } /* - * send Notification payload (for IPsec SA) in Informational exchange + * send Notification payload (with IPsec SA) in an Informational exchange */ int -isakmp_info_send_n2(iph2, type, data) - struct ph2handle *iph2; - int type; - vchar_t *data; +isakmp_info_send_n2(phase2_handle_t *iph2, int type, vchar_t *data) { - struct ph1handle *iph1 = iph2->ph1; + phase1_handle_t *iph1 = iph2->ph1; vchar_t *payload = NULL; int tlen; int error = 0; @@ -1145,7 +1171,7 @@ isakmp_info_send_n2(iph2, type, data) IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, CONSTSTR("IPSEC-SA"), CONSTSTR("Failed to transmit IPSEC-SA message (can't allocate payload)")); - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer to send.\n"); return errno; } @@ -1157,7 +1183,7 @@ isakmp_info_send_n2(iph2, type, data) n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ n->spi_size = pr->spisize; n->type = htons(type); - *(u_int32_t *)(n + 1) = pr->spi; + memcpy(n + 1, &pr->spi, sizeof(u_int32_t)); // Wcast-align fix - copy instead of assign if (data) memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); @@ -1184,13 +1210,9 @@ isakmp_info_send_n2(iph2, type, data) * When ph1->skeyid_a == NULL, send message without encoding. */ int -isakmp_info_send_common(iph1, payload, np, flags) - struct ph1handle *iph1; - vchar_t *payload; - u_int32_t np; - int flags; +isakmp_info_send_common(phase1_handle_t *iph1, vchar_t *payload, u_int32_t np, int flags) { - struct ph2handle *iph2 = NULL; + phase2_handle_t *iph2 = NULL; vchar_t *hash = NULL; struct isakmp *isakmp; struct isakmp_gen *gen; @@ -1199,28 +1221,28 @@ isakmp_info_send_common(iph1, payload, np, flags) int error = -1; /* add new entry to isakmp status table */ - iph2 = newph2(); + iph2 = ike_session_newph2(ISAKMP_VERSION_NUMBER_IKEV1, PHASE2_TYPE_INFO); if (iph2 == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to allocate ph2"); goto end; } iph2->dst = dupsaddr(iph1->remote); if (iph2->dst == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to duplicate remote address"); - delph2(iph2); + ike_session_delph2(iph2); goto end; } iph2->src = dupsaddr(iph1->local); if (iph2->src == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to duplicate local address"); - delph2(iph2); + ike_session_delph2(iph2); goto end; } - switch (iph1->remote->sa_family) { + switch (iph1->remote->ss_family) { case AF_INET: #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) ((struct sockaddr_in *)iph2->dst)->sin_port = 0; @@ -1236,32 +1258,31 @@ isakmp_info_send_common(iph1, payload, np, flags) break; #endif default: - plog(LLV_ERROR, LOCATION, NULL, - "invalid family: %d\n", iph1->remote->sa_family); - delph2(iph2); + plog(ASL_LEVEL_ERR, + "invalid family: %d\n", iph1->remote->ss_family); + ike_session_delph2(iph2); goto end; } - iph2->ph1 = iph1; iph2->side = INITIATOR; - iph2->status = PHASE2ST_START; + fsm_set_state(&iph2->status, IKEV1_STATE_INFO); iph2->msgid = isakmp_newmsgid2(iph1); /* get IV and HASH(1) if skeyid_a was generated. */ if (iph1->skeyid_a != NULL) { iph2->ivm = oakley_newiv2(iph1, iph2->msgid); if (iph2->ivm == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to generate IV"); - delph2(iph2); + ike_session_delph2(iph2); goto end; } /* generate HASH(1) */ - hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload); + hash = oakley_compute_hash1(iph1, iph2->msgid, payload); if (hash == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to generate HASH"); - delph2(iph2); + ike_session_delph2(iph2); goto end; } @@ -1280,15 +1301,14 @@ isakmp_info_send_common(iph1, payload, np, flags) else iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); - insph2(iph2); - bindph12(iph1, iph2); + ike_session_link_ph2_to_ph1(iph1, iph2); tlen += sizeof(*isakmp) + payload->l; /* create buffer for isakmp payload */ iph2->sendbuf = vmalloc(tlen); if (iph2->sendbuf == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer to send.\n"); goto err; } @@ -1331,7 +1351,7 @@ isakmp_info_send_common(iph1, payload, np, flags) iph2->ivm->iv); VPTRINIT(iph2->sendbuf); if (tmp == NULL) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to encrypt packet"); goto err; } @@ -1340,13 +1360,13 @@ isakmp_info_send_common(iph1, payload, np, flags) /* HDR*, HASH(1), N */ if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to send packet"); VPTRINIT(iph2->sendbuf); goto err; } - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "sendto Information %s.\n", s_isakmp_nptype(np)); /* @@ -1376,9 +1396,7 @@ end: return error; err: - unbindph12(iph2); - remph2(iph2); - delph2(iph2); + ike_session_unlink_phase2(iph2); goto end; } @@ -1389,12 +1407,7 @@ err: * XXX Which is SPI to be included, inbound or outbound ? */ vchar_t * -isakmp_add_pl_n(buf0, np_p, type, pr, data) - vchar_t *buf0; - u_int8_t **np_p; - int type; - struct saproto *pr; - vchar_t *data; +isakmp_add_pl_n(vchar_t *buf0, u_int8_t **np_p, int type, struct saproto *pr, vchar_t *data) { vchar_t *buf = NULL; struct isakmp_pl_n *n; @@ -1414,7 +1427,7 @@ isakmp_add_pl_n(buf0, np_p, type, pr, data) } else buf = vmalloc(tlen); if (!buf) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get a payload buffer.\n"); return NULL; } @@ -1426,7 +1439,7 @@ isakmp_add_pl_n(buf0, np_p, type, pr, data) n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ n->spi_size = pr->spisize; n->type = htons(type); - *(u_int32_t *)(n + 1) = pr->spi; /* XXX */ + memcpy(n + 1, &pr->spi, sizeof(u_int32_t)); // Wcast-align fix - copy instead of assign with cast if (data) memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); @@ -1436,93 +1449,56 @@ isakmp_add_pl_n(buf0, np_p, type, pr, data) return buf; } -static void -purge_isakmp_spi(proto, spi, n) - int proto; - isakmp_index *spi; /*network byteorder*/ - size_t n; -{ - struct ph1handle *iph1; - size_t i; - - for (i = 0; i < n; i++) { - iph1 = getph1byindex(&spi[i]); - if (!iph1) - continue; - - plog(LLV_INFO, LOCATION, NULL, - "purged ISAKMP-SA proto_id=%s spi=%s.\n", - s_ipsecdoi_proto(proto), - isakmp_pindex(&spi[i], 0)); - - SCHED_KILL(iph1->sce); - SCHED_KILL(iph1->sce_rekey); - iph1->status = PHASE1ST_EXPIRED; - ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1 - iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); - } -} - - void -purge_ipsec_spi(dst0, proto, spi, n) - struct sockaddr *dst0; - int proto; - u_int32_t *spi; /*network byteorder*/ - size_t n; +purge_ipsec_spi(struct sockaddr_storage *dst0, int proto, u_int32_t *spi /*network byteorder*/, size_t n, u_int32_t *inbound_spi, size_t *max_inbound_spi) { vchar_t *buf = NULL; struct sadb_msg *msg, *next, *end; struct sadb_sa *sa; struct sadb_lifetime *lt; - struct sockaddr *src, *dst; - struct ph2handle *iph2; + struct sockaddr_storage *src, *dst; + phase2_handle_t *iph2; u_int64_t created; - size_t i; + size_t i, j = 0; caddr_t mhp[SADB_EXT_MAX + 1]; - plog(LLV_DEBUG2, LOCATION, NULL, - "purge_ipsec_spi:\n"); - plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0)); - plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0])); - buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto)); if (buf == NULL) { - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "pfkey_dump_sadb returned nothing.\n"); return; } - msg = (struct sadb_msg *)buf->v; - end = (struct sadb_msg *)(buf->v + buf->l); + msg = ALIGNED_CAST(struct sadb_msg *)buf->v; + end = ALIGNED_CAST(struct sadb_msg *)(buf->v + buf->l); while (msg < end) { if ((msg->sadb_msg_len << 3) < sizeof(*msg)) break; - next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); + next = ALIGNED_CAST(struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); if (msg->sadb_msg_type != SADB_DUMP) { msg = next; continue; } if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "pfkey_check (%s)\n", ipsec_strerror()); msg = next; continue; } - sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); + sa = ALIGNED_CAST(struct sadb_sa *)(mhp[SADB_EXT_SA]); // Wcast-align fix (void*) - buffer of pointers to aligned structs if (!sa || !mhp[SADB_EXT_ADDRESS_SRC] || !mhp[SADB_EXT_ADDRESS_DST]) { msg = next; continue; } - src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); - dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); - lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; + src = ALIGNED_CAST(struct sockaddr_storage*)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); // Wcast-align fix (void*) - buffer of pointers to aligned structs + dst = ALIGNED_CAST(struct sockaddr_storage*)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + lt = ALIGNED_CAST(struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; if(lt != NULL) created = lt->sadb_lifetime_addtime; else @@ -1533,14 +1509,10 @@ purge_ipsec_spi(dst0, proto, spi, n) msg = next; continue; } - plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); - plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst)); - - /* XXX n^2 algorithm, inefficient */ - /* don't delete inbound SAs at the moment */ + /* don't delete inbound SAs at the moment (just save them in inbound_spi) */ /* XXX should we remove SAs with opposite direction as well? */ if (CMPSADDR2(dst0, dst)) { msg = next; @@ -1548,39 +1520,48 @@ purge_ipsec_spi(dst0, proto, spi, n) } for (i = 0; i < n; i++) { - plog(LLV_DEBUG, LOCATION, NULL, - "check spi(packet)=%u spi(db)=%u.\n", - ntohl(spi[i]), ntohl(sa->sadb_sa_spi)); + u_int32_t *i_spi; + if (spi[i] != sa->sadb_sa_spi) continue; - pfkey_send_delete(lcconf->sock_pfkey, - msg->sadb_msg_satype, - IPSEC_MODE_ANY, - src, dst, sa->sadb_sa_spi); - /* * delete a relative phase 2 handler. * continue to process if no relative phase 2 handler * exists. */ - iph2 = getph2bysaidx(src, dst, proto, spi[i]); + if (inbound_spi && max_inbound_spi && j < *max_inbound_spi) { + i_spi = &inbound_spi[j]; + } else { + i_spi = NULL; + } + iph2 = ike_session_getph2bysaidx2(src, dst, proto, spi[i], i_spi); + + pfkey_send_delete(lcconf->sock_pfkey, + msg->sadb_msg_satype, + IPSEC_MODE_ANY, + src, dst, sa->sadb_sa_spi); + if(iph2 != NULL){ delete_spd(iph2); - unbindph12(iph2); - remph2(iph2); - delph2(iph2); + ike_session_unlink_phase2(iph2); + if (i_spi) { + j++; + } } - plog(LLV_INFO, LOCATION, NULL, - "purged IPsec-SA proto_id=%s spi=%u.\n", - s_ipsecdoi_proto(proto), - ntohl(spi[i])); + plog(ASL_LEVEL_NOTICE, "Purged IPsec-SA proto_id=%s spi=%u.\n", + s_ipsecdoi_proto(proto), + ntohl(spi[i])); } msg = next; } + if (max_inbound_spi) { + *max_inbound_spi = j; + } + if (buf) vfree(buf); } @@ -1592,17 +1573,16 @@ purge_ipsec_spi(dst0, proto, spi, n) * Sun IKE behavior, and makes rekeying work much better when the peer * restarts. */ -static void -info_recv_initialcontact(iph1) - struct ph1handle *iph1; +void +info_recv_initialcontact(phase1_handle_t *iph1) { vchar_t *buf = NULL; struct sadb_msg *msg, *next, *end; struct sadb_sa *sa; - struct sockaddr *src, *dst; + struct sockaddr_storage *src, *dst; caddr_t mhp[SADB_EXT_MAX + 1]; int proto_id, i; - struct ph2handle *iph2; + phase2_handle_t *iph2; #if 0 char *loc, *rem; #endif @@ -1625,35 +1605,35 @@ info_recv_initialcontact(iph1) for (i = 0; i < pfkey_nsatypes; i++) { proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype); - plog(LLV_INFO, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "purging %s SAs for %s -> %s\n", pfkey_satypes[i].ps_name, loc, rem); if (pfkey_send_delete_all(lcconf->sock_pfkey, pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, iph1->local, iph1->remote) == -1) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "delete_all %s -> %s failed for %s (%s)\n", loc, rem, pfkey_satypes[i].ps_name, ipsec_strerror()); goto the_hard_way; } - deleteallph2(iph1->local, iph1->remote, proto_id); + ike_session_deleteallph2(iph1->local, iph1->remote, proto_id); - plog(LLV_INFO, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "purging %s SAs for %s -> %s\n", pfkey_satypes[i].ps_name, rem, loc); if (pfkey_send_delete_all(lcconf->sock_pfkey, pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, iph1->remote, iph1->local) == -1) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "delete_all %s -> %s failed for %s (%s)\n", rem, loc, pfkey_satypes[i].ps_name, ipsec_strerror()); goto the_hard_way; } - deleteallph2(iph1->remote, iph1->local, proto_id); + ike_session_deleteallph2(iph1->remote, iph1->local, proto_id); } racoon_free(loc); @@ -1667,25 +1647,25 @@ info_recv_initialcontact(iph1) buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); if (buf == NULL) { - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "pfkey_dump_sadb returned nothing.\n"); return; } - msg = (struct sadb_msg *)buf->v; - end = (struct sadb_msg *)(buf->v + buf->l); + msg = ALIGNED_CAST(struct sadb_msg *)buf->v; + end = ALIGNED_CAST(struct sadb_msg *)(buf->v + buf->l); while (msg < end) { if ((msg->sadb_msg_len << 3) < sizeof(*msg)) break; - next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); + next = ALIGNED_CAST(struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); if (msg->sadb_msg_type != SADB_DUMP) { msg = next; continue; } if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "pfkey_check (%s)\n", ipsec_strerror()); msg = next; continue; @@ -1697,9 +1677,9 @@ info_recv_initialcontact(iph1) msg = next; continue; } - sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; - src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); - dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; // Wcast-align fix (void*) - buffer of pointers to aligned structs + src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); if (sa->sadb_sa_state != SADB_SASTATE_MATURE && sa->sadb_sa_state != SADB_SASTATE_DYING) { @@ -1764,7 +1744,7 @@ info_recv_initialcontact(iph1) continue; } - plog(LLV_INFO, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "purging spi=%u.\n", ntohl(sa->sadb_sa_spi)); pfkey_send_delete(lcconf->sock_pfkey, msg->sadb_msg_satype, @@ -1776,12 +1756,10 @@ info_recv_initialcontact(iph1) * exists. */ proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); - iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); + iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); if (iph2) { delete_spd(iph2); - unbindph12(iph2); - remph2(iph2); - delph2(iph2); + ike_session_unlink_phase2(iph2); } msg = next; @@ -1791,13 +1769,11 @@ info_recv_initialcontact(iph1) } void -isakmp_check_notify(gen, iph1) - struct isakmp_gen *gen; /* points to Notify payload */ - struct ph1handle *iph1; +isakmp_check_notify(struct isakmp_gen *gen /* points to Notify payload */, phase1_handle_t *iph1) { struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen; - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "Notify Message received\n"); switch (ntohs(notify->type)) { @@ -1808,24 +1784,24 @@ isakmp_check_notify(gen, iph1) #ifdef ENABLE_HYBRID case ISAKMP_NTYPE_UNITY_HEARTBEAT: #endif - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore %s notification.\n", + plog(ASL_LEVEL_WARNING, + "Ignore %s notification.\n", s_isakmp_notify_msg(ntohs(notify->type))); break; case ISAKMP_NTYPE_INITIAL_CONTACT: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore INITIAL-CONTACT notification, " - "because it is only accepted after phase1.\n"); + plog(ASL_LEVEL_WARNING, + "Ignore INITIAL-CONTACT notification, " + "because it is only accepted after Phase 1.\n"); break; case ISAKMP_NTYPE_LOAD_BALANCE: - plog(LLV_WARNING, LOCATION, iph1->remote, - "ignore LOAD-BALANCE notification, " - "because it is only accepted after phase1.\n"); + plog(ASL_LEVEL_WARNING, + "Ignore LOAD-BALANCE notification, " + "because it is only accepted after Phase 1.\n"); break; default: isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); - plog(LLV_ERROR, LOCATION, iph1->remote, - "received unknown notification type %s.\n", + plog(ASL_LEVEL_ERR, + "Received unknown notification type %s.\n", s_isakmp_notify_msg(ntohs(notify->type))); } @@ -1833,14 +1809,12 @@ isakmp_check_notify(gen, iph1) } void -isakmp_check_ph2_notify(gen, iph2) -struct isakmp_gen *gen; /* points to Notify payload */ -struct ph2handle *iph2; +isakmp_check_ph2_notify(struct isakmp_gen *gen /* points to Notify payload */, phase2_handle_t *iph2) { struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen; - plog(LLV_DEBUG, LOCATION, iph2->dst, - "Phase2 Notify Message received\n"); + plog(ASL_LEVEL_NOTICE, + "Phase 2 Notify Message received\n"); switch (ntohs(notify->type)) { case ISAKMP_NTYPE_RESPONDER_LIFETIME: @@ -1853,24 +1827,24 @@ struct ph2handle *iph2; #ifdef ENABLE_HYBRID case ISAKMP_NTYPE_UNITY_HEARTBEAT: #endif - plog(LLV_WARNING, LOCATION, iph2->dst, - "ignore %s notification.\n", + plog(ASL_LEVEL_WARNING, + "Ignore %s notification.\n", s_isakmp_notify_msg(ntohs(notify->type))); break; case ISAKMP_NTYPE_INITIAL_CONTACT: - plog(LLV_WARNING, LOCATION, iph2->dst, - "ignore INITIAL-CONTACT notification, " - "because it is only accepted after phase1.\n"); + plog(ASL_LEVEL_WARNING, + "Ignore INITIAL-CONTACT notification, " + "because it is only accepted after Phase 1.\n"); break; case ISAKMP_NTYPE_LOAD_BALANCE: - plog(LLV_WARNING, LOCATION, iph2->dst, - "ignore LOAD-BALANCE notification, " - "because it is only accepted after phase1.\n"); + plog(ASL_LEVEL_WARNING, + "Ignore LOAD-BALANCE notification, " + "because it is only accepted after Phase 1.\n"); break; default: isakmp_info_send_n1(iph2->ph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); - plog(LLV_ERROR, LOCATION, iph2->dst, - "received unknown notification type %s.\n", + plog(ASL_LEVEL_ERR, + "Received unknown notification type %s.\n", s_isakmp_notify_msg(ntohs(notify->type))); } @@ -1879,46 +1853,38 @@ struct ph2handle *iph2; #ifdef ENABLE_VPNCONTROL_PORT static int -isakmp_info_recv_lb(iph1, n, encrypted) - struct ph1handle *iph1; - struct isakmp_pl_lb *n; - int encrypted; +isakmp_info_recv_lb(phase1_handle_t *iph1, struct isakmp_pl_lb *n, int encrypted) { if (iph1->side != INITIATOR) { - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "LOAD-BALANCE notification ignored - we are not the initiator.\n"); return 0; } - if (iph1->remote->sa_family != AF_INET) { - plog(LLV_DEBUG, LOCATION, NULL, - "LOAD-BALANCE notification ignored - only supported for IPv4.\n"); - return 0; - } if (!encrypted) { - plog(LLV_DEBUG, LOCATION, NULL, + plog(ASL_LEVEL_NOTICE, "LOAD-BALANCE notification ignored - not protected.\n"); return 0; } if (ntohs(n->h.len) != sizeof(struct isakmp_pl_lb)) { - plog(LLV_DEBUG, LOCATION, NULL, - "Invalid length of payload\n"); + plog(ASL_LEVEL_NOTICE, + "isakmp_info_recv_lb Invalid length of payload\n"); return -1; - } + } + vpncontrol_notify_ike_failed(ISAKMP_NTYPE_LOAD_BALANCE, FROM_REMOTE, - ((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr, 4, (u_int8_t*)(&(n->address))); + iph1_get_remote_v4_address(iph1), 4, (u_int8_t*)(&(n->address))); - plog(LLV_DEBUG, LOCATION, iph1->remote, - "received LOAD_BALANCE notification - redirect address=%x.\n", - ntohl(n->address)); + plog(ASL_LEVEL_NOTICE, + "Received LOAD_BALANCE notification.\n"); if (((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr != ntohl(n->address)) { - plog(LLV_DEBUG, LOCATION, iph1->remote, - "deleting old phase1 because of LOAD_BALANCE notification - redirect address=%x.\n", + plog(ASL_LEVEL_NOTICE, + "Deleting old Phase 1 because of LOAD_BALANCE notification - redirect address=%x.\n", ntohl(n->address)); - if (iph1->status == PHASE1ST_ESTABLISHED) { + if (FSM_STATE_IS_ESTABLISHED(iph1->status)) { isakmp_info_send_d1(iph1); } isakmp_ph1expire(iph1); @@ -1930,17 +1896,14 @@ isakmp_info_recv_lb(iph1, n, encrypted) #ifdef ENABLE_DPD static int -isakmp_info_recv_r_u (iph1, ru, msgid) - struct ph1handle *iph1; - struct isakmp_pl_ru *ru; - u_int32_t msgid; +isakmp_info_recv_r_u (phase1_handle_t *iph1, struct isakmp_pl_ru *ru, u_int32_t msgid) { struct isakmp_pl_ru *ru_ack; vchar_t *payload = NULL; int tlen; int error = 0; - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "DPD R-U-There received\n"); /* XXX should compare cookies with iph1->index? @@ -1952,7 +1915,7 @@ isakmp_info_recv_r_u (iph1, ru, msgid) IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, CONSTSTR("R-U-THERE? ACK"), CONSTSTR("Failed to transmit DPD response")); - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer to send.\n"); return errno; } @@ -1984,27 +1947,24 @@ isakmp_info_recv_r_u (iph1, ru, msgid) CONSTSTR(NULL)); } - plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n"); + plog(ASL_LEVEL_NOTICE, "received a valid R-U-THERE, ACK sent\n"); /* Should we mark tunnel as active ? */ return error; } static int -isakmp_info_recv_r_u_ack (iph1, ru, msgid) - struct ph1handle *iph1; - struct isakmp_pl_ru *ru; - u_int32_t msgid; +isakmp_info_recv_r_u_ack (phase1_handle_t *iph1, struct isakmp_pl_ru *ru, u_int32_t msgid) { - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "DPD R-U-There-Ack received\n"); /* XXX Maintain window of acceptable sequence numbers ? * => ru->data <= iph2->dpd_seq && * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */ if (ntohl(ru->data) != iph1->dpd_seq) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "Wrong DPD sequence number (%d, %d expected).\n", ntohl(ru->data), iph1->dpd_seq); return 0; @@ -2012,7 +1972,7 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid) if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) || memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) { - plog(LLV_ERROR, LOCATION, iph1->remote, + plog(ASL_LEVEL_ERR, "Cookie mismatch in DPD ACK!.\n"); return 0; } @@ -2039,7 +1999,11 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid) CONSTSTR("Responder DPD Response"), CONSTSTR(NULL)); } - plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n"); + plog(ASL_LEVEL_NOTICE, "received an R-U-THERE-ACK\n"); + +#ifdef ENABLE_VPNCONTROL_PORT + vpncontrol_notify_peer_resp_ph1(1, iph1); +#endif /* ENABLE_VPNCONTROL_PORT */ return 0; } @@ -2049,10 +2013,9 @@ isakmp_info_recv_r_u_ack (iph1, ru, msgid) * send Delete payload (for ISAKMP SA) in Informational exchange. */ void -isakmp_info_send_r_u(arg) - void *arg; +isakmp_info_send_r_u(void *arg) { - struct ph1handle *iph1 = arg; + phase1_handle_t *iph1 = arg; /* create R-U-THERE payload */ struct isakmp_pl_ru *ru; @@ -2060,29 +2023,22 @@ isakmp_info_send_r_u(arg) int tlen; int error = 0; - if (iph1->status != PHASE1ST_ESTABLISHED) { - plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD r-u send aborted, invalid phase1 status %d....\n", + if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) { + plog(ASL_LEVEL_NOTICE, "DPD r-u send aborted, invalid Phase 1 status %d....\n", iph1->status); return; } if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) { - u_int32_t address; - IPSECSESSIONTRACEREVENT(iph1->parent_session, IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT, CONSTSTR("DPD maximum retransmits"), CONSTSTR("maxed-out of DPD requests without receiving an ack")); - EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL); - if (iph1->remote->sa_family == AF_INET) - address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; - else - address = 0; - (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PEER_DEAD, FROM_LOCAL, address, 0, NULL); + (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PEER_DEAD, FROM_LOCAL, iph1_get_remote_v4_address(iph1), 0, NULL); purge_remote(iph1); - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "DPD: remote seems to be dead\n"); /* Do not reschedule here: phase1 is deleted, @@ -2098,7 +2054,7 @@ isakmp_info_send_r_u(arg) IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, CONSTSTR("R-U-THERE?"), CONSTSTR("Failed to transmit DPD request")); - plog(LLV_ERROR, LOCATION, NULL, + plog(ASL_LEVEL_ERR, "failed to get buffer for payload.\n"); return; } @@ -2146,7 +2102,7 @@ isakmp_info_send_r_u(arg) CONSTSTR("Responder DPD Request"), CONSTSTR(NULL)); } - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "DPD R-U-There sent (%d)\n", error); /* will be decreased if ACK received... */ @@ -2156,7 +2112,7 @@ isakmp_info_send_r_u(arg) * will be deleted/rescheduled if ACK received before */ isakmp_sched_r_u(iph1, 1); - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry); } @@ -2164,15 +2120,15 @@ isakmp_info_send_r_u(arg) * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange. */ static void -isakmp_info_monitor_r_u_algo_inbound_detect (struct ph1handle *iph1) +isakmp_info_monitor_r_u_algo_inbound_detect (phase1_handle_t *iph1) { - if (iph1->status != PHASE1ST_ESTABLISHED) { - plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) aborted, invalid phase1 status %d....\n", + if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) { + plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) aborted, invalid Phase 1 status %d....\n", iph1->status); return; } - plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) ....\n"); + plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) ....\n"); // check phase1 for ike packets received from peer if (iph1->peer_sent_ike) { @@ -2182,7 +2138,7 @@ isakmp_info_monitor_r_u_algo_inbound_detect (struct ph1handle *iph1) /* ike packets received from peer... reschedule dpd */ isakmp_sched_r_u(iph1, 0); - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "ike packets received from peer... reschedule monitor.\n"); return; @@ -2194,25 +2150,25 @@ isakmp_info_monitor_r_u_algo_inbound_detect (struct ph1handle *iph1) } else { isakmp_sched_r_u(iph1, 0); - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "rescheduling DPD monitoring (for ALGORITHM_INBOUND_DETECT).\n"); } iph1->parent_session->peer_sent_data_sc_dpd = 0; } /* - * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange. + * monitor DPD (ALGORITHM_BLACKHOLE_DETECT) Informational exchange. */ static void -isakmp_info_monitor_r_u_algo_blackhole_detect (struct ph1handle *iph1) +isakmp_info_monitor_r_u_algo_blackhole_detect (phase1_handle_t *iph1) { - if (iph1->status != PHASE1ST_ESTABLISHED) { - plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) aborted, invalid phase1 status %d....\n", + if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) { + plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) aborted, invalid Phase 1 status %d....\n", iph1->status); return; } - plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) ....\n"); + plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) ....\n"); // check if data was sent but none was received if (iph1->parent_session->i_sent_data_sc_dpd && @@ -2221,7 +2177,7 @@ isakmp_info_monitor_r_u_algo_blackhole_detect (struct ph1handle *iph1) } else { isakmp_sched_r_u(iph1, 0); - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "rescheduling DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) i = %d, peer %d.\n", iph1->parent_session->i_sent_data_sc_dpd, iph1->parent_session->peer_sent_data_sc_dpd); @@ -2234,10 +2190,9 @@ isakmp_info_monitor_r_u_algo_blackhole_detect (struct ph1handle *iph1) * monitor DPD Informational exchange. */ static void -isakmp_info_monitor_r_u(arg) -void *arg; +isakmp_info_monitor_r_u(void *arg) { - struct ph1handle *iph1 = arg; + phase1_handle_t *iph1 = arg; if (iph1 && iph1->rmconf) { if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT) { @@ -2245,7 +2200,7 @@ void *arg; } else if (iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) { isakmp_info_monitor_r_u_algo_blackhole_detect(iph1); } else { - plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring aborted, invalid algorithm %d....\n", + plog(ASL_LEVEL_NOTICE, "DPD monitoring aborted, invalid algorithm %d....\n", iph1->rmconf->dpd_algo); } } @@ -2253,9 +2208,7 @@ void *arg; /* Schedule a new R-U-THERE */ int -isakmp_sched_r_u(iph1, retry) - struct ph1handle *iph1; - int retry; +isakmp_sched_r_u(phase1_handle_t *iph1, int retry) { if(iph1 == NULL || iph1->rmconf == NULL) @@ -2289,11 +2242,10 @@ isakmp_sched_r_u(iph1, retry) * 2) indicates liveness (e.g. received ike packets). */ void -isakmp_reschedule_info_monitor_if_pending (struct ph1handle *iph1, - char *reason) +isakmp_reschedule_info_monitor_if_pending (phase1_handle_t *iph1, char *reason) { if (!iph1 || - iph1->status != PHASE1ST_ESTABLISHED || + !FSM_STATE_IS_ESTABLISHED(iph1->status) || !iph1->dpd_support || !iph1->rmconf->dpd_interval || iph1->rmconf->dpd_algo == DPD_ALGO_DEFAULT) { @@ -2305,7 +2257,7 @@ isakmp_reschedule_info_monitor_if_pending (struct ph1handle *iph1, isakmp_sched_r_u(iph1, 0); - plog(LLV_DEBUG, LOCATION, iph1->remote, + plog(ASL_LEVEL_NOTICE, "%s... rescheduling send_r_u.\n", reason); }