| File: | programs/pluto/ikev2_ike_auth.c |
| Warning: | line 494, column 8 Access to field 'policy' results in a dereference of a null pointer (loaded from variable 'cc') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * IKEv2 parent SA creation routines, for Libreswan | |||
| 3 | * | |||
| 4 | * Copyright (C) 2007-2008 Michael Richardson <mcr@xelerance.com> | |||
| 5 | * Copyright (C) 2008-2011 Paul Wouters <paul@xelerance.com> | |||
| 6 | * Copyright (C) 2008 Antony Antony <antony@xelerance.com> | |||
| 7 | * Copyright (C) 2008-2009 David McCullough <david_mccullough@securecomputing.com> | |||
| 8 | * Copyright (C) 2010,2012 Avesh Agarwal <avagarwa@redhat.com> | |||
| 9 | * Copyright (C) 2010-2019 Tuomo Soini <tis@foobar.fi | |||
| 10 | * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com> | |||
| 11 | * Copyright (C) 2012-2018 Antony Antony <antony@phenome.org> | |||
| 12 | * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com> | |||
| 13 | * Copyright (C) 2013 David McCullough <ucdevel@gmail.com> | |||
| 14 | * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com> | |||
| 15 | * Copyright (C) 2015-2019 Andrew Cagney <cagney@gnu.org> | |||
| 16 | * Copyright (C) 2017-2018 Sahana Prasad <sahana.prasad07@gmail.com> | |||
| 17 | * Copyright (C) 2017-2018 Vukasin Karadzic <vukasin.karadzic@gmail.com> | |||
| 18 | * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com> | |||
| 19 | * Copyright (C) 2020 Yulia Kuzovkova <ukuzovkova@gmail.com> | |||
| 20 | * | |||
| 21 | * This program is free software; you can redistribute it and/or modify it | |||
| 22 | * under the terms of the GNU General Public License as published by the | |||
| 23 | * Free Software Foundation; either version 2 of the License, or (at your | |||
| 24 | * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>. | |||
| 25 | * | |||
| 26 | * This program is distributed in the hope that it will be useful, but | |||
| 27 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |||
| 28 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
| 29 | * for more details. | |||
| 30 | * | |||
| 31 | */ | |||
| 32 | ||||
| 33 | #include "defs.h" | |||
| 34 | #include "log.h" | |||
| 35 | #include "demux.h" | |||
| 36 | #include "state.h" | |||
| 37 | #include "crypt_dh.h" | |||
| 38 | #include "ikev2_send.h" | |||
| 39 | #include "ikev2.h" | |||
| 40 | #include "connections.h" | |||
| 41 | #include "secrets.h" | |||
| 42 | #include "ikev2_message.h" | |||
| 43 | #ifdef USE_PAM_AUTH1 | |||
| 44 | #include "pam_auth.h" | |||
| 45 | #endif | |||
| 46 | #include "pluto_x509.h" | |||
| 47 | #include "ikev2_ike_auth.h" | |||
| 48 | #include "pending.h" | |||
| 49 | #include "pluto_stats.h" | |||
| 50 | #include "cert_decode_helper.h" | |||
| 51 | #include "ikev2_child.h" | |||
| 52 | #include "ikev2_peer_id.h" | |||
| 53 | #include "crypt_symkey.h" | |||
| 54 | #include "nat_traversal.h" | |||
| 55 | #include "ikev2_auth.h" | |||
| 56 | #include "ikev2_redirect.h" | |||
| 57 | #include "ikev2_ipseckey.h" | |||
| 58 | #include "ikev2_ppk.h" | |||
| 59 | #include "keys.h" | |||
| 60 | #include "ike_alg_hash.h" | |||
| 61 | #include "ikev2_cp.h" | |||
| 62 | #include "kernel.h" /* for raw_policy() */ | |||
| 63 | #include "ikev2_delete.h" /* for submit_v2_delete_exchange() */ | |||
| 64 | ||||
| 65 | static stf_status process_v2_IKE_AUTH_request_tail(struct state *st, | |||
| 66 | struct msg_digest *md, | |||
| 67 | bool_Bool pam_status); | |||
| 68 | ||||
| 69 | static stf_status ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue(struct ike_sa *ike, | |||
| 70 | struct msg_digest *md, | |||
| 71 | const struct hash_signature *sig); | |||
| 72 | ||||
| 73 | ||||
| 74 | stf_status ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_continue(struct state *ike_st, | |||
| 75 | struct msg_digest *md) | |||
| 76 | { | |||
| 77 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
| 78 | pexpect(ike->sa.st_sa_role == SA_INITIATOR)({ _Bool assertion__ = ike->sa.st_sa_role == SA_INITIATOR; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 78, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sa_role == SA_INITIATOR" ); } assertion__; }); | |||
| ||||
| 79 | pexpect(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 79, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } assertion__; }); /* i.e., MD!=NULL */ | |||
| 80 | dbg("%s() for #%lu %s: g^{xy} calculated, sending IKE_AUTH",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: g^{xy} calculated, sending IKE_AUTH" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } } | |||
| 81 | __func__, ike->sa.st_serialno, ike->sa.st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: g^{xy} calculated, sending IKE_AUTH" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } }; | |||
| 82 | ||||
| 83 | struct connection *const pc = ike->sa.st_connection; /* parent connection */ | |||
| 84 | ||||
| 85 | if (!(md->hdr.isa_xchg == ISAKMP_v2_IKE_INTERMEDIATE)) { | |||
| 86 | if (ike->sa.st_dh_shared_secret == NULL((void*)0)) { | |||
| 87 | /* | |||
| 88 | * XXX: this is the initiator so returning a | |||
| 89 | * notification is kind of useless. | |||
| 90 | */ | |||
| 91 | pstat_sa_failed(&ike->sa, REASON_CRYPTO_FAILED); | |||
| 92 | return STF_FAIL; | |||
| 93 | } | |||
| 94 | calc_v2_keymat(&ike->sa, NULL((void*)0), NULL((void*)0), /*no old keymat*/ | |||
| 95 | &ike->sa.st_ike_rekey_spis); | |||
| 96 | } | |||
| 97 | ||||
| 98 | /* | |||
| 99 | * All systems are go. | |||
| 100 | * | |||
| 101 | * Since DH succeeded, a secure (but unauthenticated) SA | |||
| 102 | * (channel) is available. From this point on, should things | |||
| 103 | * go south, the state needs to be abandoned (but it shouldn't | |||
| 104 | * happen). | |||
| 105 | */ | |||
| 106 | ||||
| 107 | /* | |||
| 108 | * Since systems are go, start updating the state, starting | |||
| 109 | * with SPIr. | |||
| 110 | */ | |||
| 111 | rehash_state(&ike->sa, &md->hdr.isa_ike_responder_spiisa_ike_spis.responder); | |||
| 112 | ||||
| 113 | /* | |||
| 114 | * If we and responder are willing to use a PPK, we need to | |||
| 115 | * generate NO_PPK_AUTH as well as PPK-based AUTH payload. | |||
| 116 | * | |||
| 117 | * Stash the no-ppk keys in st_skey_*_no_ppk, and then | |||
| 118 | * scramble the st_skey_* keys with PPK. | |||
| 119 | */ | |||
| 120 | if (LIN(POLICY_PPK_ALLOW, pc->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (pc-> policy)) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX)))) && ike->sa.st_seen_ppk) { | |||
| 121 | chunk_t *ppk_id; | |||
| 122 | chunk_t *ppk = get_connection_ppk(ike->sa.st_connection, &ppk_id); | |||
| 123 | ||||
| 124 | if (ppk != NULL((void*)0)) { | |||
| 125 | dbg("found PPK and PPK_ID for our connection"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("found PPK and PPK_ID for our connection"); } }; | |||
| 126 | ||||
| 127 | pexpect(ike->sa.st_sk_d_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_d_no_ppk == ((void*)0 ); if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 127, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sk_d_no_ppk == ((void*)0)" ); } assertion__; }); | |||
| 128 | ike->sa.st_sk_d_no_ppk = reference_symkey(__func__, "sk_d_no_ppk", ike->sa.st_skey_d_nss); | |||
| 129 | ||||
| 130 | pexpect(ike->sa.st_sk_pi_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_pi_no_ppk == ((void*) 0); if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 130, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sk_pi_no_ppk == ((void*)0)" ); } assertion__; }); | |||
| 131 | ike->sa.st_sk_pi_no_ppk = reference_symkey(__func__, "sk_pi_no_ppk", ike->sa.st_skey_pi_nss); | |||
| 132 | ||||
| 133 | pexpect(ike->sa.st_sk_pr_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_pr_no_ppk == ((void*) 0); if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 133, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sk_pr_no_ppk == ((void*)0)" ); } assertion__; }); | |||
| 134 | ike->sa.st_sk_pr_no_ppk = reference_symkey(__func__, "sk_pr_no_ppk", ike->sa.st_skey_pr_nss); | |||
| 135 | ||||
| 136 | ppk_recalculate(ppk, ike->sa.st_oakley.ta_prf, | |||
| 137 | &ike->sa.st_skey_d_nss, | |||
| 138 | &ike->sa.st_skey_pi_nss, | |||
| 139 | &ike->sa.st_skey_pr_nss, | |||
| 140 | ike->sa.st_logger); | |||
| 141 | log_state(RC_LOG, &ike->sa, | |||
| 142 | "PPK AUTH calculated as initiator"); | |||
| 143 | } else { | |||
| 144 | if (pc->policy & POLICY_PPK_INSIST((lset_t)1 << (POLICY_PPK_INSIST_IX))) { | |||
| 145 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 146 | "connection requires PPK, but we didn't find one"); | |||
| 147 | return STF_FATAL; | |||
| 148 | } else { | |||
| 149 | log_state(RC_LOG, &ike->sa, | |||
| 150 | "failed to find PPK and PPK_ID, continuing without PPK"); | |||
| 151 | /* we should omit sending any PPK Identity, so we pretend we didn't see USE_PPK */ | |||
| 152 | ike->sa.st_seen_ppk = false0; | |||
| 153 | } | |||
| 154 | } | |||
| 155 | } | |||
| 156 | ||||
| 157 | /* | |||
| 158 | * Construct the IDi payload and store it in state so that it | |||
| 159 | * can be emitted later. Then use that to construct the | |||
| 160 | * "MACedIDFor[I]". | |||
| 161 | * | |||
| 162 | * Code assumes that struct ikev2_id's "IDType|RESERVED" is | |||
| 163 | * laid out the same as the packet. | |||
| 164 | */ | |||
| 165 | ||||
| 166 | { | |||
| 167 | shunk_t data; | |||
| 168 | ike->sa.st_v2_id_payload.header = build_v2_id_payload(&pc->spd.this, &data, | |||
| 169 | "my IDi", ike->sa.st_logger); | |||
| 170 | ike->sa.st_v2_id_payload.data = clone_hunk(data, "my IDi")({ typeof(data) hunk_ = data; clone_bytes_as_chunk(hunk_.ptr, hunk_.len, "my IDi"); }); | |||
| 171 | } | |||
| 172 | ||||
| 173 | ike->sa.st_v2_id_payload.mac = v2_hash_id_payload("IDi", ike, | |||
| 174 | "st_skey_pi_nss", | |||
| 175 | ike->sa.st_skey_pi_nss); | |||
| 176 | if (ike->sa.st_seen_ppk && !LIN(POLICY_PPK_INSIST, pc->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (pc-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
| 177 | /* ID payload that we've build is the same */ | |||
| 178 | ike->sa.st_v2_id_payload.mac_no_ppk_auth = | |||
| 179 | v2_hash_id_payload("IDi (no-PPK)", ike, | |||
| 180 | "sk_pi_no_pkk", | |||
| 181 | ike->sa.st_sk_pi_no_ppk); | |||
| 182 | } | |||
| 183 | ||||
| 184 | { | |||
| 185 | enum keyword_authby authby = v2_auth_by(ike); | |||
| 186 | enum ikev2_auth_method auth_method = v2_auth_method(ike, authby); | |||
| 187 | switch (auth_method) { | |||
| 188 | case IKEv2_AUTH_RSA: | |||
| 189 | { | |||
| 190 | const struct hash_desc *hash_algo = &ike_alg_hash_sha1; | |||
| 191 | struct crypt_mac hash_to_sign = | |||
| 192 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 193 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 194 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 195 | authby, auth_method, | |||
| 196 | ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue)) { | |||
| 197 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
| 198 | return STF_FATAL; | |||
| 199 | } | |||
| 200 | return STF_SUSPEND; | |||
| 201 | } | |||
| 202 | case IKEv2_AUTH_DIGSIG: | |||
| 203 | { | |||
| 204 | const struct hash_desc *hash_algo = v2_auth_negotiated_signature_hash(ike); | |||
| 205 | if (hash_algo == NULL((void*)0)) { | |||
| 206 | return STF_FATAL; | |||
| 207 | } | |||
| 208 | struct crypt_mac hash_to_sign = | |||
| 209 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 210 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 211 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 212 | authby, auth_method, | |||
| 213 | ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue)) { | |||
| 214 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
| 215 | return STF_FATAL; | |||
| 216 | } | |||
| 217 | return STF_SUSPEND; | |||
| 218 | } | |||
| 219 | case IKEv2_AUTH_PSK: | |||
| 220 | case IKEv2_AUTH_NULL: | |||
| 221 | { | |||
| 222 | struct hash_signature sig = { .len = 0, }; | |||
| 223 | return ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue(ike, md, &sig); | |||
| 224 | } | |||
| 225 | default: | |||
| 226 | log_state(RC_LOG, &ike->sa, | |||
| 227 | "authentication method %s not supported", | |||
| 228 | enum_name(&ikev2_auth_names, auth_method)); | |||
| 229 | return STF_FATAL; | |||
| 230 | } | |||
| 231 | } | |||
| 232 | } | |||
| 233 | ||||
| 234 | static stf_status ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue(struct ike_sa *ike, | |||
| 235 | struct msg_digest *md, | |||
| 236 | const struct hash_signature *auth_sig) | |||
| 237 | { | |||
| 238 | struct connection *const pc = ike->sa.st_connection; /* parent connection */ | |||
| 239 | ikev2_log_parentSA(&ike->sa); | |||
| 240 | ||||
| 241 | /* | |||
| 242 | * XXX: | |||
| 243 | * | |||
| 244 | * Should this code use clone_in_pbs_as_chunk() which uses | |||
| 245 | * pbs_room() (.roof-.start)? The original code: | |||
| 246 | * | |||
| 247 | * clonetochunk(st->st_firstpacket_peer, md->message_pbs.start, | |||
| 248 | * pbs_offset(&md->message_pbs), | |||
| 249 | * "saved first received packet"); | |||
| 250 | * | |||
| 251 | * and clone_out_pbs_as_chunk() both use pbs_offset() | |||
| 252 | * (.cur-.start). | |||
| 253 | * | |||
| 254 | * Suspect it doesn't matter as the code initializing | |||
| 255 | * .message_pbs forces .roof==.cur - look for the comment | |||
| 256 | * "trim padding (not actually legit)". | |||
| 257 | */ | |||
| 258 | /* record first packet for later checking of signature */ | |||
| 259 | if (md->hdr.isa_xchg
| |||
| 260 | replace_chunk(&ike->sa.st_firstpacket_peer, | |||
| 261 | clone_pbs_out_as_chunk(&md->message_pbs, "saved first received non-intermediate packet")); | |||
| 262 | } | |||
| 263 | /* beginning of data going out */ | |||
| 264 | ||||
| 265 | /* make sure HDR is at start of a clean buffer */ | |||
| 266 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
| 267 | reply_buffer, sizeof(reply_buffer), | |||
| 268 | ike->sa.st_logger); | |||
| 269 | ||||
| 270 | /* HDR out */ | |||
| 271 | ||||
| 272 | struct pbs_outpacket_byte_stream rbody = open_v2_message(&reply_stream, ike, | |||
| 273 | NULL((void*)0) /* request */, | |||
| 274 | ISAKMP_v2_IKE_AUTH); | |||
| 275 | if (!pbs_ok(&rbody)((&rbody)->start != ((void*)0))) { | |||
| 276 | return STF_INTERNAL_ERROR; | |||
| 277 | } | |||
| 278 | ||||
| 279 | /* insert an Encryption payload header (SK) */ | |||
| 280 | ||||
| 281 | struct v2SK_payload sk = open_v2SK_payload(ike->sa.st_logger, &rbody, ike); | |||
| 282 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
| 283 | return STF_INTERNAL_ERROR; | |||
| 284 | } | |||
| 285 | ||||
| 286 | /* actual data */ | |||
| 287 | ||||
| 288 | /* decide whether to send CERT payload */ | |||
| 289 | ||||
| 290 | bool_Bool send_cert = ikev2_send_cert_decision(ike); | |||
| 291 | bool_Bool ic = pc->initial_contact && (ike->sa.st_ike_pred == SOS_NOBODY0); | |||
| 292 | bool_Bool send_idr = ((pc->spd.that.id.kind != ID_NULL && pc->spd.that.id.name.len != 0) || | |||
| 293 | pc->spd.that.id.kind == ID_NULL); /* me tarzan, you jane */ | |||
| 294 | ||||
| 295 | if (impair.send_no_idr) { | |||
| 296 | log_state(RC_LOG, &ike->sa, "IMPAIR: omitting IDr payload"); | |||
| 297 | send_idr = false0; | |||
| 298 | } | |||
| 299 | ||||
| 300 | dbg("IDr payload will %sbe sent", send_idr ? "" : "NOT "){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("IDr payload will %sbe sent", send_idr ? "" : "NOT " ); } }; | |||
| 301 | ||||
| 302 | /* send out the IDi payload */ | |||
| 303 | ||||
| 304 | { | |||
| 305 | pb_stream i_id_pbs; | |||
| 306 | if (!out_struct(&ike->sa.st_v2_id_payload.header, | |||
| 307 | &ikev2_id_i_desc, | |||
| 308 | &sk.pbs, | |||
| 309 | &i_id_pbs) || | |||
| 310 | !out_hunk(ike->sa.st_v2_id_payload.data, &i_id_pbs, "my identity")({ typeof(ike->sa.st_v2_id_payload.data) hunk_ = ike->sa .st_v2_id_payload.data; struct packet_byte_stream *outs_ = & i_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_.len , ("my identity")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); })) | |||
| 311 | return STF_INTERNAL_ERROR; | |||
| 312 | close_output_pbs(&i_id_pbs); | |||
| 313 | } | |||
| 314 | ||||
| 315 | if (impair.add_unknown_v2_payload_to_sk == ISAKMP_v2_IKE_AUTH) { | |||
| 316 | if (!emit_v2UNKNOWN("SK request", | |||
| 317 | impair.add_unknown_v2_payload_to_sk, | |||
| 318 | &sk.pbs)) { | |||
| 319 | return STF_INTERNAL_ERROR; | |||
| 320 | } | |||
| 321 | } | |||
| 322 | ||||
| 323 | /* send [CERT,] payload RFC 4306 3.6, 1.2) */ | |||
| 324 | if (send_cert) { | |||
| 325 | stf_status certstat = ikev2_send_cert(ike->sa.st_connection, &sk.pbs); | |||
| 326 | if (certstat != STF_OK) | |||
| 327 | return certstat; | |||
| 328 | ||||
| 329 | /* send CERTREQ */ | |||
| 330 | bool_Bool send_certreq = ikev2_send_certreq_INIT_decision(&ike->sa, SA_INITIATOR); | |||
| 331 | if (send_certreq) { | |||
| 332 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 333 | dn_buf buf; | |||
| 334 | DBG_log("Sending [CERTREQ] of %s", | |||
| 335 | str_dn(ike->sa.st_connection->spd.that.ca, &buf)); | |||
| 336 | } | |||
| 337 | ikev2_send_certreq(&ike->sa, md, &sk.pbs); | |||
| 338 | } | |||
| 339 | } | |||
| 340 | ||||
| 341 | /* you Tarzan, me Jane support */ | |||
| 342 | if (send_idr
| |||
| 343 | switch (pc->spd.that.id.kind) { | |||
| 344 | case ID_DER_ASN1_DN: | |||
| 345 | case ID_FQDN: | |||
| 346 | case ID_USER_FQDN: | |||
| 347 | case ID_KEY_ID: | |||
| 348 | case ID_NULL: | |||
| 349 | { | |||
| 350 | shunk_t id_b; | |||
| 351 | struct ikev2_id r_id = build_v2_id_payload(&pc->spd.that, &id_b, | |||
| 352 | "their IDr", | |||
| 353 | ike->sa.st_logger); | |||
| 354 | pb_stream r_id_pbs; | |||
| 355 | if (!out_struct(&r_id, &ikev2_id_r_desc, &sk.pbs, | |||
| 356 | &r_id_pbs) || | |||
| 357 | !out_hunk(id_b, &r_id_pbs, "their IDr")({ typeof(id_b) hunk_ = id_b; struct packet_byte_stream *outs_ = &r_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_ .len, ("their IDr")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); })) | |||
| 358 | return STF_INTERNAL_ERROR; | |||
| 359 | ||||
| 360 | close_output_pbs(&r_id_pbs); | |||
| 361 | break; | |||
| 362 | } | |||
| 363 | default: | |||
| 364 | { | |||
| 365 | esb_buf b; | |||
| 366 | dbg("Not sending IDr payload for remote ID type %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Not sending IDr payload for remote ID type %s" , enum_show(&ike_id_type_names, pc->spd.that.id.kind, & b)); } } | |||
| 367 | enum_show(&ike_id_type_names, pc->spd.that.id.kind, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Not sending IDr payload for remote ID type %s" , enum_show(&ike_id_type_names, pc->spd.that.id.kind, & b)); } }; | |||
| 368 | break; | |||
| 369 | } | |||
| 370 | } | |||
| 371 | } | |||
| 372 | ||||
| 373 | if (ic
| |||
| 374 | log_state(RC_LOG, &ike->sa, "sending INITIAL_CONTACT"); | |||
| 375 | if (!emit_v2N(v2N_INITIAL_CONTACT, &sk.pbs)) | |||
| 376 | return STF_INTERNAL_ERROR; | |||
| 377 | } else { | |||
| 378 | dbg("not sending INITIAL_CONTACT"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("not sending INITIAL_CONTACT"); } }; | |||
| 379 | } | |||
| 380 | ||||
| 381 | /* send out the AUTH payload */ | |||
| 382 | ||||
| 383 | if (!emit_v2_auth(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, &sk.pbs)) { | |||
| 384 | return STF_INTERNAL_ERROR; | |||
| 385 | } | |||
| 386 | ||||
| 387 | if (LIN(POLICY_MOBIKE, ike->sa.st_connection->policy)(((((lset_t)1 << (POLICY_MOBIKE_IX))) & (ike->sa .st_connection->policy)) == (((lset_t)1 << (POLICY_MOBIKE_IX ))))) { | |||
| 388 | ike->sa.st_ike_sent_v2n_mobike_supported = true1; | |||
| 389 | if (!emit_v2N(v2N_MOBIKE_SUPPORTED, &sk.pbs)) { | |||
| 390 | return STF_INTERNAL_ERROR; | |||
| 391 | } | |||
| 392 | } | |||
| 393 | ||||
| 394 | /* | |||
| 395 | * Now that the AUTH payload is done(?), create and emit the | |||
| 396 | * child using the first pending connection (or the IKE SA's | |||
| 397 | * connection) if there isn't one. | |||
| 398 | * | |||
| 399 | * Then emit SA2i, TSi and TSr and NOTIFY payloads related to | |||
| 400 | * the IPsec SA. | |||
| 401 | */ | |||
| 402 | ||||
| 403 | /* Child Connection */ | |||
| 404 | lset_t unused_policy = pc->policy; /* unused */ | |||
| 405 | struct fd *child_whackfd = null_fd((struct fd *) ((void*)0)); /* must-free */ | |||
| 406 | struct connection *cc = first_pending(ike, &unused_policy, &child_whackfd); | |||
| 407 | if (cc == NULL((void*)0)) { | |||
| 408 | llog_sa(RC_LOG, ike, "omitting CHILD SA payloads")llog(RC_LOG, (ike)->sa.st_logger, "omitting CHILD SA payloads" ); | |||
| 409 | } else { | |||
| 410 | /* | |||
| 411 | * XXX: The problem isn't so much that the child state is | |||
| 412 | * created - it provides somewhere to store all the child's | |||
| 413 | * state - but that things switch to the child before the IKE | |||
| 414 | * SA is finished. Consequently, code is forced to switch | |||
| 415 | * back to the IKE SA. | |||
| 416 | */ | |||
| 417 | struct child_sa *child = new_v2_child_state(cc, ike, IPSEC_SA, | |||
| 418 | SA_INITIATOR, | |||
| 419 | STATE_V2_IKE_AUTH_CHILD_I0, | |||
| 420 | child_whackfd); | |||
| 421 | close_any(&child_whackfd)close_any_fd((&child_whackfd), ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 421, }; &here; })); | |||
| 422 | ike->sa.st_v2_larval_initiator_sa = child; | |||
| 423 | ||||
| 424 | /* | |||
| 425 | * XXX because the early child state ends up with the | |||
| 426 | * try counter check, we need to copy it. | |||
| 427 | * | |||
| 428 | * XXX: huh?!? | |||
| 429 | */ | |||
| 430 | child->sa.st_try = ike->sa.st_try; | |||
| 431 | ||||
| 432 | if (cc != pc) { | |||
| 433 | /* lie */ | |||
| 434 | connection_buf cib; | |||
| 435 | log_state(RC_LOG, &ike->sa, | |||
| 436 | "switching CHILD #%lu to pending connection "PRI_CONNECTION"\"%s\"%s", | |||
| 437 | child->sa.st_serialno, pri_connection(cc, &cib)(cc)->name, str_connection_instance(cc, &cib)); | |||
| 438 | } | |||
| 439 | ||||
| 440 | if (!prep_v2_child_for_request(child)) { | |||
| 441 | return STF_INTERNAL_ERROR; | |||
| 442 | } | |||
| 443 | ||||
| 444 | /* XXX: look further down you're seeing double */ | |||
| 445 | if (need_v2_configuration_payload(child->sa.st_connection, | |||
| 446 | ike->sa.hidden_variables.st_nat_traversal)) { | |||
| 447 | if (!emit_v2_child_configuration_payload(child, &sk.pbs)) { | |||
| 448 | return STF_INTERNAL_ERROR; | |||
| 449 | } | |||
| 450 | } | |||
| 451 | ||||
| 452 | /* | |||
| 453 | * A CHILD_SA established during an AUTH exchange does | |||
| 454 | * not propose DH - the IKE SA's SKEYSEED is always | |||
| 455 | * used. | |||
| 456 | */ | |||
| 457 | struct ikev2_proposals *child_proposals = | |||
| 458 | get_v2_ike_auth_child_proposals(cc, "IKE SA initiator emitting ESP/AH proposals", | |||
| 459 | child->sa.st_logger); | |||
| 460 | ||||
| 461 | if (!emit_v2_child_request_payloads(child, child_proposals, &sk.pbs)) { | |||
| 462 | return STF_INTERNAL_ERROR; | |||
| 463 | } | |||
| 464 | ||||
| 465 | /* send CP payloads */ | |||
| 466 | if (cc->modecfg_domains != NULL((void*)0) || cc->modecfg_dns != NULL((void*)0)) { | |||
| 467 | if (!emit_v2_child_configuration_payload(child, &sk.pbs)) { | |||
| 468 | return STF_INTERNAL_ERROR; | |||
| 469 | } | |||
| 470 | } | |||
| 471 | } | |||
| 472 | ||||
| 473 | /* | |||
| 474 | * If we and responder are willing to use a PPK, we need to | |||
| 475 | * generate NO_PPK_AUTH as well as PPK-based AUTH payload | |||
| 476 | */ | |||
| 477 | if (ike->sa.st_seen_ppk) { | |||
| 478 | chunk_t *ppk_id; | |||
| 479 | get_connection_ppk(ike->sa.st_connection, &ppk_id); | |||
| 480 | struct ppk_id_payload ppk_id_p = { .type = 0, }; | |||
| 481 | create_ppk_id_payload(ppk_id, &ppk_id_p); | |||
| 482 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 483 | DBG_log("ppk type: %d", (int) ppk_id_p.type); | |||
| 484 | DBG_dump_hunk("ppk_id from payload:", ppk_id_p.ppk_id){ typeof(ppk_id_p.ppk_id) hunk_ = ppk_id_p.ppk_id; DBG_dump("ppk_id from payload:" , hunk_.ptr, hunk_.len); }; | |||
| 485 | } | |||
| 486 | ||||
| 487 | pb_stream ppks; | |||
| 488 | if (!emit_v2Npl(v2N_PPK_IDENTITY, &sk.pbs, &ppks) || | |||
| 489 | !emit_unified_ppk_id(&ppk_id_p, &ppks)) { | |||
| 490 | return STF_INTERNAL_ERROR; | |||
| 491 | } | |||
| 492 | close_output_pbs(&ppks); | |||
| 493 | ||||
| 494 | if (!LIN(POLICY_PPK_INSIST, cc->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (cc-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
| ||||
| 495 | if (!ikev2_calc_no_ppk_auth(ike, &ike->sa.st_v2_id_payload.mac_no_ppk_auth, | |||
| 496 | &ike->sa.st_no_ppk_auth)) { | |||
| 497 | dbg("ikev2_calc_no_ppk_auth() failed dying"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2_calc_no_ppk_auth() failed dying"); } }; | |||
| 498 | return STF_FATAL; | |||
| 499 | } | |||
| 500 | ||||
| 501 | if (!emit_v2N_hunk(v2N_NO_PPK_AUTH,emit_v2N_bytes(v2N_NO_PPK_AUTH, (ike->sa.st_no_ppk_auth).ptr , (ike->sa.st_no_ppk_auth).len, &sk.pbs) | |||
| 502 | ike->sa.st_no_ppk_auth, &sk.pbs)emit_v2N_bytes(v2N_NO_PPK_AUTH, (ike->sa.st_no_ppk_auth).ptr , (ike->sa.st_no_ppk_auth).len, &sk.pbs)) { | |||
| 503 | return STF_INTERNAL_ERROR; | |||
| 504 | } | |||
| 505 | } | |||
| 506 | } | |||
| 507 | ||||
| 508 | /* | |||
| 509 | * The initiator: | |||
| 510 | * | |||
| 511 | * We sent normal IKEv2_AUTH_RSA but if the policy also allows | |||
| 512 | * AUTH_NULL, we will send a Notify with NULL_AUTH in separate | |||
| 513 | * chunk. This is only done on the initiator in IKE_AUTH, and | |||
| 514 | * not repeated in rekeys. | |||
| 515 | */ | |||
| 516 | if (v2_auth_by(ike) == AUTHBY_RSASIG && pc->policy & POLICY_AUTH_NULL((lset_t)1 << (POLICY_AUTH_NULL_IX))) { | |||
| 517 | /* store in null_auth */ | |||
| 518 | chunk_t null_auth = NULL_HUNK{ .ptr = ((void*)0), .len = 0, }; | |||
| 519 | if (!ikev2_create_psk_auth(AUTHBY_NULL, ike, | |||
| 520 | &ike->sa.st_v2_id_payload.mac, | |||
| 521 | &null_auth)) { | |||
| 522 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 523 | "Failed to calculate additional NULL_AUTH"); | |||
| 524 | return STF_FATAL; | |||
| 525 | } | |||
| 526 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
| 527 | if (!emit_v2N_hunk(v2N_NULL_AUTH, null_auth, &sk.pbs)emit_v2N_bytes(v2N_NULL_AUTH, (null_auth).ptr, (null_auth).len , &sk.pbs)) { | |||
| 528 | free_chunk_content(&null_auth); | |||
| 529 | return STF_INTERNAL_ERROR; | |||
| 530 | } | |||
| 531 | free_chunk_content(&null_auth); | |||
| 532 | } | |||
| 533 | ||||
| 534 | if (!close_v2SK_payload(&sk)) { | |||
| 535 | return STF_INTERNAL_ERROR; | |||
| 536 | } | |||
| 537 | close_output_pbs(&rbody); | |||
| 538 | close_output_pbs(&reply_stream); | |||
| 539 | ||||
| 540 | /* | |||
| 541 | * For AUTH exchange, store the message in the IKE SA. The | |||
| 542 | * attempt to create the CHILD SA could have failed. | |||
| 543 | */ | |||
| 544 | return record_v2SK_message(&reply_stream, &sk, | |||
| 545 | "sending IKE_AUTH request", | |||
| 546 | MESSAGE_REQUEST); | |||
| 547 | } | |||
| 548 | ||||
| 549 | /* STATE_V2_PARENT_R1: I2 --> R2 | |||
| 550 | * <-- HDR, SK {IDi, [CERT,] [CERTREQ,] | |||
| 551 | * [IDr,] AUTH, SAi2, | |||
| 552 | * TSi, TSr} | |||
| 553 | * HDR, SK {IDr, [CERT,] AUTH, | |||
| 554 | * SAr2, TSi, TSr} --> | |||
| 555 | * | |||
| 556 | * [Parent SA established] | |||
| 557 | */ | |||
| 558 | ||||
| 559 | static dh_shared_secret_cb process_v2_IKE_AUTH_request_no_skeyseed_continue; /* type assertion */ | |||
| 560 | ||||
| 561 | stf_status process_v2_IKE_AUTH_request_no_skeyseed(struct ike_sa *ike, | |||
| 562 | struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
| 563 | struct msg_digest *md UNUSED__attribute__ ((unused))) | |||
| 564 | { | |||
| 565 | /* | |||
| 566 | * the initiator sent us an encrypted payload. We need to calculate | |||
| 567 | * our g^xy, and skeyseed values, and then decrypt the payload. | |||
| 568 | */ | |||
| 569 | ||||
| 570 | dbg("ikev2 parent %s(): calculating g^{xy} in order to decrypt I2", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2 parent %s(): calculating g^{xy} in order to decrypt I2" , __func__); } }; | |||
| 571 | ||||
| 572 | /* initiate calculation of g^xy */ | |||
| 573 | submit_dh_shared_secret(&ike->sa, ike->sa.st_gi/*responder needs initiator KE*/, | |||
| 574 | process_v2_IKE_AUTH_request_no_skeyseed_continue, | |||
| 575 | HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 575, }; &here ; })); | |||
| 576 | return STF_SUSPEND; | |||
| 577 | } | |||
| 578 | ||||
| 579 | static stf_status process_v2_IKE_AUTH_request_no_skeyseed_continue(struct state *ike_st, | |||
| 580 | struct msg_digest *md) | |||
| 581 | { | |||
| 582 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
| 583 | pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 583, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; }); | |||
| 584 | pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 584, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */ | |||
| 585 | pexpect(ike->sa.st_state->kind == STATE_V2_PARENT_R1)({ _Bool assertion__ = ike->sa.st_state->kind == STATE_V2_PARENT_R1 ; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 585, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_state->kind == STATE_V2_PARENT_R1" ); } assertion__; }); | |||
| 586 | dbg("%s() for #%lu %s: calculating g^{xy}, sending R2",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: calculating g^{xy}, sending R2" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } } | |||
| 587 | __func__, ike->sa.st_serialno, ike->sa.st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: calculating g^{xy}, sending R2" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } }; | |||
| 588 | ||||
| 589 | /* extract calculated values from r */ | |||
| 590 | ||||
| 591 | if (ike->sa.st_dh_shared_secret == NULL((void*)0)) { | |||
| 592 | /* | |||
| 593 | * Since dh failed, the channel isn't end-to-end | |||
| 594 | * encrypted. Send back a clear text notify and then | |||
| 595 | * abandon the connection. | |||
| 596 | */ | |||
| 597 | dbg("aborting IKE SA: DH failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("aborting IKE SA: DH failed"); } }; | |||
| 598 | send_v2N_response_from_md(md, v2N_INVALID_SYNTAX, NULL((void*)0)); | |||
| 599 | return STF_FATAL; | |||
| 600 | } | |||
| 601 | ||||
| 602 | calc_v2_keymat(&ike->sa, NULL((void*)0)/*old_skey_d*/, NULL((void*)0)/*old_prf*/, | |||
| 603 | &ike->sa.st_ike_spis/*new SPIs*/); | |||
| 604 | ||||
| 605 | ikev2_process_state_packet(ike, &ike->sa, md); | |||
| 606 | /* above does complete state transition */ | |||
| 607 | return STF_SKIP_COMPLETE_STATE_TRANSITION; | |||
| 608 | } | |||
| 609 | ||||
| 610 | #ifdef USE_PAM_AUTH1 | |||
| 611 | ||||
| 612 | static pam_auth_callback_fn ikev2_pam_continue; /* type assertion */ | |||
| 613 | ||||
| 614 | static stf_status ikev2_pam_continue(struct state *ike_st, | |||
| 615 | struct msg_digest *md, | |||
| 616 | const char *name UNUSED__attribute__ ((unused)), | |||
| 617 | bool_Bool success) | |||
| 618 | { | |||
| 619 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
| 620 | pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 620, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; }); | |||
| 621 | pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 621, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */ | |||
| 622 | pexpect(ike->sa.st_state->kind == STATE_V2_PARENT_R1)({ _Bool assertion__ = ike->sa.st_state->kind == STATE_V2_PARENT_R1 ; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 622, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_state->kind == STATE_V2_PARENT_R1" ); } assertion__; }); | |||
| 623 | dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, ike->sa.st_serialno , ike->sa.st_state->name); } } | |||
| 624 | __func__, ike->sa.st_serialno, ike->sa.st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, ike->sa.st_serialno , ike->sa.st_state->name); } }; | |||
| 625 | ||||
| 626 | if (!success) { | |||
| 627 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 628 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
| 629 | ENCRYPTED_PAYLOAD); | |||
| 630 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 631 | return STF_FATAL; /* STF_ZOMBIFY */ | |||
| 632 | } | |||
| 633 | ||||
| 634 | return process_v2_IKE_AUTH_request_tail(&ike->sa, md, success); | |||
| 635 | } | |||
| 636 | ||||
| 637 | #endif /* USE_PAM_AUTH */ | |||
| 638 | ||||
| 639 | static stf_status process_v2_IKE_AUTH_request_continue_tail(struct state *st, | |||
| 640 | struct msg_digest *md); | |||
| 641 | ||||
| 642 | stf_status process_v2_IKE_AUTH_request(struct ike_sa *ike, | |||
| 643 | struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
| 644 | struct msg_digest *md) | |||
| 645 | { | |||
| 646 | ||||
| 647 | /* for testing only */ | |||
| 648 | if (impair.send_no_ikev2_auth) { | |||
| 649 | log_state(RC_LOG, &ike->sa, | |||
| 650 | "IMPAIR_SEND_NO_IKEV2_AUTH set - not sending IKE_AUTH packet"); | |||
| 651 | return STF_IGNORE; | |||
| 652 | } | |||
| 653 | ||||
| 654 | /* | |||
| 655 | * This log line establishes that the packet's been decrypted | |||
| 656 | * and now it is being processed for real. | |||
| 657 | * | |||
| 658 | * XXX: move this into ikev2.c? | |||
| 659 | */ | |||
| 660 | LLOG_JAMBUF(RC_LOG, ike->sa.st_logger, buf)for (char lswbuf[((size_t)1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = ((void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf), sizeof(lswbuf)), *buf = &jambuf ; buf != ((void*)0); buf = ((void*)0)) for (({ if (((RC_LOG) & NO_PREFIX) == ((lset_t)0) && (((RC_LOG) & STREAM_MASK ) != DEBUG_STREAM || (cur_debugging & (((lset_t)1 << (DBG_ADD_PREFIX_IX)))))) { (ike->sa.st_logger)->object_vec ->jam_object_prefix(buf, (ike->sa.st_logger)->object ); } }); buf != ((void*)0); jambuf_to_logger(buf, (ike->sa .st_logger), RC_LOG), buf = ((void*)0)) { | |||
| 661 | jam(buf, "processing decrypted "); | |||
| 662 | lswlog_msg_digest(buf, md); | |||
| 663 | } | |||
| 664 | ||||
| 665 | stf_status e = process_v2_IKE_AUTH_request_continue_tail(&ike->sa, md); | |||
| 666 | LSWDBGP(DBG_BASE, buf)for (_Bool lswlog_p = (cur_debugging & (((lset_t)1 << (DBG_BASE_IX)))); lswlog_p; lswlog_p = 0) for (char lswbuf[( (size_t)1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_ = ((void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf ), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf = ((void*)0)) for (; buf != ((void*)0); jambuf_to_logger(buf , &failsafe_logger, DEBUG_STREAM), buf = ((void*)0)) { | |||
| 667 | jam(buf, "process_v2_IKE_AUTH_request_continue_tail returned "); | |||
| 668 | jam_v2_stf_status(buf, e); | |||
| 669 | } | |||
| 670 | ||||
| 671 | /* | |||
| 672 | * if failed OE, delete state completely, no create_child_sa | |||
| 673 | * allowed so childless parent makes no sense. That is also | |||
| 674 | * the reason why we send v2N_AUTHENTICATION_FAILED, even | |||
| 675 | * though authenticated succeeded. It shows the remote end | |||
| 676 | * we have deleted the SA from our end. | |||
| 677 | */ | |||
| 678 | if (e >= STF_FAIL && | |||
| 679 | (ike->sa.st_connection->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))) { | |||
| 680 | dbg("deleting opportunistic IKE SA with no Child SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting opportunistic IKE SA with no Child SA" ); } }; | |||
| 681 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 682 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 683 | ENCRYPTED_PAYLOAD); | |||
| 684 | return STF_FATAL; /* STF_ZOMBIFY */ | |||
| 685 | } | |||
| 686 | ||||
| 687 | return e; | |||
| 688 | } | |||
| 689 | ||||
| 690 | static stf_status process_v2_IKE_AUTH_request_post_cert_decode(struct state *st, | |||
| 691 | struct msg_digest *md); | |||
| 692 | ||||
| 693 | static stf_status process_v2_IKE_AUTH_request_continue_tail(struct state *st, | |||
| 694 | struct msg_digest *md) | |||
| 695 | { | |||
| 696 | struct ike_sa *ike = ike_sa(st, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 696, }; &here ; })); | |||
| 697 | ||||
| 698 | struct payload_digest *cert_payloads = md->chain[ISAKMP_NEXT_v2CERT]; | |||
| 699 | if (cert_payloads != NULL((void*)0)) { | |||
| 700 | submit_cert_decode(ike, st, md, cert_payloads, | |||
| 701 | process_v2_IKE_AUTH_request_post_cert_decode, | |||
| 702 | "responder decoding certificates"); | |||
| 703 | return STF_SUSPEND; | |||
| 704 | } else { | |||
| 705 | dbg("no certs to decode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no certs to decode"); } }; | |||
| 706 | ike->sa.st_remote_certs.processed = true1; | |||
| 707 | ike->sa.st_remote_certs.harmless = true1; | |||
| 708 | } | |||
| 709 | return process_v2_IKE_AUTH_request_post_cert_decode(st, md); | |||
| 710 | } | |||
| 711 | ||||
| 712 | static stf_status process_v2_IKE_AUTH_request_ipseckey_continue(struct ike_sa *ike, | |||
| 713 | struct msg_digest *md, | |||
| 714 | bool_Bool err); | |||
| 715 | ||||
| 716 | static stf_status process_v2_IKE_AUTH_request_id_tail(struct ike_sa *ike, struct msg_digest *md); | |||
| 717 | ||||
| 718 | static stf_status process_v2_IKE_AUTH_request_post_cert_decode(struct state *ike_sa, | |||
| 719 | struct msg_digest *md) | |||
| 720 | { | |||
| 721 | struct ike_sa *ike = pexpect_ike_sa(ike_sa); | |||
| 722 | ikev2_log_parentSA(&ike->sa); | |||
| 723 | ||||
| 724 | /* going to switch to child st. before that update parent */ | |||
| 725 | if (!LHAS(ike->sa.hidden_variables.st_nat_traversal, NATED_HOST)(((ike->sa.hidden_variables.st_nat_traversal) & ((lset_t )1 << (NATED_HOST))) != ((lset_t)0))) | |||
| 726 | update_ike_endpoints(ike, md); | |||
| 727 | ||||
| 728 | nat_traversal_change_port_lookup(md, &ike->sa); /* shouldn't this be ike? */ | |||
| 729 | ||||
| 730 | diag_t d = ikev2_responder_decode_initiator_id(ike, md); | |||
| 731 | if (d != NULL((void*)0)) { | |||
| 732 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
| 733 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 734 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 735 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
| 736 | ENCRYPTED_PAYLOAD); | |||
| 737 | return STF_FATAL; | |||
| 738 | } | |||
| 739 | ||||
| 740 | enum ikev2_auth_method atype = md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method; | |||
| 741 | if (IS_LIBUNBOUND1 && id_ipseckey_allowed(ike, atype)) { | |||
| 742 | dns_status ret = responder_fetch_idi_ipseckey(ike, process_v2_IKE_AUTH_request_ipseckey_continue); | |||
| 743 | switch (ret) { | |||
| 744 | case DNS_SUSPEND: | |||
| 745 | return STF_SUSPEND; | |||
| 746 | case DNS_FATAL: | |||
| 747 | llog_sa(RC_LOG_SERIOUS, ike, "DNS: IPSECKEY not found or usable")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "DNS: IPSECKEY not found or usable" ); | |||
| 748 | return STF_FATAL; | |||
| 749 | case DNS_OK: | |||
| 750 | break; | |||
| 751 | } | |||
| 752 | } | |||
| 753 | ||||
| 754 | return process_v2_IKE_AUTH_request_id_tail(ike, md); | |||
| 755 | } | |||
| 756 | ||||
| 757 | stf_status process_v2_IKE_AUTH_request_ipseckey_continue(struct ike_sa *ike, | |||
| 758 | struct msg_digest *md, | |||
| 759 | bool_Bool err) | |||
| 760 | { | |||
| 761 | if (err) { | |||
| 762 | /* already logged?! */ | |||
| 763 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 764 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
| 765 | ENCRYPTED_PAYLOAD); | |||
| 766 | return STF_FATAL; | |||
| 767 | } | |||
| 768 | return process_v2_IKE_AUTH_request_id_tail(ike, md); | |||
| 769 | } | |||
| 770 | ||||
| 771 | stf_status process_v2_IKE_AUTH_request_id_tail(struct ike_sa *ike, struct msg_digest *md) | |||
| 772 | { | |||
| 773 | lset_t policy = ike->sa.st_connection->policy; | |||
| 774 | bool_Bool found_ppk = false0; | |||
| 775 | chunk_t null_auth = EMPTY_CHUNK((const chunk_t) { .ptr = ((void*)0), .len = 0 }); | |||
| 776 | ||||
| 777 | /* | |||
| 778 | * The NOTIFY payloads we receive in the IKE_AUTH request are | |||
| 779 | * either related to the IKE SA, or the Child SA. Here we only | |||
| 780 | * process the ones related to the IKE SA. | |||
| 781 | */ | |||
| 782 | if (md->pd[PD_v2N_PPK_IDENTITY] != NULL((void*)0)) { | |||
| 783 | dbg("received PPK_IDENTITY"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received PPK_IDENTITY"); } }; | |||
| 784 | struct ppk_id_payload payl; | |||
| 785 | if (!extract_v2N_ppk_identity(&md->pd[PD_v2N_PPK_IDENTITY]->pbs, &payl, ike)) { | |||
| 786 | dbg("failed to extract PPK_ID from PPK_IDENTITY payload. Abort!"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("failed to extract PPK_ID from PPK_IDENTITY payload. Abort!" ); } }; | |||
| 787 | return STF_FATAL; | |||
| 788 | } | |||
| 789 | ||||
| 790 | const chunk_t *ppk = get_ppk_by_id(&payl.ppk_id); | |||
| 791 | free_chunk_content(&payl.ppk_id); | |||
| 792 | if (ppk != NULL((void*)0)) { | |||
| 793 | found_ppk = true1; | |||
| 794 | } | |||
| 795 | ||||
| 796 | if (found_ppk && LIN(POLICY_PPK_ALLOW, policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (policy) ) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) { | |||
| 797 | ppk_recalculate(ppk, ike->sa.st_oakley.ta_prf, | |||
| 798 | &ike->sa.st_skey_d_nss, | |||
| 799 | &ike->sa.st_skey_pi_nss, | |||
| 800 | &ike->sa.st_skey_pr_nss, | |||
| 801 | ike->sa.st_logger); | |||
| 802 | ike->sa.st_ppk_used = true1; | |||
| 803 | log_state(RC_LOG, &ike->sa, | |||
| 804 | "PPK AUTH calculated as responder"); | |||
| 805 | } else { | |||
| 806 | log_state(RC_LOG, &ike->sa, | |||
| 807 | "ignored received PPK_IDENTITY - connection does not require PPK or PPKID not found"); | |||
| 808 | } | |||
| 809 | } | |||
| 810 | if (md->pd[PD_v2N_NO_PPK_AUTH] != NULL((void*)0)) { | |||
| 811 | pb_stream pbs = md->pd[PD_v2N_NO_PPK_AUTH]->pbs; | |||
| 812 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
| 813 | dbg("received NO_PPK_AUTH"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received NO_PPK_AUTH"); } }; | |||
| 814 | if (LIN(POLICY_PPK_INSIST, policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (policy )) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
| 815 | dbg("Ignored NO_PPK_AUTH data - connection insists on PPK"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Ignored NO_PPK_AUTH data - connection insists on PPK" ); } }; | |||
| 816 | } else { | |||
| 817 | ||||
| 818 | chunk_t no_ppk_auth = alloc_chunk(len, "NO_PPK_AUTH"); | |||
| 819 | diag_t d = pbs_in_raw(&pbs, no_ppk_auth.ptr, len, "NO_PPK_AUTH extract"); | |||
| 820 | if (d != NULL((void*)0)) { | |||
| 821 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, | |||
| 822 | "failed to extract %zd bytes of NO_PPK_AUTH from Notify payload", len); | |||
| 823 | free_chunk_content(&no_ppk_auth); | |||
| 824 | return STF_FATAL; | |||
| 825 | } | |||
| 826 | replace_chunk(&ike->sa.st_no_ppk_auth, no_ppk_auth); | |||
| 827 | } | |||
| 828 | } | |||
| 829 | ike->sa.st_ike_seen_v2n_mobike_supported = md->pd[PD_v2N_MOBIKE_SUPPORTED] != NULL((void*)0); | |||
| 830 | if (ike->sa.st_ike_seen_v2n_mobike_supported) { | |||
| 831 | dbg("received v2N_MOBIKE_SUPPORTED %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" ); } } | |||
| 832 | ike->sa.st_ike_sent_v2n_mobike_supported ?{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" ); } } | |||
| 833 | "and sent" : "while it did not sent"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" ); } }; | |||
| 834 | } | |||
| 835 | if (md->pd[PD_v2N_NULL_AUTH] != NULL((void*)0)) { | |||
| 836 | pb_stream pbs = md->pd[PD_v2N_NULL_AUTH]->pbs; | |||
| 837 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
| 838 | ||||
| 839 | dbg("received v2N_NULL_AUTH"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_NULL_AUTH"); } }; | |||
| 840 | null_auth = alloc_chunk(len, "NULL_AUTH"); | |||
| 841 | diag_t d = pbs_in_raw(&pbs, null_auth.ptr, len, "NULL_AUTH extract"); | |||
| 842 | if (d != NULL((void*)0)) { | |||
| 843 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, | |||
| 844 | "failed to extract %zd bytes of NULL_AUTH from Notify payload: ", len); | |||
| 845 | free_chunk_content(&null_auth); | |||
| 846 | return STF_FATAL; | |||
| 847 | } | |||
| 848 | } | |||
| 849 | ike->sa.st_ike_seen_v2n_initial_contact = md->pd[PD_v2N_INITIAL_CONTACT] != NULL((void*)0); | |||
| 850 | ||||
| 851 | /* | |||
| 852 | * If we found proper PPK ID and policy allows PPK, use that. | |||
| 853 | * Otherwise use NO_PPK_AUTH | |||
| 854 | */ | |||
| 855 | if (found_ppk && LIN(POLICY_PPK_ALLOW, policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (policy) ) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) | |||
| 856 | free_chunk_content(&ike->sa.st_no_ppk_auth); | |||
| 857 | ||||
| 858 | if (!found_ppk && LIN(POLICY_PPK_INSIST, policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (policy )) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
| 859 | log_state(RC_LOG_SERIOUS, &ike->sa, "Requested PPK_ID not found and connection requires a valid PPK"); | |||
| 860 | free_chunk_content(&null_auth); | |||
| 861 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 862 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 863 | ENCRYPTED_PAYLOAD); | |||
| 864 | return STF_FATAL; | |||
| 865 | } | |||
| 866 | ||||
| 867 | /* calculate hash of IDi for AUTH below */ | |||
| 868 | struct crypt_mac idhash_in = v2_id_hash(ike, "IDi verify hash", "IDi", | |||
| 869 | same_pbs_in_as_shunk(&md->chain[ISAKMP_NEXT_v2IDi]->pbs), | |||
| 870 | "skey_pi", ike->sa.st_skey_pi_nss); | |||
| 871 | ||||
| 872 | /* process CERTREQ payload */ | |||
| 873 | if (md->chain[ISAKMP_NEXT_v2CERTREQ] != NULL((void*)0)) { | |||
| 874 | dbg("received CERTREQ payload; going to decode it"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received CERTREQ payload; going to decode it" ); } }; | |||
| 875 | ikev2_decode_cr(md, ike->sa.st_logger); | |||
| 876 | } | |||
| 877 | ||||
| 878 | /* process AUTH payload */ | |||
| 879 | ||||
| 880 | enum keyword_authby that_authby = ike->sa.st_connection->spd.that.authby; | |||
| 881 | ||||
| 882 | passert(that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET)({ _Bool assertion__ = that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET; if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 882, }; &here ; }); const struct logger *logger_ = &failsafe_logger; llog_passert (logger_, here, "%s", "that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET" ); } (void) 1; }); | |||
| 883 | ||||
| 884 | if (!ike->sa.st_ppk_used && ike->sa.st_no_ppk_auth.ptr != NULL((void*)0)) { | |||
| 885 | /* | |||
| 886 | * we didn't recalculate keys with PPK, but we found NO_PPK_AUTH | |||
| 887 | * (meaning that initiator did use PPK) so we try to verify NO_PPK_AUTH. | |||
| 888 | */ | |||
| 889 | dbg("going to try to verify NO_PPK_AUTH."){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("going to try to verify NO_PPK_AUTH."); } }; | |||
| 890 | /* making a dummy pb_stream so we could pass it to v2_check_auth */ | |||
| 891 | pb_stream pbs_no_ppk_auth; | |||
| 892 | pb_stream pbs = md->chain[ISAKMP_NEXT_v2AUTH]->pbs; | |||
| 893 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
| 894 | init_pbs(&pbs_no_ppk_auth, ike->sa.st_no_ppk_auth.ptr, len, "pb_stream for verifying NO_PPK_AUTH"); | |||
| 895 | ||||
| 896 | diag_t d = v2_authsig_and_log(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
| 897 | ike, &idhash_in, &pbs_no_ppk_auth, | |||
| 898 | ike->sa.st_connection->spd.that.authby); | |||
| 899 | if (d != NULL((void*)0)) { | |||
| 900 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
| 901 | dbg("no PPK auth failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no PPK auth failed"); } }; | |||
| 902 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 903 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 904 | ENCRYPTED_PAYLOAD); | |||
| 905 | free_chunk_content(&null_auth); /* ??? necessary? */ | |||
| 906 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 907 | return STF_FATAL; | |||
| 908 | } | |||
| 909 | dbg("NO_PPK_AUTH verified"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NO_PPK_AUTH verified"); } }; | |||
| 910 | } else { | |||
| 911 | bool_Bool policy_null = LIN(POLICY_AUTH_NULL, ike->sa.st_connection->policy)(((((lset_t)1 << (POLICY_AUTH_NULL_IX))) & (ike-> sa.st_connection->policy)) == (((lset_t)1 << (POLICY_AUTH_NULL_IX )))); | |||
| 912 | bool_Bool policy_rsasig = LIN(POLICY_RSASIG, ike->sa.st_connection->policy)(((((lset_t)1 << (POLICY_RSASIG_IX))) & (ike->sa .st_connection->policy)) == (((lset_t)1 << (POLICY_RSASIG_IX )))); | |||
| 913 | ||||
| 914 | /* | |||
| 915 | * if received NULL_AUTH in Notify payload and we only allow NULL Authentication, | |||
| 916 | * proceed with verifying that payload, else verify AUTH normally | |||
| 917 | */ | |||
| 918 | if (null_auth.ptr != NULL((void*)0) && policy_null && !policy_rsasig) { | |||
| 919 | /* making a dummy pb_stream so we could pass it to v2_check_auth */ | |||
| 920 | pb_stream pbs_null_auth; | |||
| 921 | size_t len = null_auth.len; | |||
| 922 | ||||
| 923 | dbg("going to try to verify NULL_AUTH from Notify payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("going to try to verify NULL_AUTH from Notify payload" ); } }; | |||
| 924 | init_pbs(&pbs_null_auth, null_auth.ptr, len, "pb_stream for verifying NULL_AUTH"); | |||
| 925 | diag_t d = v2_authsig_and_log(IKEv2_AUTH_NULL, ike, &idhash_in, | |||
| 926 | &pbs_null_auth, AUTHBY_NULL); | |||
| 927 | if (d != NULL((void*)0)) { | |||
| 928 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
| 929 | dbg("NULL_auth from Notify Payload failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NULL_auth from Notify Payload failed"); } }; | |||
| 930 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 931 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 932 | ENCRYPTED_PAYLOAD); | |||
| 933 | free_chunk_content(&null_auth); | |||
| 934 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 935 | return STF_FATAL; | |||
| 936 | } | |||
| 937 | dbg("NULL_AUTH verified"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NULL_AUTH verified"); } }; | |||
| 938 | } else { | |||
| 939 | dbg("responder verifying AUTH payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("responder verifying AUTH payload"); } }; | |||
| 940 | diag_t d = v2_authsig_and_log(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
| 941 | ike, &idhash_in, &md->chain[ISAKMP_NEXT_v2AUTH]->pbs, | |||
| 942 | ike->sa.st_connection->spd.that.authby); | |||
| 943 | if (d != NULL((void*)0)) { | |||
| 944 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
| 945 | dbg("I2 Auth Payload failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("I2 Auth Payload failed"); } }; | |||
| 946 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 947 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 948 | ENCRYPTED_PAYLOAD); | |||
| 949 | free_chunk_content(&null_auth); | |||
| 950 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 951 | return STF_FATAL; | |||
| 952 | } | |||
| 953 | } | |||
| 954 | } | |||
| 955 | ||||
| 956 | /* AUTH succeeded */ | |||
| 957 | ||||
| 958 | free_chunk_content(&null_auth); | |||
| 959 | ||||
| 960 | #ifdef USE_PAM_AUTH1 | |||
| 961 | /* | |||
| 962 | * The AUTH payload is verified succsfully. Now invoke the | |||
| 963 | * PAM helper to authorize connection (based on name only, not | |||
| 964 | * password) When pam helper is done state will be woken up | |||
| 965 | * and continue. | |||
| 966 | */ | |||
| 967 | if (ike->sa.st_connection->policy & POLICY_IKEV2_PAM_AUTHORIZE((lset_t)1 << (POLICY_IKEV2_PAM_AUTHORIZE_IX))) { | |||
| 968 | id_buf thatidb; | |||
| 969 | const char *thatid = str_id(&ike->sa.st_connection->spd.that.id, &thatidb)str_id_bytes(&ike->sa.st_connection->spd.that.id, jam_raw_bytes , &thatidb); | |||
| 970 | llog_sa(RC_LOG, ike,llog(RC_LOG, (ike)->sa.st_logger, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid) | |||
| 971 | "IKEv2: [XAUTH]PAM method requested to authorize '%s'",llog(RC_LOG, (ike)->sa.st_logger, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid) | |||
| 972 | thatid)llog(RC_LOG, (ike)->sa.st_logger, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid); | |||
| 973 | if (!pam_auth_fork_request(&ike->sa, thatid, "password", | |||
| 974 | "IKEv2", ikev2_pam_continue)) { | |||
| 975 | return STF_FATAL; | |||
| 976 | } | |||
| 977 | return STF_SUSPEND; | |||
| 978 | } | |||
| 979 | #endif | |||
| 980 | ||||
| 981 | return process_v2_IKE_AUTH_request_tail(&ike->sa, md, true1); | |||
| 982 | } | |||
| 983 | ||||
| 984 | static v2_auth_signature_cb process_v2_IKE_AUTH_request_auth_signature_continue; /* type check */ | |||
| 985 | ||||
| 986 | static stf_status process_v2_IKE_AUTH_request_tail(struct state *ike_st, | |||
| 987 | struct msg_digest *md, | |||
| 988 | bool_Bool pam_status) | |||
| 989 | { | |||
| 990 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
| 991 | struct connection *const c = ike->sa.st_connection; | |||
| 992 | ||||
| 993 | if (!pam_status) { | |||
| 994 | /* | |||
| 995 | * TBD: send this notification encrypted because the | |||
| 996 | * AUTH payload succeed | |||
| 997 | */ | |||
| 998 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 999 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 1000 | ENCRYPTED_PAYLOAD); | |||
| 1001 | return STF_FATAL; | |||
| 1002 | } | |||
| 1003 | ||||
| 1004 | /* | |||
| 1005 | * Construct the IDr payload and store it in state so that it | |||
| 1006 | * can be emitted later. Then use that to construct the | |||
| 1007 | * "MACedIDFor[R]". | |||
| 1008 | * | |||
| 1009 | * Code assumes that struct ikev2_id's "IDType|RESERVED" is | |||
| 1010 | * laid out the same as the packet. | |||
| 1011 | */ | |||
| 1012 | ||||
| 1013 | if (ike->sa.st_peer_wants_null) { | |||
| 1014 | /* make it the Null ID */ | |||
| 1015 | ike->sa.st_v2_id_payload.header.isai_type = ID_NULL; | |||
| 1016 | ike->sa.st_v2_id_payload.data = empty_chunk; | |||
| 1017 | } else { | |||
| 1018 | shunk_t data; | |||
| 1019 | ike->sa.st_v2_id_payload.header = build_v2_id_payload(&c->spd.this, &data, | |||
| 1020 | "my IDr", | |||
| 1021 | ike->sa.st_logger); | |||
| 1022 | ike->sa.st_v2_id_payload.data = clone_hunk(data, "my IDr")({ typeof(data) hunk_ = data; clone_bytes_as_chunk(hunk_.ptr, hunk_.len, "my IDr"); }); | |||
| 1023 | } | |||
| 1024 | ||||
| 1025 | /* will be signed in auth payload */ | |||
| 1026 | ike->sa.st_v2_id_payload.mac = v2_hash_id_payload("IDr", ike, "st_skey_pr_nss", | |||
| 1027 | ike->sa.st_skey_pr_nss); | |||
| 1028 | ||||
| 1029 | { | |||
| 1030 | enum keyword_authby authby = v2_auth_by(ike); | |||
| 1031 | enum ikev2_auth_method auth_method = v2_auth_method(ike, authby); | |||
| 1032 | switch (auth_method) { | |||
| 1033 | case IKEv2_AUTH_RSA: | |||
| 1034 | { | |||
| 1035 | const struct hash_desc *hash_algo = &ike_alg_hash_sha1; | |||
| 1036 | struct crypt_mac hash_to_sign = | |||
| 1037 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 1038 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 1039 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
| 1040 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 1041 | authby, auth_method, | |||
| 1042 | process_v2_IKE_AUTH_request_auth_signature_continue)) { | |||
| 1043 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
| 1044 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 1045 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 1046 | ENCRYPTED_PAYLOAD); | |||
| 1047 | return STF_FATAL; | |||
| 1048 | } | |||
| 1049 | return STF_SUSPEND; | |||
| 1050 | } | |||
| 1051 | case IKEv2_AUTH_DIGSIG: | |||
| 1052 | { | |||
| 1053 | const struct hash_desc *hash_algo = v2_auth_negotiated_signature_hash(ike); | |||
| 1054 | if (hash_algo == NULL((void*)0)) { | |||
| 1055 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 1056 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 1057 | ENCRYPTED_PAYLOAD); | |||
| 1058 | return STF_FATAL; | |||
| 1059 | } | |||
| 1060 | struct crypt_mac hash_to_sign = | |||
| 1061 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 1062 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 1063 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
| 1064 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 1065 | authby, auth_method, | |||
| 1066 | process_v2_IKE_AUTH_request_auth_signature_continue)) { | |||
| 1067 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
| 1068 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 1069 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 1070 | ENCRYPTED_PAYLOAD); | |||
| 1071 | return STF_FATAL; | |||
| 1072 | } | |||
| 1073 | return STF_SUSPEND; | |||
| 1074 | } | |||
| 1075 | case IKEv2_AUTH_PSK: | |||
| 1076 | case IKEv2_AUTH_NULL: | |||
| 1077 | { | |||
| 1078 | struct hash_signature sig = { .len = 0, }; | |||
| 1079 | return process_v2_IKE_AUTH_request_auth_signature_continue(ike, md, &sig); | |||
| 1080 | } | |||
| 1081 | default: | |||
| 1082 | log_state(RC_LOG, &ike->sa, | |||
| 1083 | "authentication method %s not supported", | |||
| 1084 | enum_name(&ikev2_auth_names, auth_method)); | |||
| 1085 | return STF_FATAL; | |||
| 1086 | } | |||
| 1087 | } | |||
| 1088 | } | |||
| 1089 | ||||
| 1090 | static stf_status process_v2_IKE_AUTH_request_auth_signature_continue(struct ike_sa *ike, | |||
| 1091 | struct msg_digest *md, | |||
| 1092 | const struct hash_signature *auth_sig) | |||
| 1093 | { | |||
| 1094 | struct connection *c = ike->sa.st_connection; | |||
| 1095 | ||||
| 1096 | /* | |||
| 1097 | * Update the parent state to make sure that it knows we have | |||
| 1098 | * authenticated properly. | |||
| 1099 | * | |||
| 1100 | * XXX: is this double book keeping? Same action happens in | |||
| 1101 | * success_v2_state_transition() and almost happens in | |||
| 1102 | * ikev2_ike_sa_established(). | |||
| 1103 | */ | |||
| 1104 | c->newest_ike_sa = ike->sa.st_serialno; | |||
| 1105 | ike->sa.st_viable_parent = true1; | |||
| 1106 | linux_audit_conn(&ike->sa, LAK_PARENT_START); | |||
| 1107 | pstat_sa_established(&ike->sa); | |||
| 1108 | ||||
| 1109 | if (LHAS(ike->sa.hidden_variables.st_nat_traversal, NATED_HOST)(((ike->sa.hidden_variables.st_nat_traversal) & ((lset_t )1 << (NATED_HOST))) != ((lset_t)0))) { | |||
| 1110 | /* ensure we run keepalives if needed */ | |||
| 1111 | if (c->nat_keepalive) { | |||
| 1112 | /* XXX: just trigger this event? */ | |||
| 1113 | nat_traversal_ka_event(ike->sa.st_logger); | |||
| 1114 | } | |||
| 1115 | } | |||
| 1116 | ||||
| 1117 | /* send response */ | |||
| 1118 | if (LIN(POLICY_MOBIKE, c->policy)(((((lset_t)1 << (POLICY_MOBIKE_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_MOBIKE_IX)))) && ike->sa.st_ike_seen_v2n_mobike_supported) { | |||
| 1119 | if (c->spd.that.host_type == KH_ANY) { | |||
| 1120 | /* only allow %any connection to mobike */ | |||
| 1121 | ike->sa.st_ike_sent_v2n_mobike_supported = true1; | |||
| 1122 | } else { | |||
| 1123 | log_state(RC_LOG, &ike->sa, | |||
| 1124 | "not responding with v2N_MOBIKE_SUPPORTED, that end is not %%any"); | |||
| 1125 | } | |||
| 1126 | } | |||
| 1127 | ||||
| 1128 | bool_Bool send_redirect = false0; | |||
| 1129 | ||||
| 1130 | if (ike->sa.st_seen_redirect_sup && | |||
| 1131 | (LIN(POLICY_SEND_REDIRECT_ALWAYS, c->policy)(((((lset_t)1 << (POLICY_SEND_REDIRECT_ALWAYS_IX))) & (c->policy)) == (((lset_t)1 << (POLICY_SEND_REDIRECT_ALWAYS_IX )))) || | |||
| 1132 | (!LIN(POLICY_SEND_REDIRECT_NEVER, c->policy)(((((lset_t)1 << (POLICY_SEND_REDIRECT_NEVER_IX))) & (c->policy)) == (((lset_t)1 << (POLICY_SEND_REDIRECT_NEVER_IX )))) && | |||
| 1133 | require_ddos_cookies()))) { | |||
| 1134 | if (c->redirect_to == NULL((void*)0)) { | |||
| 1135 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 1136 | "redirect-to is not specified, can't redirect requests"); | |||
| 1137 | } else { | |||
| 1138 | send_redirect = true1; | |||
| 1139 | } | |||
| 1140 | } | |||
| 1141 | ||||
| 1142 | /* | |||
| 1143 | * Wipes any connections that were using an old version of | |||
| 1144 | * this SA? Is this too early or too late? | |||
| 1145 | * | |||
| 1146 | * XXX: The call was originally sandwiched vis: | |||
| 1147 | * | |||
| 1148 | * - create child sa() | |||
| 1149 | * - add_xfrmi() | |||
| 1150 | * - IKE_SA_established() | |||
| 1151 | * - install_ipsec_sa() | |||
| 1152 | * | |||
| 1153 | * which means things were deleted after the child sa was | |||
| 1154 | * created. But now it happens before. Is this a problem? | |||
| 1155 | */ | |||
| 1156 | IKE_SA_established(ike); | |||
| 1157 | ||||
| 1158 | /* make sure HDR is at start of a clean buffer */ | |||
| 1159 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
| 1160 | reply_buffer, sizeof(reply_buffer), | |||
| 1161 | ike->sa.st_logger); | |||
| 1162 | ||||
| 1163 | /* HDR out */ | |||
| 1164 | ||||
| 1165 | struct pbs_outpacket_byte_stream rbody = open_v2_message(&reply_stream, ike, | |||
| 1166 | md /* response */, | |||
| 1167 | ISAKMP_v2_IKE_AUTH); | |||
| 1168 | ||||
| 1169 | /* decide to send CERT payload before we generate IDr */ | |||
| 1170 | bool_Bool send_cert = ikev2_send_cert_decision(ike); | |||
| 1171 | ||||
| 1172 | /* insert an Encryption payload header */ | |||
| 1173 | ||||
| 1174 | struct v2SK_payload sk = open_v2SK_payload(ike->sa.st_logger, &rbody, ike); | |||
| 1175 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
| 1176 | return STF_INTERNAL_ERROR; | |||
| 1177 | } | |||
| 1178 | ||||
| 1179 | if (impair.add_unknown_v2_payload_to_sk == ISAKMP_v2_IKE_AUTH) { | |||
| 1180 | if (!emit_v2UNKNOWN("SK reply", | |||
| 1181 | impair.add_unknown_v2_payload_to_sk, | |||
| 1182 | &sk.pbs)) { | |||
| 1183 | return STF_INTERNAL_ERROR; | |||
| 1184 | } | |||
| 1185 | } | |||
| 1186 | ||||
| 1187 | /* send any NOTIFY payloads */ | |||
| 1188 | if (ike->sa.st_ike_sent_v2n_mobike_supported) { | |||
| 1189 | if (!emit_v2N(v2N_MOBIKE_SUPPORTED, &sk.pbs)) | |||
| 1190 | return STF_INTERNAL_ERROR; | |||
| 1191 | } | |||
| 1192 | ||||
| 1193 | if (ike->sa.st_ppk_used) { | |||
| 1194 | if (!emit_v2N(v2N_PPK_IDENTITY, &sk.pbs)) | |||
| 1195 | return STF_INTERNAL_ERROR; | |||
| 1196 | } | |||
| 1197 | ||||
| 1198 | /* | |||
| 1199 | * A redirect does not tear down the IKE SA; instead that is | |||
| 1200 | * left to the initiator: | |||
| 1201 | * | |||
| 1202 | * https://datatracker.ietf.org/doc/html/rfc5685#section-6 | |||
| 1203 | * 6. Redirect during IKE_AUTH Exchange | |||
| 1204 | * | |||
| 1205 | * When the client receives the IKE_AUTH response with the | |||
| 1206 | * REDIRECT payload, it SHOULD delete the IKEv2 security | |||
| 1207 | * association with the gateway by sending an INFORMATIONAL | |||
| 1208 | * message with a DELETE payload. | |||
| 1209 | */ | |||
| 1210 | if (send_redirect) { | |||
| 1211 | if (!emit_redirect_notification(shunk1(c->redirect_to), &sk.pbs)) | |||
| 1212 | return STF_INTERNAL_ERROR; | |||
| 1213 | ike->sa.st_sent_redirect = true1; /* mark that we have sent REDIRECT in IKE_AUTH */ | |||
| 1214 | } | |||
| 1215 | ||||
| 1216 | /* send out the IDr payload */ | |||
| 1217 | { | |||
| 1218 | pb_stream r_id_pbs; | |||
| 1219 | if (!out_struct(&ike->sa.st_v2_id_payload.header, | |||
| 1220 | &ikev2_id_r_desc, &sk.pbs, &r_id_pbs) || | |||
| 1221 | !out_hunk(ike->sa.st_v2_id_payload.data,({ typeof(ike->sa.st_v2_id_payload.data) hunk_ = ike->sa .st_v2_id_payload.data; struct packet_byte_stream *outs_ = & r_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_.len , ("my identity")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); }) | |||
| 1222 | &r_id_pbs, "my identity")({ typeof(ike->sa.st_v2_id_payload.data) hunk_ = ike->sa .st_v2_id_payload.data; struct packet_byte_stream *outs_ = & r_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_.len , ("my identity")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); })) | |||
| 1223 | return STF_INTERNAL_ERROR; | |||
| 1224 | close_output_pbs(&r_id_pbs); | |||
| 1225 | dbg("added IDr payload to packet"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("added IDr payload to packet"); } }; | |||
| 1226 | } | |||
| 1227 | ||||
| 1228 | /* | |||
| 1229 | * send CERT payload RFC 4306 3.6, 1.2:([CERT,] ) | |||
| 1230 | * upon which our received I2 CERTREQ is ignored, | |||
| 1231 | * but ultimately should go into the CERT decision | |||
| 1232 | */ | |||
| 1233 | if (send_cert) { | |||
| 1234 | stf_status certstat = ikev2_send_cert(ike->sa.st_connection, &sk.pbs); | |||
| 1235 | if (certstat != STF_OK) | |||
| 1236 | return certstat; | |||
| 1237 | } | |||
| 1238 | ||||
| 1239 | /* now send AUTH payload */ | |||
| 1240 | ||||
| 1241 | if (!emit_v2_auth(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, &sk.pbs)) { | |||
| 1242 | return STF_INTERNAL_ERROR; | |||
| 1243 | } | |||
| 1244 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
| 1245 | ||||
| 1246 | if (c->config->sec_label.len > 0) { | |||
| 1247 | pexpect(c->kind == CK_TEMPLATE)({ _Bool assertion__ = c->kind == CK_TEMPLATE; if (!assertion__ ) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1247, }; &here; }); const struct logger *logger_ = & failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->kind == CK_TEMPLATE" ); } assertion__; }); | |||
| 1248 | pexpect(c->spd.this.sec_label.len == 0)({ _Bool assertion__ = c->spd.this.sec_label.len == 0; if ( !assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 1248, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->spd.this.sec_label.len == 0" ); } assertion__; }); | |||
| 1249 | if (!install_se_connection_policies(c, ike->sa.st_logger)) { | |||
| 1250 | return STF_FATAL; | |||
| 1251 | } | |||
| 1252 | } | |||
| 1253 | ||||
| 1254 | /* | |||
| 1255 | * Try to build a child. | |||
| 1256 | * | |||
| 1257 | * The result can be fatal, or just doesn't create the child. | |||
| 1258 | */ | |||
| 1259 | ||||
| 1260 | if (send_redirect) { | |||
| 1261 | dbg("skipping child; redirect response"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("skipping child; redirect response"); } }; | |||
| 1262 | } else { | |||
| 1263 | v2_notification_t cn = process_v2_IKE_AUTH_request_child_sa_payloads(ike, md, &sk.pbs); | |||
| 1264 | if (v2_notification_fatal(cn)) { | |||
| 1265 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 1266 | cn, NULL((void*)0)/*no-data*/, | |||
| 1267 | ENCRYPTED_PAYLOAD); | |||
| 1268 | return STF_FATAL; | |||
| 1269 | } else if (cn != v2N_NOTHING_WRONG) { | |||
| 1270 | emit_v2N(cn, &sk.pbs); | |||
| 1271 | } | |||
| 1272 | } | |||
| 1273 | ||||
| 1274 | if (!close_v2SK_payload(&sk)) { | |||
| 1275 | return STF_INTERNAL_ERROR; | |||
| 1276 | } | |||
| 1277 | close_output_pbs(&rbody); | |||
| 1278 | close_output_pbs(&reply_stream); | |||
| 1279 | ||||
| 1280 | /* | |||
| 1281 | * For AUTH exchange, store the message in the IKE SA. | |||
| 1282 | * The attempt to create the CHILD SA could have | |||
| 1283 | * failed. | |||
| 1284 | */ | |||
| 1285 | stf_status status = record_v2SK_message(&reply_stream, &sk, | |||
| 1286 | "replying to IKE_AUTH request", | |||
| 1287 | MESSAGE_RESPONSE); | |||
| 1288 | ||||
| 1289 | return status; | |||
| 1290 | } | |||
| 1291 | ||||
| 1292 | /* STATE_V2_PARENT_I2: R2 --> I3 | |||
| 1293 | * <-- HDR, SK {IDr, [CERT,] AUTH, | |||
| 1294 | * [SAr2,] [TSi,] [TSr,]} | |||
| 1295 | * [Parent SA established] | |||
| 1296 | * | |||
| 1297 | * For error handling in this function, please read: | |||
| 1298 | * https://tools.ietf.org/html/rfc7296#section-2.21.2 | |||
| 1299 | */ | |||
| 1300 | ||||
| 1301 | static stf_status process_v2_IKE_AUTH_response_post_cert_decode(struct state *st, struct msg_digest *md); | |||
| 1302 | ||||
| 1303 | stf_status process_v2_IKE_AUTH_response(struct ike_sa *ike, struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
| 1304 | struct msg_digest *md) | |||
| 1305 | { | |||
| 1306 | /* | |||
| 1307 | * If the initiator rejects the responders authentication it | |||
| 1308 | * should immediately send a delete notification and wipe the SA. | |||
| 1309 | * | |||
| 1310 | * This doesn't happen. Instead the SA is deleted. | |||
| 1311 | */ | |||
| 1312 | struct payload_digest *cert_payloads = md->chain[ISAKMP_NEXT_v2CERT]; | |||
| 1313 | if (cert_payloads != NULL((void*)0)) { | |||
| 1314 | submit_cert_decode(ike, &ike->sa, md, cert_payloads, | |||
| 1315 | process_v2_IKE_AUTH_response_post_cert_decode, | |||
| 1316 | "initiator decoding certificates"); | |||
| 1317 | return STF_SUSPEND; | |||
| 1318 | } else { | |||
| 1319 | dbg("no certs to decode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no certs to decode"); } }; | |||
| 1320 | ike->sa.st_remote_certs.processed = true1; | |||
| 1321 | ike->sa.st_remote_certs.harmless = true1; | |||
| 1322 | return process_v2_IKE_AUTH_response_post_cert_decode(&ike->sa, md); | |||
| 1323 | } | |||
| 1324 | } | |||
| 1325 | ||||
| 1326 | static stf_status process_v2_IKE_AUTH_response_post_cert_decode(struct state *ike_sa, struct msg_digest *md) | |||
| 1327 | { | |||
| 1328 | passert(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 1328, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_passert(logger_, here, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } (void) 1; }); | |||
| 1329 | struct ike_sa *ike = pexpect_ike_sa(ike_sa); | |||
| 1330 | ||||
| 1331 | diag_t d = ikev2_initiator_decode_responder_id(ike, md); | |||
| 1332 | if (d != NULL((void*)0)) { | |||
| 1333 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
| 1334 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 1335 | /* | |||
| 1336 | * We cannot send a response as we are processing | |||
| 1337 | * IKE_AUTH reply the RFC states we should pretend | |||
| 1338 | * IKE_AUTH was okay, and then send an INFORMATIONAL | |||
| 1339 | * DELETE IKE SA but we have not implemented that yet. | |||
| 1340 | */ | |||
| 1341 | return STF_V2_DELETE_IKE_AUTH_INITIATOR; | |||
| 1342 | } | |||
| 1343 | ||||
| 1344 | struct connection *c = ike->sa.st_connection; | |||
| 1345 | enum keyword_authby that_authby = c->spd.that.authby; | |||
| 1346 | ||||
| 1347 | passert(that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET)({ _Bool assertion__ = that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET; if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1347, }; &here ; }); const struct logger *logger_ = &failsafe_logger; llog_passert (logger_, here, "%s", "that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET" ); } (void) 1; }); | |||
| 1348 | ||||
| 1349 | if (md->pd[PD_v2N_PPK_IDENTITY] != NULL((void*)0)) { | |||
| 1350 | if (!LIN(POLICY_PPK_ALLOW, c->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) { | |||
| 1351 | llog_sa(RC_LOG_SERIOUS, ike, "received PPK_IDENTITY but connection does not allow PPK")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "received PPK_IDENTITY but connection does not allow PPK" ); | |||
| 1352 | return STF_FATAL; | |||
| 1353 | } | |||
| 1354 | } else { | |||
| 1355 | if (LIN(POLICY_PPK_INSIST, c->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
| 1356 | llog_sa(RC_LOG_SERIOUS, ike,llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "failed to receive PPK confirmation and connection has ppk=insist" ) | |||
| 1357 | "failed to receive PPK confirmation and connection has ppk=insist")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "failed to receive PPK confirmation and connection has ppk=insist" ); | |||
| 1358 | dbg("should be initiating a notify that kills the state"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("should be initiating a notify that kills the state" ); } }; | |||
| 1359 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 1360 | return STF_FATAL; | |||
| 1361 | } | |||
| 1362 | } | |||
| 1363 | ||||
| 1364 | /* | |||
| 1365 | * If we sent USE_PPK and we did not receive a PPK_IDENTITY, | |||
| 1366 | * it means the responder failed to find our PPK ID, but allowed | |||
| 1367 | * the connection to continue without PPK by using our NO_PPK_AUTH | |||
| 1368 | * payload. We should revert our key material to NO_PPK versions. | |||
| 1369 | */ | |||
| 1370 | if (ike->sa.st_seen_ppk && | |||
| 1371 | md->pd[PD_v2N_PPK_IDENTITY] == NULL((void*)0) && | |||
| 1372 | LIN(POLICY_PPK_ALLOW, c->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) { | |||
| 1373 | /* discard the PPK based calculations */ | |||
| 1374 | ||||
| 1375 | log_state(RC_LOG, &ike->sa, "peer wants to continue without PPK - switching to NO_PPK"); | |||
| 1376 | ||||
| 1377 | release_symkey(__func__, "st_skey_d_nss", &ike->sa.st_skey_d_nss); | |||
| 1378 | ike->sa.st_skey_d_nss = reference_symkey(__func__, "used sk_d from no ppk", ike->sa.st_sk_d_no_ppk); | |||
| 1379 | ||||
| 1380 | release_symkey(__func__, "st_skey_pi_nss", &ike->sa.st_skey_pi_nss); | |||
| 1381 | ike->sa.st_skey_pi_nss = reference_symkey(__func__, "used sk_pi from no ppk", ike->sa.st_sk_pi_no_ppk); | |||
| 1382 | ||||
| 1383 | release_symkey(__func__, "st_skey_pr_nss", &ike->sa.st_skey_pr_nss); | |||
| 1384 | ike->sa.st_skey_pr_nss = reference_symkey(__func__, "used sk_pr from no ppk", ike->sa.st_sk_pr_no_ppk); | |||
| 1385 | } | |||
| 1386 | ||||
| 1387 | struct crypt_mac idhash_in = v2_id_hash(ike, "idhash auth R2", "IDr", | |||
| 1388 | same_pbs_in_as_shunk(&md->chain[ISAKMP_NEXT_v2IDr]->pbs), | |||
| 1389 | "skey_pr", ike->sa.st_skey_pr_nss); | |||
| 1390 | ||||
| 1391 | /* process AUTH payload */ | |||
| 1392 | ||||
| 1393 | dbg("initiator verifying AUTH payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("initiator verifying AUTH payload"); } }; | |||
| 1394 | d = v2_authsig_and_log(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
| 1395 | ike, &idhash_in, &md->chain[ISAKMP_NEXT_v2AUTH]->pbs, that_authby); | |||
| 1396 | if (d != NULL((void*)0)) { | |||
| 1397 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
| 1398 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 1399 | /* | |||
| 1400 | * We cannot send a response as we are processing | |||
| 1401 | * IKE_AUTH reply the RFC states we should pretend | |||
| 1402 | * IKE_AUTH was okay, and then send an INFORMATIONAL | |||
| 1403 | * DELETE IKE SA but we have not implemented that yet. | |||
| 1404 | */ | |||
| 1405 | return STF_V2_DELETE_IKE_AUTH_INITIATOR; | |||
| 1406 | } | |||
| 1407 | ||||
| 1408 | /* | |||
| 1409 | * AUTH succeeed | |||
| 1410 | * | |||
| 1411 | * update the parent state to make sure that it knows we have | |||
| 1412 | * authenticated properly. | |||
| 1413 | */ | |||
| 1414 | ikev2_ike_sa_established(ike, md->svm, STATE_V2_ESTABLISHED_IKE_SA); | |||
| 1415 | ||||
| 1416 | /* | |||
| 1417 | * IF there's a redirect, process it and return immediately. | |||
| 1418 | * Function gets to decide status. | |||
| 1419 | */ | |||
| 1420 | stf_status redirect_status = STF_OK; | |||
| 1421 | if (redirect_ike_auth(ike, md, &redirect_status)) { | |||
| 1422 | return redirect_status; | |||
| 1423 | } | |||
| 1424 | ||||
| 1425 | ike->sa.st_ike_seen_v2n_mobike_supported = (md->pd[PD_v2N_MOBIKE_SUPPORTED] != NULL((void*)0)); | |||
| 1426 | if (ike->sa.st_ike_seen_v2n_mobike_supported) { | |||
| 1427 | dbg("received v2N_MOBIKE_SUPPORTED %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", (ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" )); } } | |||
| 1428 | (ike->sa.st_ike_sent_v2n_mobike_supported ? "and sent" :{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", (ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" )); } } | |||
| 1429 | "while it did not sent")){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", (ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" )); } }; | |||
| 1430 | } | |||
| 1431 | ||||
| 1432 | /* | |||
| 1433 | * Keep the portal open ... | |||
| 1434 | */ | |||
| 1435 | if (LHAS(ike->sa.hidden_variables.st_nat_traversal, NATED_HOST)(((ike->sa.hidden_variables.st_nat_traversal) & ((lset_t )1 << (NATED_HOST))) != ((lset_t)0))) { | |||
| 1436 | /* ensure we run keepalives if needed */ | |||
| 1437 | if (c->nat_keepalive) { | |||
| 1438 | /* | |||
| 1439 | * Trigger a keep alive for all states. | |||
| 1440 | * | |||
| 1441 | * XXX: call nat_traversal_new_ka_event() | |||
| 1442 | * instead? There's no hurry right? | |||
| 1443 | */ | |||
| 1444 | nat_traversal_ka_event(ike->sa.st_logger); | |||
| 1445 | } | |||
| 1446 | } | |||
| 1447 | ||||
| 1448 | if (c->config->sec_label.len > 0) { | |||
| 1449 | pexpect(c->kind == CK_TEMPLATE)({ _Bool assertion__ = c->kind == CK_TEMPLATE; if (!assertion__ ) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1449, }; &here; }); const struct logger *logger_ = & failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->kind == CK_TEMPLATE" ); } assertion__; }); | |||
| 1450 | pexpect(c->spd.this.sec_label.len == 0)({ _Bool assertion__ = c->spd.this.sec_label.len == 0; if ( !assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 1450, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->spd.this.sec_label.len == 0" ); } assertion__; }); | |||
| 1451 | if (!install_se_connection_policies(c, ike->sa.st_logger)) { | |||
| 1452 | return STF_FATAL; | |||
| 1453 | } | |||
| 1454 | } | |||
| 1455 | ||||
| 1456 | /* | |||
| 1457 | * Figure out of the child is both expected and viable. | |||
| 1458 | * | |||
| 1459 | * See 2.21.2. Error Handling in IKE_AUTH | |||
| 1460 | */ | |||
| 1461 | ||||
| 1462 | v2_notification_t n = process_v2_IKE_AUTH_response_child_sa_payloads(ike, md); | |||
| 1463 | ||||
| 1464 | if (v2_notification_fatal(n)) { | |||
| 1465 | /* already logged */ | |||
| 1466 | /* | |||
| 1467 | * XXX: there was something "really bad" about the | |||
| 1468 | * child. Should be sending the fatal notification in | |||
| 1469 | * a new exchange (see RFC); returning STF_FATAL just | |||
| 1470 | * causes the IKE SA to silently self-destruct. | |||
| 1471 | */ | |||
| 1472 | return STF_FATAL; | |||
| 1473 | } | |||
| 1474 | ||||
| 1475 | if(n != v2N_NOTHING_WRONG) { | |||
| 1476 | /* already logged */ | |||
| 1477 | /* | |||
| 1478 | * This end (the initiator) did not like something | |||
| 1479 | * about the Child SA. | |||
| 1480 | * | |||
| 1481 | * (If the responder sent back an error notification | |||
| 1482 | * to reject the Child SA, then the above call would | |||
| 1483 | * have cleaned up the mess and return | |||
| 1484 | * v2N_NOTHING_WRONG. After all, problem solved. | |||
| 1485 | */ | |||
| 1486 | llog_sa(RC_LOG_SERIOUS, ike, "IKE SA established but initiator rejected Child SA response")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "IKE SA established but initiator rejected Child SA response" ); | |||
| 1487 | struct child_sa *larval_child = ike->sa.st_v2_larval_initiator_sa; | |||
| 1488 | ike->sa.st_v2_larval_initiator_sa = NULL((void*)0); | |||
| 1489 | passert(larval_child != NULL)({ _Bool assertion__ = larval_child != ((void*)0); if (!assertion__ ) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1489, }; &here; }); const struct logger *logger_ = & failsafe_logger; llog_passert(logger_, here, "%s", "larval_child != ((void*)0)" ); } (void) 1; }); | |||
| 1490 | /* | |||
| 1491 | * Needed to un-plug the pending queue. Without this | |||
| 1492 | * the next pending exchange is never started. | |||
| 1493 | * | |||
| 1494 | * While not obvious from the name - unpend() - the | |||
| 1495 | * code is doing two things: removing LARVAL_CHILD's | |||
| 1496 | * pending connection; and submitting a request to | |||
| 1497 | * initiate the next pending connection, if any. | |||
| 1498 | * | |||
| 1499 | * The key thing here is that unpend() delays creating | |||
| 1500 | * the next child until after the previous child is | |||
| 1501 | * done. Avoiding a race for which child goes next. | |||
| 1502 | * | |||
| 1503 | * For IKEv2, should merge the pending queue into the | |||
| 1504 | * Message ID queue. Have a queue of exchanges, and a | |||
| 1505 | * queue of things to do when there are no exchanges. | |||
| 1506 | */ | |||
| 1507 | unpend(ike, larval_child->sa.st_connection); | |||
| 1508 | /* | |||
| 1509 | * Quickly delete this larval SA. | |||
| 1510 | */ | |||
| 1511 | submit_v2_delete_exchange(ike, larval_child); | |||
| 1512 | } | |||
| 1513 | ||||
| 1514 | return STF_OK; | |||
| 1515 | } | |||
| 1516 | ||||
| 1517 | /* | |||
| 1518 | * 2.21.2. Error Handling in IKE_AUTH | |||
| 1519 | * | |||
| 1520 | * ... If the error occurred on the responder, the | |||
| 1521 | * notification is returned in the protected response, and is | |||
| 1522 | * usually the only payload in that response. Although the IKE_AUTH | |||
| 1523 | * messages are encrypted and integrity protected, if the peer | |||
| 1524 | * receiving this notification has not authenticated the other end | |||
| 1525 | * yet, that peer needs to treat the information with caution. | |||
| 1526 | * | |||
| 1527 | * Continuing to retransmit is pointless - it will get back | |||
| 1528 | * the same response. | |||
| 1529 | */ | |||
| 1530 | ||||
| 1531 | stf_status process_v2_IKE_AUTH_failure_response(struct ike_sa *ike, | |||
| 1532 | struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
| 1533 | struct msg_digest *md) | |||
| 1534 | { | |||
| 1535 | struct child_sa *child = ike->sa.st_v2_larval_initiator_sa; | |||
| 1536 | ||||
| 1537 | /* | |||
| 1538 | * Mark IKE SA as failing. | |||
| 1539 | */ | |||
| 1540 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 1541 | ||||
| 1542 | /* | |||
| 1543 | * Try to print a meaningful log of the notification error; | |||
| 1544 | * but do it in slightly different ways so it is possible to | |||
| 1545 | * figure out which code path was taken. | |||
| 1546 | */ | |||
| 1547 | ||||
| 1548 | /* | |||
| 1549 | * These are all IKE SA failures - try to blame IKE first. | |||
| 1550 | */ | |||
| 1551 | ||||
| 1552 | bool_Bool logged_something_serious = false0; | |||
| 1553 | FOR_EACH_THING(pd, PD_v2N_INVALID_SYNTAX, PD_v2N_AUTHENTICATION_FAILED,for (typeof(PD_v2N_INVALID_SYNTAX) things_[] = { PD_v2N_INVALID_SYNTAX , PD_v2N_AUTHENTICATION_FAILED, PD_v2N_UNSUPPORTED_CRITICAL_PAYLOAD }, *thingp_ = things_, pd; thingp_ < things_ + (sizeof(things_ ) / sizeof(*(things_))) ? (pd = *thingp_, 1) : 0; thingp_++) | |||
| 1554 | PD_v2N_UNSUPPORTED_CRITICAL_PAYLOAD)for (typeof(PD_v2N_INVALID_SYNTAX) things_[] = { PD_v2N_INVALID_SYNTAX , PD_v2N_AUTHENTICATION_FAILED, PD_v2N_UNSUPPORTED_CRITICAL_PAYLOAD }, *thingp_ = things_, pd; thingp_ < things_ + (sizeof(things_ ) / sizeof(*(things_))) ? (pd = *thingp_, 1) : 0; thingp_++) { | |||
| 1555 | if (md->pd[pd] != NULL((void*)0)) { | |||
| 1556 | v2_notification_t n = md->pd[pd]->payload.v2n.isan_type; | |||
| 1557 | pstat(ikev2_recv_notifies_e, n){ const unsigned pstat_ = (n); const struct pluto_stat *ps_ = &pstats_ikev2_recv_notifies_e; if (pstat_ < ps_->floor || pstat_ >= ps_->roof) { ps_->count[ps_->roof - ps_->floor]++; } else { ps_->count[pstat_-ps_->floor ]++; } }; | |||
| 1558 | const char *why = enum_name_short(&ikev2_notify_names, n); | |||
| 1559 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 1560 | "IKE SA authentication request rejected by peer: %s", why); | |||
| 1561 | logged_something_serious = true1; | |||
| 1562 | break; | |||
| 1563 | } | |||
| 1564 | } | |||
| 1565 | ||||
| 1566 | if (!logged_something_serious) { | |||
| 1567 | /* | |||
| 1568 | * Dump as much information as possible. | |||
| 1569 | */ | |||
| 1570 | for (struct payload_digest *ntfy = md->chain[ISAKMP_NEXT_v2N]; | |||
| 1571 | ntfy != NULL((void*)0); ntfy = ntfy->next) { | |||
| 1572 | v2_notification_t n = ntfy->payload.v2n.isan_type; | |||
| 1573 | /* same scope */ | |||
| 1574 | esb_buf esb; | |||
| 1575 | const char *name = enum_show_short(&ikev2_notify_names, n, &esb); | |||
| 1576 | ||||
| 1577 | if (ntfy->payload.v2n.isan_spisize != 0) { | |||
| 1578 | /* invalid-syntax, but can't do anything about it */ | |||
| 1579 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 1580 | "received an encrypted %s notification with an unexpected non-empty SPI; deleting IKE SA", | |||
| 1581 | name); | |||
| 1582 | logged_something_serious = true1; | |||
| 1583 | break; | |||
| 1584 | } | |||
| 1585 | ||||
| 1586 | if (n >= v2N_STATUS_FLOOR) { | |||
| 1587 | /* just log */ | |||
| 1588 | pstat(ikev2_recv_notifies_s, n){ const unsigned pstat_ = (n); const struct pluto_stat *ps_ = &pstats_ikev2_recv_notifies_s; if (pstat_ < ps_->floor || pstat_ >= ps_->roof) { ps_->count[ps_->roof - ps_->floor]++; } else { ps_->count[pstat_-ps_->floor ]++; } }; | |||
| 1589 | log_state(RC_LOG, &ike->sa, | |||
| 1590 | "IKE_AUTH response contained the status notification %s", name); | |||
| 1591 | } else { | |||
| 1592 | pstat(ikev2_recv_notifies_e, n){ const unsigned pstat_ = (n); const struct pluto_stat *ps_ = &pstats_ikev2_recv_notifies_e; if (pstat_ < ps_->floor || pstat_ >= ps_->roof) { ps_->count[ps_->roof - ps_->floor]++; } else { ps_->count[pstat_-ps_->floor ]++; } }; | |||
| 1593 | logged_something_serious = true1; | |||
| 1594 | /* | |||
| 1595 | * There won't be a child state | |||
| 1596 | * transition, so log if error is | |||
| 1597 | * child related. | |||
| 1598 | * | |||
| 1599 | * see RFC 7296 Section 1.2 | |||
| 1600 | */ | |||
| 1601 | switch(n) { | |||
| 1602 | case v2N_NO_PROPOSAL_CHOSEN: | |||
| 1603 | case v2N_SINGLE_PAIR_REQUIRED: | |||
| 1604 | case v2N_NO_ADDITIONAL_SAS: | |||
| 1605 | case v2N_INTERNAL_ADDRESS_FAILURE: | |||
| 1606 | case v2N_FAILED_CP_REQUIRED: | |||
| 1607 | case v2N_TS_UNACCEPTABLE: | |||
| 1608 | case v2N_INVALID_SELECTORS: | |||
| 1609 | if (child == NULL((void*)0)) { | |||
| 1610 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 1611 | "IKE_AUTH response contained the CHILD SA error notification '%s' but there is no child", name); | |||
| 1612 | } else { | |||
| 1613 | log_state(RC_LOG_SERIOUS, &child->sa, | |||
| 1614 | "IKE_AUTH response contained the error notification %s", name); | |||
| 1615 | } | |||
| 1616 | break; | |||
| 1617 | default: | |||
| 1618 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 1619 | "IKE_AUTH response contained the error notification %s", name); | |||
| 1620 | break; | |||
| 1621 | } | |||
| 1622 | /* first is enough */ | |||
| 1623 | break; | |||
| 1624 | } | |||
| 1625 | } | |||
| 1626 | } | |||
| 1627 | ||||
| 1628 | if (!logged_something_serious) { | |||
| 1629 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 1630 | "IKE SA authentication request rejected by peer: unrecognized response"); | |||
| 1631 | } | |||
| 1632 | ||||
| 1633 | return STF_FATAL; | |||
| 1634 | } |