File: | programs/pluto/ikev2.c |
Warning: | line 3684, column 8 Dereference of null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* demultiplex incoming IKE messages | |||
2 | * | |||
3 | * Copyright (C) 1997 Angelos D. Keromytis. | |||
4 | * Copyright (C) 1998-2010,2013-2017 D. Hugh Redelmeier <hugh@mimosa.com> | |||
5 | * Copyright (C) 2007-2008 Michael Richardson <mcr@xelerance.com> | |||
6 | * Copyright (C) 2009 David McCullough <david_mccullough@securecomputing.com> | |||
7 | * Copyright (C) 2008-2011 Paul Wouters <paul@xelerance.com> | |||
8 | * Copyright (C) 2010 Simon Deziel <simon@xelerance.com> | |||
9 | * Copyright (C) 2010 Tuomo Soini <tis@foobar.fi> | |||
10 | * Copyright (C) 2011-2012 Avesh Agarwal <avagarwa@redhat.com> | |||
11 | * Copyright (C) 2012 Paul Wouters <paul@libreswan.org> | |||
12 | * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com> | |||
13 | * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com> | |||
14 | * Copyright (C) 2015-2019 Andrew Cagney | |||
15 | * Copyright (C) 2016-2018 Antony Antony <appu@phenome.org> | |||
16 | * Copyright (C) 2017 Sahana Prasad <sahana.prasad07@gmail.com> | |||
17 | * | |||
18 | * This program is free software; you can redistribute it and/or modify it | |||
19 | * under the terms of the GNU General Public License as published by the | |||
20 | * Free Software Foundation; either version 2 of the License, or (at your | |||
21 | * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>. | |||
22 | * | |||
23 | * This program is distributed in the hope that it will be useful, but | |||
24 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |||
25 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
26 | * for more details. | |||
27 | * | |||
28 | */ | |||
29 | ||||
30 | #include <unistd.h> | |||
31 | #include <sys/types.h> | |||
32 | #include <sys/socket.h> | |||
33 | #include <netinet/in.h> | |||
34 | #include <arpa/inet.h> | |||
35 | ||||
36 | ||||
37 | #include "sysdep.h" | |||
38 | #include "constants.h" | |||
39 | ||||
40 | #include "defs.h" | |||
41 | #include "id.h" | |||
42 | #include "x509.h" | |||
43 | #include "pluto_x509.h" | |||
44 | #include "certs.h" | |||
45 | #include "connections.h" /* needs id.h */ | |||
46 | #include "state.h" | |||
47 | #include "packet.h" | |||
48 | #include "crypto.h" | |||
49 | #include "crypt_symkey.h" | |||
50 | #include "ike_alg.h" | |||
51 | #include "log.h" | |||
52 | #include "demux.h" /* needs packet.h */ | |||
53 | #include "pluto_crypt.h" /* for pluto_crypto_req & pluto_crypto_req_cont */ | |||
54 | #include "ikev2.h" | |||
55 | #include "ipsec_doi.h" /* needs demux.h and state.h */ | |||
56 | #include "timer.h" | |||
57 | #include "whack.h" /* requires connections.h */ | |||
58 | #include "server.h" | |||
59 | #include "spdb.h" | |||
60 | #include "nat_traversal.h" | |||
61 | #include "vendor.h" | |||
62 | #include "ip_address.h" | |||
63 | #include "ikev2_send.h" | |||
64 | #include "state_db.h" | |||
65 | #include "ietf_constants.h" | |||
66 | #include "ikev2_cookie.h" | |||
67 | #include "plutoalg.h" /* for default_ike_groups */ | |||
68 | #include "ikev2_message.h" /* for ikev2_decrypt_msg() */ | |||
69 | #include "pluto_stats.h" | |||
70 | #include "keywords.h" | |||
71 | #include "ikev2_msgid.h" | |||
72 | #include "ikev2_redirect.h" | |||
73 | #include "ikev2_states.h" | |||
74 | #include "ip_endpoint.h" | |||
75 | #include "hostpair.h" /* for find_v2_host_connection() */ | |||
76 | #include "kernel.h" | |||
77 | #include "iface.h" | |||
78 | #include "ikev2_notify.h" | |||
79 | ||||
80 | static void v2_dispatch(struct ike_sa *ike, struct state *st, | |||
81 | struct msg_digest *md, | |||
82 | const struct state_v2_microcode *transition); | |||
83 | ||||
84 | /* | |||
85 | * IKEv2 has slightly different states than IKEv1. | |||
86 | * | |||
87 | * IKEv2 puts all the responsibility for retransmission on the end that | |||
88 | * wants to do something, usually, that the initiator. (But, not always | |||
89 | * the original initiator, of the responder decides it needs to rekey first) | |||
90 | * | |||
91 | * Each exchange has a bit that indicates if it is an Initiator message, | |||
92 | * or if it is a response. The Responder never retransmits its messages | |||
93 | * except in response to an Initiator retransmission. | |||
94 | * | |||
95 | * The message ID is *NOT* used in the cryptographic state at all, but instead | |||
96 | * serves the role of a sequence number. This makes the state machine far | |||
97 | * simpler, and there really are no exceptions. | |||
98 | * | |||
99 | * The upper level state machine is therefore much simpler. | |||
100 | * The lower level takes care of retransmissions, and the upper layer state | |||
101 | * machine just has to worry about whether it needs to go into cookie mode, | |||
102 | * etc. | |||
103 | * | |||
104 | * Like IKEv1, IKEv2 can have multiple child SAs. Like IKEv1, each one of | |||
105 | * the child SAs ("Phase 2") will get their own state. Unlike IKEv1, | |||
106 | * an implementation may negotiate multiple CHILD_SAs at the same time | |||
107 | * using different MessageIDs. This is enabled by an option (a notify) | |||
108 | * that the responder sends to the initiator. The initiator may only | |||
109 | * do concurrent negotiations if it sees the notify. | |||
110 | * | |||
111 | * XXX This implementation does not support concurrency, but it shouldn't be | |||
112 | * that hard to do. The most difficult part will be to map the message IDs | |||
113 | * to the right state. Some CHILD_SAs may take multiple round trips, | |||
114 | * and each one will have to be mapped to the same state. | |||
115 | * | |||
116 | * The IKEv2 state values are chosen from the same state space as IKEv1. | |||
117 | * | |||
118 | */ | |||
119 | ||||
120 | /* | |||
121 | * From RFC 5996 syntax: [optional] and {encrypted} | |||
122 | * | |||
123 | * Initiator Responder | |||
124 | * ------------------------------------------------------------------- | |||
125 | * | |||
126 | * IKE_SA_INIT exchange (initial exchange): | |||
127 | * | |||
128 | * HDR, SAi1, KEi, Ni --> | |||
129 | * <-- HDR, SAr1, KEr, Nr, [CERTREQ] | |||
130 | * | |||
131 | * IKE_AUTH exchange (after IKE_SA_INIT exchange): | |||
132 | * | |||
133 | * HDR, SK {IDi, [CERT,] [CERTREQ,] | |||
134 | * [IDr,] AUTH, SAi2, | |||
135 | * TSi, TSr} --> | |||
136 | * <-- HDR, SK {IDr, [CERT,] AUTH, | |||
137 | * SAr2, TSi, TSr} | |||
138 | * [Parent SA (SAx1) established. Child SA (SAx2) may have been established] | |||
139 | * | |||
140 | * | |||
141 | * Extended IKE_AUTH (see RFC 5996bis 2.6): | |||
142 | * | |||
143 | * HDR(A,0), SAi1, KEi, Ni --> | |||
144 | * <-- HDR(A,0), N(COOKIE) | |||
145 | * HDR(A,0), N(COOKIE), SAi1, | |||
146 | * KEi, Ni --> | |||
147 | * <-- HDR(A,B), SAr1, KEr, | |||
148 | * Nr, [CERTREQ] | |||
149 | * HDR(A,B), SK {IDi, [CERT,] | |||
150 | * [CERTREQ,] [IDr,] AUTH, | |||
151 | * SAi2, TSi, TSr} --> | |||
152 | * <-- HDR(A,B), SK {IDr, [CERT,] | |||
153 | * AUTH, SAr2, TSi, TSr} | |||
154 | * [Parent SA (SAx1) established. Child SA (SAx2) may have been established] | |||
155 | * | |||
156 | * | |||
157 | * CREATE_CHILD_SA Exchange (new child variant RFC 5996 1.3.1): | |||
158 | * | |||
159 | * HDR, SK {SA, Ni, [KEi], | |||
160 | * TSi, TSr} --> | |||
161 | * <-- HDR, SK {SA, Nr, [KEr], | |||
162 | * TSi, TSr} | |||
163 | * | |||
164 | * | |||
165 | * CREATE_CHILD_SA Exchange (rekey child variant RFC 5996 1.3.3): | |||
166 | * | |||
167 | * HDR, SK {N(REKEY_SA), SA, Ni, [KEi], | |||
168 | * TSi, TSr} --> | |||
169 | * <-- HDR, SK {SA, Nr, [KEr], | |||
170 | * TSi, TSr} | |||
171 | * | |||
172 | * | |||
173 | * CREATE_CHILD_SA Exchange (rekey parent SA variant RFC 5996 1.3.2): | |||
174 | * | |||
175 | * HDR, SK {SA, Ni, KEi} --> | |||
176 | * <-- HDR, SK {SA, Nr, KEr} | |||
177 | */ | |||
178 | ||||
179 | /* Short forms for building payload type sets */ | |||
180 | ||||
181 | #define P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) LELEM(ISAKMP_NEXT_v2##N)((lset_t)1 << (ISAKMP_NEXT_v2##N)) | |||
182 | ||||
183 | /* | |||
184 | * IKEv2 State transitions (aka microcodes). | |||
185 | * | |||
186 | * This table contains all possible state transitions, some of which | |||
187 | * involve a message. | |||
188 | * | |||
189 | * During initialization this table parsed populating the | |||
190 | * corresponding IKEv2 finite states. While not the most efficient, | |||
191 | * it seems to work. | |||
192 | */ | |||
193 | ||||
194 | static /*const*/ struct state_v2_microcode v2_state_microcode_table[] = { | |||
195 | ||||
196 | #define req_clear_payloads message_payloads.required /* required unencrypted payloads (allows just one) for received packet */ | |||
197 | #define opt_clear_payloads message_payloads.optional /* optional unencrypted payloads (none or one) for received packet */ | |||
198 | #define req_enc_payloads encrypted_payloads.required /* required encrypted payloads (allows just one) for received packet */ | |||
199 | #define opt_enc_payloads encrypted_payloads.optional /* optional encrypted payloads (none or one) for received packet */ | |||
200 | ||||
201 | /* no state: --> CREATE_CHILD IKE Rekey Request | |||
202 | * HDR, SAi, KEi, Ni --> | |||
203 | */ | |||
204 | ||||
205 | { .story = "Initiate CREATE_CHILD_SA IKE Rekey", | |||
206 | .state = STATE_V2_REKEY_IKE_I0, | |||
207 | .next_state = STATE_V2_REKEY_IKE_I1, | |||
208 | .send = MESSAGE_REQUEST, | |||
209 | .processor = NULL((void*)0), | |||
210 | .timeout_event = EVENT_RETRANSMIT, }, | |||
211 | ||||
212 | /* no state: --> CREATE IPsec Rekey Request | |||
213 | * HDR, SAi1, N(REKEY_SA), {KEi,} Ni TSi TSr --> | |||
214 | */ | |||
215 | { .story = "Initiate CREATE_CHILD_SA IPsec Rekey SA", | |||
216 | .state = STATE_V2_REKEY_CHILD_I0, | |||
217 | .next_state = STATE_V2_REKEY_CHILD_I1, | |||
218 | .send = MESSAGE_REQUEST, | |||
219 | .processor = NULL((void*)0), | |||
220 | .timeout_event = EVENT_RETRANSMIT, }, | |||
221 | ||||
222 | /* no state: --> CREATE IPsec Child Request | |||
223 | * HDR, SAi1, {KEi,} Ni TSi TSr --> | |||
224 | */ | |||
225 | { .story = "Initiate CREATE_CHILD_SA IPsec SA", | |||
226 | .state = STATE_V2_NEW_CHILD_I0, | |||
227 | .next_state = STATE_V2_NEW_CHILD_I1, | |||
228 | .send = MESSAGE_REQUEST, | |||
229 | .processor = NULL((void*)0), | |||
230 | .timeout_event = EVENT_RETRANSMIT, }, | |||
231 | ||||
232 | /* no state: --> I1 | |||
233 | * HDR, SAi1, KEi, Ni --> | |||
234 | */ | |||
235 | { .story = "initiate IKE_SA_INIT", | |||
236 | .state = STATE_PARENT_I0, | |||
237 | .next_state = STATE_PARENT_I1, | |||
238 | .send = MESSAGE_REQUEST, | |||
239 | .processor = NULL((void*)0), | |||
240 | .timeout_event = EVENT_RETRANSMIT, }, | |||
241 | ||||
242 | /* STATE_PARENT_I1: R1B --> I1B | |||
243 | * <-- HDR, N | |||
244 | * HDR, N, SAi1, KEi, Ni --> | |||
245 | */ | |||
246 | ||||
247 | { .story = "received anti-DDOS COOKIE notify response; resending IKE_SA_INIT request with cookie payload added", | |||
248 | .state = STATE_PARENT_I1, | |||
249 | .next_state = STATE_PARENT_I0, | |||
250 | .flags = SMF2_SUPPRESS_SUCCESS_LOG, | |||
251 | .send = NO_MESSAGE, | |||
252 | .message_payloads = { .required = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), .notification = v2N_COOKIE, }, | |||
253 | .processor = process_IKE_SA_INIT_v2N_COOKIE_response, | |||
254 | .recv_role = MESSAGE_RESPONSE, | |||
255 | .recv_type = ISAKMP_v2_IKE_SA_INIT, | |||
256 | .timeout_event = EVENT_SO_DISCARD, }, | |||
257 | ||||
258 | { .story = "received IKE_SA_INIT INVALID_KE_PAYLOAD notify response; resending IKE_SA_INIT with new KE payload", | |||
259 | .state = STATE_PARENT_I1, | |||
260 | .next_state = STATE_PARENT_I0, | |||
261 | .flags = SMF2_SUPPRESS_SUCCESS_LOG, | |||
262 | .send = NO_MESSAGE, | |||
263 | .message_payloads = { .required = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), .notification = v2N_INVALID_KE_PAYLOAD, }, | |||
264 | .processor = process_IKE_SA_INIT_v2N_INVALID_KE_PAYLOAD_response, | |||
265 | .recv_role = MESSAGE_RESPONSE, | |||
266 | .recv_type = ISAKMP_v2_IKE_SA_INIT, | |||
267 | .timeout_event = EVENT_SO_DISCARD, }, | |||
268 | ||||
269 | { .story = "received REDIRECT notify response; resending IKE_SA_INIT request to new destination", | |||
270 | .state = STATE_PARENT_I1, | |||
271 | .next_state = STATE_IKESA_DEL, | |||
272 | .flags = SMF2_SUPPRESS_SUCCESS_LOG, | |||
273 | .send = NO_MESSAGE, | |||
274 | .message_payloads = { .required = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), .notification = v2N_REDIRECT, }, | |||
275 | .processor = process_IKE_SA_INIT_v2N_REDIRECT_response, | |||
276 | .recv_role = MESSAGE_RESPONSE, | |||
277 | .recv_type = ISAKMP_v2_IKE_SA_INIT, | |||
278 | /* XXX: this is an instant timeout */ | |||
279 | .timeout_event = EVENT_v2_REDIRECT, | |||
280 | }, | |||
281 | ||||
282 | /* STATE_PARENT_I1: R1 --> I2 | |||
283 | * <-- HDR, SAr1, KEr, Nr, [CERTREQ] | |||
284 | * HDR, SK {IDi, [CERT,] [CERTREQ,] | |||
285 | * [IDr,] AUTH, SAi2, | |||
286 | * TSi, TSr} --> | |||
287 | */ | |||
288 | { .story = "Initiator: process IKE_SA_INIT reply, initiate IKE_AUTH", | |||
289 | .state = STATE_PARENT_I1, | |||
290 | .next_state = STATE_PARENT_I2, | |||
291 | .send = MESSAGE_REQUEST, | |||
292 | .req_clear_payloads = P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(KE)((lset_t)1 << (ISAKMP_NEXT_v2KE)) | P(Nr)((lset_t)1 << (ISAKMP_NEXT_v2Nr)), | |||
293 | .opt_clear_payloads = P(CERTREQ)((lset_t)1 << (ISAKMP_NEXT_v2CERTREQ)), | |||
294 | .processor = ikev2_parent_inR1outI2, | |||
295 | .recv_role = MESSAGE_RESPONSE, | |||
296 | .recv_type = ISAKMP_v2_IKE_SA_INIT, | |||
297 | .timeout_event = EVENT_RETRANSMIT, }, | |||
298 | ||||
299 | /* STATE_PARENT_I2: R2 --> | |||
300 | * <-- HDR, SK {IDr, [CERT,] AUTH, | |||
301 | * SAr2, TSi, TSr} | |||
302 | * [Parent SA established] | |||
303 | */ | |||
304 | { .story = "Initiator: process INVALID_SYNTAX AUTH notification", | |||
305 | .state = STATE_PARENT_I2, .next_state = STATE_PARENT_I2, | |||
306 | .message_payloads = { .required = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), }, | |||
307 | .encrypted_payloads = { .required = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), .notification = v2N_INVALID_SYNTAX, }, | |||
308 | .processor = ikev2_auth_initiator_process_failure_notification, | |||
309 | .recv_role = MESSAGE_RESPONSE, | |||
310 | .recv_type = ISAKMP_v2_IKE_AUTH, }, | |||
311 | { .story = "Initiator: process AUTHENTICATION_FAILED AUTH notification", | |||
312 | .state = STATE_PARENT_I2, .next_state = STATE_PARENT_I2, | |||
313 | .message_payloads = { .required = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), }, | |||
314 | .encrypted_payloads = { .required = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), .notification = v2N_AUTHENTICATION_FAILED, }, | |||
315 | .processor = ikev2_auth_initiator_process_failure_notification, | |||
316 | .recv_role = MESSAGE_RESPONSE, | |||
317 | .recv_type = ISAKMP_v2_IKE_AUTH, }, | |||
318 | { .story = "Initiator: process UNSUPPORTED_CRITICAL_PAYLOAD AUTH notification", | |||
319 | .state = STATE_PARENT_I2, .next_state = STATE_PARENT_I2, | |||
320 | .message_payloads = { .required = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), }, | |||
321 | .encrypted_payloads = { .required = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), .notification = v2N_UNSUPPORTED_CRITICAL_PAYLOAD, }, | |||
322 | .processor = ikev2_auth_initiator_process_failure_notification, | |||
323 | .recv_role = MESSAGE_RESPONSE, | |||
324 | .recv_type = ISAKMP_v2_IKE_AUTH, }, | |||
325 | /* | |||
326 | * XXX: Danger! This state transition mashes the IKE SA's | |||
327 | * initial state and the CHILD SA's final state. There should | |||
328 | * instead be two separate state transitions: IKE SA: | |||
329 | * STATE_PARENT_I2 -> STATE_PARENT_I3; CHILD SA: ??? -> | |||
330 | * STATE_V2_ESTABLISHED_CHILD_SA -> ???. The IKE SA could | |||
331 | * then initiate the CHILD SA's transaction. | |||
332 | */ | |||
333 | { .story = "Initiator: process IKE_AUTH response", | |||
334 | .state = STATE_PARENT_I2, | |||
335 | .next_state = STATE_V2_ESTABLISHED_CHILD_SA, | |||
336 | .flags = SMF2_ESTABLISHED, | |||
337 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
338 | .req_enc_payloads = P(IDr)((lset_t)1 << (ISAKMP_NEXT_v2IDr)) | P(AUTH)((lset_t)1 << (ISAKMP_NEXT_v2AUTH)) | P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(TSi)((lset_t)1 << (ISAKMP_NEXT_v2TSi)) | P(TSr)((lset_t)1 << (ISAKMP_NEXT_v2TSr)), | |||
339 | .opt_enc_payloads = P(CERT)((lset_t)1 << (ISAKMP_NEXT_v2CERT))|P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
340 | .processor = ikev2_parent_inR2, | |||
341 | .recv_role = MESSAGE_RESPONSE, | |||
342 | .recv_type = ISAKMP_v2_IKE_AUTH, | |||
343 | .timeout_event = EVENT_SA_REPLACE, }, | |||
344 | { .story = "IKE SA: process IKE_AUTH response containing unknown notification", | |||
345 | .state = STATE_PARENT_I2, .next_state = STATE_PARENT_I2, | |||
346 | .message_payloads = { .required = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), }, | |||
347 | .encrypted_payloads = { .required = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), }, | |||
348 | .processor = ikev2_auth_initiator_process_unknown_notification, | |||
349 | .recv_role = MESSAGE_RESPONSE, | |||
350 | .recv_type = ISAKMP_v2_IKE_AUTH, }, | |||
351 | ||||
352 | /* no state: none I1 --> R1 | |||
353 | * <-- HDR, SAi1, KEi, Ni | |||
354 | * HDR, SAr1, KEr, Nr, [CERTREQ] --> | |||
355 | */ | |||
356 | { .story = "Respond to IKE_SA_INIT", | |||
357 | .state = STATE_PARENT_R0, | |||
358 | .next_state = STATE_PARENT_R1, | |||
359 | .send = MESSAGE_RESPONSE, | |||
360 | .req_clear_payloads = P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(KE)((lset_t)1 << (ISAKMP_NEXT_v2KE)) | P(Ni)((lset_t)1 << (ISAKMP_NEXT_v2Ni)), | |||
361 | .processor = ikev2_parent_inI1outR1, | |||
362 | .recv_role = MESSAGE_REQUEST, | |||
363 | .recv_type = ISAKMP_v2_IKE_SA_INIT, | |||
364 | .timeout_event = EVENT_SO_DISCARD, }, | |||
365 | ||||
366 | /* STATE_PARENT_R1: I2 --> R2 | |||
367 | * <-- HDR, SK {IDi, [CERT,] [CERTREQ,] | |||
368 | * [IDr,] AUTH, SAi2, | |||
369 | * TSi, TSr} | |||
370 | * HDR, SK {IDr, [CERT,] AUTH, | |||
371 | * SAr2, TSi, TSr} --> | |||
372 | * | |||
373 | * [Parent SA established] | |||
374 | */ | |||
375 | { .story = "Responder: process IKE_AUTH request (no SKEYSEED)", | |||
376 | .state = STATE_PARENT_R1, | |||
377 | .next_state = STATE_PARENT_R1, | |||
378 | .flags = SMF2_NO_SKEYSEED, | |||
379 | .send = MESSAGE_RESPONSE, | |||
380 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
381 | .req_enc_payloads = LEMPTY((lset_t)0), | |||
382 | .opt_enc_payloads = LEMPTY((lset_t)0), | |||
383 | .processor = ikev2_ike_sa_process_auth_request_no_skeyid, | |||
384 | .recv_role = MESSAGE_REQUEST, | |||
385 | .recv_type = ISAKMP_v2_IKE_AUTH, | |||
386 | .timeout_event = EVENT_SA_REPLACE, }, | |||
387 | /* | |||
388 | * XXX: Danger! This state transition mashes the IKE SA's | |||
389 | * initial state and the CHILD SA's final state. There should | |||
390 | * instead be two separate state transitions: IKE SA: | |||
391 | * STATE_PARENT_R1->STATE_PARENT_R2; CHILD SA:: ??? -> | |||
392 | * STATE_V2_ESTABLISHED_CHILD_SA. The IKE SA could then | |||
393 | * initiate the CHILD SA's transaction. | |||
394 | */ | |||
395 | { .story = "Responder: process IKE_AUTH request", | |||
396 | .state = STATE_PARENT_R1, | |||
397 | .next_state = STATE_V2_ESTABLISHED_CHILD_SA, | |||
398 | .flags = SMF2_ESTABLISHED, | |||
399 | .send = MESSAGE_RESPONSE, | |||
400 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
401 | .req_enc_payloads = P(IDi)((lset_t)1 << (ISAKMP_NEXT_v2IDi)) | P(AUTH)((lset_t)1 << (ISAKMP_NEXT_v2AUTH)) | P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(TSi)((lset_t)1 << (ISAKMP_NEXT_v2TSi)) | P(TSr)((lset_t)1 << (ISAKMP_NEXT_v2TSr)), | |||
402 | .opt_enc_payloads = P(CERT)((lset_t)1 << (ISAKMP_NEXT_v2CERT)) | P(CERTREQ)((lset_t)1 << (ISAKMP_NEXT_v2CERTREQ)) | P(IDr)((lset_t)1 << (ISAKMP_NEXT_v2IDr)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
403 | .processor = ikev2_ike_sa_process_auth_request, | |||
404 | .recv_role = MESSAGE_REQUEST, | |||
405 | .recv_type = ISAKMP_v2_IKE_AUTH, | |||
406 | .timeout_event = EVENT_SA_REPLACE, }, | |||
407 | ||||
408 | /* | |||
409 | * There are three different CREATE_CHILD_SA's invocations, | |||
410 | * this is the combined write up (not in RFC). See above for | |||
411 | * individual cases from RFC | |||
412 | * | |||
413 | * HDR, SK {SA, Ni, [KEi], [N(REKEY_SA)], [TSi, TSr]} --> | |||
414 | * <-- HDR, SK {N} | |||
415 | * <-- HDR, SK {SA, Nr, [KEr], [TSi, TSr]} | |||
416 | */ | |||
417 | ||||
418 | /* | |||
419 | * Create Child SA Exchange to rekey IKE SA | |||
420 | * no state: --> REKEY_IKE_R | |||
421 | * HDR, SAi1, KEi, Ni --> | |||
422 | * <-- HDR, SAr1, KEr, Nr | |||
423 | */ | |||
424 | { .story = "Respond to CREATE_CHILD_SA IKE Rekey", | |||
425 | .state = STATE_V2_REKEY_IKE_R0, | |||
426 | .next_state = STATE_V2_ESTABLISHED_IKE_SA, | |||
427 | .send = MESSAGE_RESPONSE, | |||
428 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
429 | .req_enc_payloads = P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(Ni)((lset_t)1 << (ISAKMP_NEXT_v2Ni)) | P(KE)((lset_t)1 << (ISAKMP_NEXT_v2KE)), | |||
430 | .opt_enc_payloads = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), | |||
431 | .processor = ikev2_child_ike_inIoutR, | |||
432 | .recv_role = MESSAGE_REQUEST, | |||
433 | .recv_type = ISAKMP_v2_CREATE_CHILD_SA, | |||
434 | .timeout_event = EVENT_SA_REPLACE }, | |||
435 | ||||
436 | { .story = "Process CREATE_CHILD_SA IKE Rekey Response", | |||
437 | .state = STATE_V2_REKEY_IKE_I1, | |||
438 | .next_state = STATE_V2_ESTABLISHED_IKE_SA, | |||
439 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
440 | .req_enc_payloads = P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(Ni)((lset_t)1 << (ISAKMP_NEXT_v2Ni)) | P(KE)((lset_t)1 << (ISAKMP_NEXT_v2KE)), | |||
441 | .opt_enc_payloads = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)), | |||
442 | .processor = ikev2_child_ike_inR, | |||
443 | .recv_role = MESSAGE_RESPONSE, | |||
444 | .recv_type = ISAKMP_v2_CREATE_CHILD_SA, | |||
445 | .timeout_event = EVENT_SA_REPLACE, }, | |||
446 | ||||
447 | /* | |||
448 | * request --> [N(REKEY_SA),] | |||
449 | * [CP(CFG_REQUEST),] | |||
450 | * [N(IPCOMP_SUPPORTED)+,] | |||
451 | * [N(USE_TRANSPORT_MODE),] | |||
452 | * [N(ESP_TFC_PADDING_NOT_SUPPORTED),] | |||
453 | * [N(NON_FIRST_FRAGMENTS_ALSO),] | |||
454 | * SA, Ni, [KEi,] TSi, TSr, | |||
455 | * [V+][N+] | |||
456 | */ | |||
457 | { .story = "Process CREATE_CHILD_SA IPsec SA Response", | |||
458 | .state = STATE_V2_NEW_CHILD_I1, | |||
459 | .next_state = STATE_V2_ESTABLISHED_CHILD_SA, | |||
460 | .flags = SMF2_ESTABLISHED, | |||
461 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
462 | .req_enc_payloads = P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(Ni)((lset_t)1 << (ISAKMP_NEXT_v2Ni)) | P(TSi)((lset_t)1 << (ISAKMP_NEXT_v2TSi)) | P(TSr)((lset_t)1 << (ISAKMP_NEXT_v2TSr)), | |||
463 | .opt_enc_payloads = P(KE)((lset_t)1 << (ISAKMP_NEXT_v2KE)) | P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
464 | .processor = ikev2_child_inR, | |||
465 | .recv_role = MESSAGE_RESPONSE, | |||
466 | .recv_type = ISAKMP_v2_CREATE_CHILD_SA, | |||
467 | .timeout_event = EVENT_SA_REPLACE, }, | |||
468 | ||||
469 | /* | |||
470 | * XXX: is there any benefit in having this state -- just | |||
471 | * merge this and next? | |||
472 | */ | |||
473 | ||||
474 | { .story = "Respond to CREATE_CHILD_SA rekey CHILD SA request", | |||
475 | .state = STATE_V2_REKEY_CHILD_R0, | |||
476 | .next_state = STATE_V2_ESTABLISHED_CHILD_SA, | |||
477 | .flags = SMF2_ESTABLISHED, | |||
478 | .send = MESSAGE_RESPONSE, | |||
479 | .message_payloads.required = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
480 | .encrypted_payloads.required = P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(Ni)((lset_t)1 << (ISAKMP_NEXT_v2Ni)) | P(TSi)((lset_t)1 << (ISAKMP_NEXT_v2TSi)) | P(TSr)((lset_t)1 << (ISAKMP_NEXT_v2TSr)), | |||
481 | .encrypted_payloads.optional = P(KE)((lset_t)1 << (ISAKMP_NEXT_v2KE)) | P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
482 | .encrypted_payloads.notification = v2N_REKEY_SA, | |||
483 | .processor = ikev2_child_inIoutR, | |||
484 | .recv_role = MESSAGE_REQUEST, | |||
485 | .recv_type = ISAKMP_v2_CREATE_CHILD_SA, | |||
486 | .timeout_event = EVENT_SA_REPLACE, }, | |||
487 | ||||
488 | { .story = "Respond to CREATE_CHILD_SA IPsec SA Request", | |||
489 | .state = STATE_V2_NEW_CHILD_R0, | |||
490 | .next_state = STATE_V2_ESTABLISHED_CHILD_SA, | |||
491 | .flags = SMF2_ESTABLISHED, | |||
492 | .send = MESSAGE_RESPONSE, | |||
493 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
494 | .req_enc_payloads = P(SA)((lset_t)1 << (ISAKMP_NEXT_v2SA)) | P(Ni)((lset_t)1 << (ISAKMP_NEXT_v2Ni)) | P(TSi)((lset_t)1 << (ISAKMP_NEXT_v2TSi)) | P(TSr)((lset_t)1 << (ISAKMP_NEXT_v2TSr)), | |||
495 | .opt_enc_payloads = P(KE)((lset_t)1 << (ISAKMP_NEXT_v2KE)) | P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
496 | .processor = ikev2_child_inIoutR, | |||
497 | .recv_role = MESSAGE_REQUEST, | |||
498 | .recv_type = ISAKMP_v2_CREATE_CHILD_SA, | |||
499 | .timeout_event = EVENT_SA_REPLACE, }, | |||
500 | ||||
501 | /* Informational Exchange */ | |||
502 | ||||
503 | /* RFC 5996 1.4 "The INFORMATIONAL Exchange" | |||
504 | * | |||
505 | * HDR, SK {[N,] [D,] [CP,] ...} --> | |||
506 | * <-- HDR, SK {[N,] [D,] [CP], ...} | |||
507 | * | |||
508 | * A liveness exchange is a special empty message. | |||
509 | * | |||
510 | * XXX: since these just generate an empty response, they | |||
511 | * might as well have a dedicated liveness function. | |||
512 | * | |||
513 | * XXX: rather than all this transition duplication, the | |||
514 | * established states should share common transition stored | |||
515 | * outside of this table. | |||
516 | */ | |||
517 | ||||
518 | { .story = "Informational Request (liveness probe)", | |||
519 | .state = STATE_V2_ESTABLISHED_IKE_SA, | |||
520 | .next_state = STATE_V2_ESTABLISHED_IKE_SA, | |||
521 | .flags = SMF2_SUPPRESS_SUCCESS_LOG, | |||
522 | .send = MESSAGE_RESPONSE, | |||
523 | .message_payloads.required = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
524 | .processor = process_encrypted_informational_ikev2, | |||
525 | .recv_role = MESSAGE_REQUEST, | |||
526 | .recv_type = ISAKMP_v2_INFORMATIONAL, | |||
527 | .timeout_event = EVENT_RETAIN, }, | |||
528 | ||||
529 | { .story = "Informational Response (liveness probe)", | |||
530 | .state = STATE_V2_ESTABLISHED_IKE_SA, | |||
531 | .next_state = STATE_V2_ESTABLISHED_IKE_SA, | |||
532 | .flags = SMF2_SUPPRESS_SUCCESS_LOG|SMF2_RELEASE_WHACK, | |||
533 | .message_payloads.required = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
534 | .processor = process_encrypted_informational_ikev2, | |||
535 | .recv_role = MESSAGE_RESPONSE, | |||
536 | .recv_type = ISAKMP_v2_INFORMATIONAL, | |||
537 | .timeout_event = EVENT_RETAIN, }, | |||
538 | ||||
539 | { .story = "Informational Request", | |||
540 | .state = STATE_V2_ESTABLISHED_IKE_SA, | |||
541 | .next_state = STATE_V2_ESTABLISHED_IKE_SA, | |||
542 | .send = MESSAGE_RESPONSE, | |||
543 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
544 | .opt_enc_payloads = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) | P(D)((lset_t)1 << (ISAKMP_NEXT_v2D)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
545 | .processor = process_encrypted_informational_ikev2, | |||
546 | .recv_role = MESSAGE_REQUEST, | |||
547 | .recv_type = ISAKMP_v2_INFORMATIONAL, | |||
548 | .timeout_event = EVENT_RETAIN, }, | |||
549 | ||||
550 | { .story = "Informational Response", | |||
551 | .state = STATE_V2_ESTABLISHED_IKE_SA, | |||
552 | .recv_type = ISAKMP_v2_INFORMATIONAL, | |||
553 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
554 | .opt_enc_payloads = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) | P(D)((lset_t)1 << (ISAKMP_NEXT_v2D)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
555 | .processor = process_encrypted_informational_ikev2, | |||
556 | .next_state = STATE_V2_ESTABLISHED_IKE_SA, | |||
557 | .recv_role = MESSAGE_RESPONSE, | |||
558 | .timeout_event = EVENT_RETAIN, }, | |||
559 | ||||
560 | { .story = "IKE_SA_DEL: process INFORMATIONAL", | |||
561 | .state = STATE_IKESA_DEL, | |||
562 | .next_state = STATE_IKESA_DEL, | |||
563 | .flags = 0, | |||
564 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
565 | .opt_enc_payloads = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) | P(D)((lset_t)1 << (ISAKMP_NEXT_v2D)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
566 | .processor = process_encrypted_informational_ikev2, | |||
567 | .recv_role = MESSAGE_RESPONSE, | |||
568 | .recv_type = ISAKMP_v2_INFORMATIONAL, | |||
569 | .timeout_event = EVENT_RETAIN, }, | |||
570 | ||||
571 | { .story = "IKE_SA_DEL: process INFORMATIONAL", | |||
572 | .state = STATE_CHILDSA_DEL, | |||
573 | .next_state = STATE_CHILDSA_DEL, | |||
574 | .flags = 0, | |||
575 | .req_clear_payloads = P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)), | |||
576 | .opt_enc_payloads = P(N)((lset_t)1 << (ISAKMP_NEXT_v2N)) | P(D)((lset_t)1 << (ISAKMP_NEXT_v2D)) | P(CP)((lset_t)1 << (ISAKMP_NEXT_v2CP)), | |||
577 | .processor = process_encrypted_informational_ikev2, | |||
578 | .recv_role = MESSAGE_RESPONSE, | |||
579 | .recv_type = ISAKMP_v2_INFORMATIONAL, | |||
580 | .timeout_event = EVENT_RETAIN, }, | |||
581 | ||||
582 | /* last entry */ | |||
583 | { .story = "roof", | |||
584 | .state = STATE_IKEv2_ROOF } | |||
585 | ||||
586 | #undef req_clear_payloads | |||
587 | #undef opt_clear_payloads | |||
588 | #undef req_enc_payloads | |||
589 | #undef opt_enc_payloads | |||
590 | ||||
591 | }; | |||
592 | ||||
593 | void init_ikev2(void) | |||
594 | { | |||
595 | dbg("checking IKEv2 state table"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("checking IKEv2 state table"); } }; | |||
596 | ||||
597 | /* | |||
598 | * Fill in FINITE_STATES[]. | |||
599 | * | |||
600 | * This is a hack until each finite-state is a separate object | |||
601 | * with corresponding edges (aka microcodes). | |||
602 | * | |||
603 | * XXX: Long term goal is to have a constant FINITE_STATES[] | |||
604 | * contain constant pointers and this static writeable array | |||
605 | * to just go away. | |||
606 | */ | |||
607 | for (enum state_kind kind = STATE_IKEv2_FLOOR; kind < STATE_IKEv2_ROOF; kind++) { | |||
608 | /* fill in using static struct */ | |||
609 | const struct finite_state *fs = &v2_states[kind - STATE_IKEv2_FLOOR]; | |||
610 | passert(fs->kind == kind){ _Bool assertion__ = fs->kind == kind; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 610}, "%s", "fs->kind == kind"); } }; | |||
611 | passert(finite_states[kind] == NULL){ _Bool assertion__ = finite_states[kind] == ((void*)0); if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 611}, "%s", "finite_states[kind] == NULL" ); } }; | |||
612 | finite_states[kind] = fs; | |||
613 | } | |||
614 | ||||
615 | /* | |||
616 | * Iterate over the state transitions filling in missing bits | |||
617 | * and checking for consistency. | |||
618 | */ | |||
619 | for (struct state_v2_microcode *t = v2_state_microcode_table; | |||
620 | t->state < STATE_IKEv2_ROOF; t++) { | |||
621 | ||||
622 | passert(t->state >= STATE_IKEv2_FLOOR){ _Bool assertion__ = t->state >= STATE_IKEv2_FLOOR; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 622}, "%s", "t->state >= STATE_IKEv2_FLOOR" ); } }; | |||
623 | passert(t->state < STATE_IKEv2_ROOF){ _Bool assertion__ = t->state < STATE_IKEv2_ROOF; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 623}, "%s", "t->state < STATE_IKEv2_ROOF" ); } }; | |||
624 | struct finite_state *from = &v2_states[t->state - STATE_IKEv2_FLOOR]; | |||
625 | ||||
626 | passert(t->next_state >= STATE_IKEv2_FLOOR){ _Bool assertion__ = t->next_state >= STATE_IKEv2_FLOOR ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 626}, "%s", "t->next_state >= STATE_IKEv2_FLOOR" ); } }; | |||
627 | passert(t->next_state < STATE_IKEv2_ROOF){ _Bool assertion__ = t->next_state < STATE_IKEv2_ROOF; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 627}, "%s", "t->next_state < STATE_IKEv2_ROOF" ); } }; | |||
628 | const struct finite_state *to = finite_states[t->next_state]; | |||
629 | passert(to != NULL){ _Bool assertion__ = to != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 629}, "%s", "to != NULL"); } }; | |||
630 | ||||
631 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
632 | if (from->nr_transitions == 0) { | |||
633 | LSWLOG_DEBUG(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 (; buf != ((void*) 0); jambuf_to_debug_stream(buf), buf = ((void*)0)) { | |||
634 | jam(buf, " "); | |||
635 | lswlog_finite_state(buf, from); | |||
636 | jam(buf, ":"); | |||
637 | } | |||
638 | } | |||
639 | const char *send; | |||
640 | switch (t->send) { | |||
641 | case NO_MESSAGE: send = ""; break; | |||
642 | case MESSAGE_REQUEST: send = " send-request"; break; | |||
643 | case MESSAGE_RESPONSE: send = " send-response"; break; | |||
644 | default: bad_case(t->send)libreswan_bad_case("t->send", (t->send), (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 644}); | |||
645 | } | |||
646 | DBG_log(" -> %s %s%s (%s)", to->short_name, | |||
647 | enum_short_name(&timer_event_names, | |||
648 | t->timeout_event), | |||
649 | send, t->story); | |||
650 | } | |||
651 | ||||
652 | /* | |||
653 | * Check that the NOTIFY -> PBS -> MD.pbs[]!=NULL will work. | |||
654 | */ | |||
655 | if (t->message_payloads.notification != v2N_NOTHING_WRONG) { | |||
656 | pexpect(v2_notification_to_v2_pbs(t->message_payloads.notification) != PBS_v2_INVALID)({ _Bool assertion__ = v2_notification_to_v2_pbs(t->message_payloads .notification) != PBS_v2_INVALID; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 656}, "%s", "v2_notification_to_v2_pbs(t->message_payloads.notification) != PBS_v2_INVALID" ); } assertion__; }); | |||
657 | } | |||
658 | if (t->encrypted_payloads.notification != v2N_NOTHING_WRONG) { | |||
659 | pexpect(v2_notification_to_v2_pbs(t->encrypted_payloads.notification) != PBS_v2_INVALID)({ _Bool assertion__ = v2_notification_to_v2_pbs(t->encrypted_payloads .notification) != PBS_v2_INVALID; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 659}, "%s", "v2_notification_to_v2_pbs(t->encrypted_payloads.notification) != PBS_v2_INVALID" ); } assertion__; }); | |||
660 | } | |||
661 | ||||
662 | /* | |||
663 | * Check recv:MESSAGE_REQUEST->send:MESSAGE_RESPONSE. | |||
664 | */ | |||
665 | pexpect(t->recv_role == MESSAGE_REQUEST ? t->send = MESSAGE_RESPONSE : true)({ _Bool assertion__ = t->recv_role == MESSAGE_REQUEST ? t ->send = MESSAGE_RESPONSE : 1; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 665}, "%s", "t->recv_role == MESSAGE_REQUEST ? t->send = MESSAGE_RESPONSE : true" ); } assertion__; }); | |||
666 | ||||
667 | /* | |||
668 | * Check recv_type && recv_role | |||
669 | */ | |||
670 | pexpect(t->recv_role == NO_MESSAGE ? t->recv_type == 0 : t->recv_type != 0)({ _Bool assertion__ = t->recv_role == NO_MESSAGE ? t-> recv_type == 0 : t->recv_type != 0; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 670}, "%s", "t->recv_role == NO_MESSAGE ? t->recv_type == 0 : t->recv_type != 0" ); } assertion__; }); | |||
671 | ||||
672 | /* | |||
673 | * Point .fs_v2_microcode at the first transition for | |||
674 | * the from state. All other transitions for the from | |||
675 | * state should follow immediately after (or to put it | |||
676 | * another way, previous should match). | |||
677 | */ | |||
678 | if (from->v2_transitions == NULL((void*)0)) { | |||
679 | /* start of the next state */ | |||
680 | passert(from->nr_transitions == 0){ _Bool assertion__ = from->nr_transitions == 0; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 680}, "%s", "from->nr_transitions == 0" ); } }; | |||
681 | from->v2_transitions = t; | |||
682 | } else { | |||
683 | passert(t[-1].state == t->state){ _Bool assertion__ = t[-1].state == t->state; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 683}, "%s", "t[-1].state == t->state" ); } }; | |||
684 | } | |||
685 | from->nr_transitions++; | |||
686 | } | |||
687 | } | |||
688 | ||||
689 | /* | |||
690 | * split an incoming message into payloads | |||
691 | */ | |||
692 | static struct payload_summary ikev2_decode_payloads(struct logger *log, | |||
693 | struct msg_digest *md, | |||
694 | pb_stream *in_pbs, | |||
695 | enum next_payload_types_ikev2 np) | |||
696 | { | |||
697 | struct payload_summary summary = { | |||
698 | .parsed = true1, | |||
699 | .n = v2N_NOTHING_WRONG, | |||
700 | }; | |||
701 | ||||
702 | /* | |||
703 | * ??? zero out the digest descriptors -- might nuke | |||
704 | * ISAKMP_NEXT_v2SK digest! | |||
705 | * | |||
706 | * XXX: and v2SKF? Safer to leave them as is and just use new | |||
707 | * ones - always add to MD, never take away. | |||
708 | */ | |||
709 | ||||
710 | /* | |||
711 | * XXX: Currently, when a message containing an SK payload is | |||
712 | * decoded, the encrypted payloads get appended to the | |||
713 | * previously decoded non-encrypted payloads. For instance, | |||
714 | * given a message containing two notifications: | |||
715 | * | |||
716 | * N(1), SK{ N(2) } | |||
717 | * | |||
718 | * The notification digest would contain both the unencrypted | |||
719 | * N(1) and encrypted N(2). Since the unencrypted value is | |||
720 | * protected, while not very good, isn't really dangerous. | |||
721 | */ | |||
722 | ||||
723 | while (np != ISAKMP_NEXT_v2NONE) { | |||
724 | dbg("Now let's proceed with payload (%s)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Now let's proceed with payload (%s)", enum_show (&ikev2_payload_names, np)); } } | |||
725 | enum_show(&ikev2_payload_names, np)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Now let's proceed with payload (%s)", enum_show (&ikev2_payload_names, np)); } }; | |||
726 | ||||
727 | if (md->digest_roof >= elemsof(md->digest)(sizeof(md->digest) / sizeof(*(md->digest)))) { | |||
728 | log_message(RC_LOG_SERIOUS, log, | |||
729 | "more than %zu payloads in message; ignored", | |||
730 | elemsof(md->digest)(sizeof(md->digest) / sizeof(*(md->digest)))); | |||
731 | summary.n = v2N_INVALID_SYNTAX; | |||
732 | break; | |||
733 | } | |||
734 | ||||
735 | /* | |||
736 | * *pd is the payload digest for this payload. | |||
737 | * It has three fields: | |||
738 | * pbs is filled in by in_struct | |||
739 | * payload is filled in by in_struct | |||
740 | * next is filled in by list linking logic | |||
741 | */ | |||
742 | struct payload_digest *const pd = md->digest + md->digest_roof; | |||
743 | ||||
744 | /* | |||
745 | * map the payload onto its payload descriptor which | |||
746 | * describes how to decode it | |||
747 | */ | |||
748 | const struct_desc *sd = v2_payload_desc(np); | |||
749 | ||||
750 | if (sd == NULL((void*)0)) { | |||
751 | /* | |||
752 | * This payload is unknown to us. RFCs 4306 | |||
753 | * and 5996 2.5 say that if the payload has | |||
754 | * the Critical Bit, we should be upset but if | |||
755 | * it does not, we should just ignore it. | |||
756 | */ | |||
757 | if (!in_struct(&pd->payload, &ikev2_generic_desc, in_pbs, &pd->pbs)) { | |||
758 | log_message(RC_LOG_SERIOUS, log, | |||
759 | "malformed payload in packet"); | |||
760 | summary.n = v2N_INVALID_SYNTAX; | |||
761 | break; | |||
762 | } | |||
763 | if (pd->payload.v2gen.isag_critical & ISAKMP_PAYLOAD_CRITICAL0x80) { | |||
764 | /* | |||
765 | * It was critical. See RFC 5996 1.5 | |||
766 | * "Version Numbers and Forward | |||
767 | * Compatibility" | |||
768 | */ | |||
769 | const char *role; | |||
770 | switch (v2_msg_role(md)) { | |||
771 | case MESSAGE_REQUEST: | |||
772 | role = "request"; | |||
773 | break; | |||
774 | case MESSAGE_RESPONSE: | |||
775 | role = "response"; | |||
776 | break; | |||
777 | default: | |||
778 | bad_case(v2_msg_role(md))libreswan_bad_case("v2_msg_role(md)", (v2_msg_role(md)), (where_t ) { .func = __func__, .basename = "ikev2.c" , .line = 778}); | |||
779 | } | |||
780 | log_message(RC_LOG_SERIOUS, log, | |||
781 | "message %s contained an unknown critical payload type (%s)", | |||
782 | role, enum_show(&ikev2_payload_names, np)); | |||
783 | summary.n = v2N_UNSUPPORTED_CRITICAL_PAYLOAD; | |||
784 | summary.data[0] = np; | |||
785 | summary.data_size = 1; | |||
786 | break; | |||
787 | } | |||
788 | struct esb_buf eb; | |||
789 | log_message(RC_COMMENT, log, | |||
790 | "non-critical payload ignored because it contains an unknown or unexpected payload type (%s) at the outermost level", | |||
791 | enum_showb(&ikev2_payload_names, np, &eb)); | |||
792 | np = pd->payload.generic.isag_np; | |||
793 | continue; | |||
794 | } | |||
795 | ||||
796 | if (np >= LELEM_ROOF64) { | |||
797 | dbg("huge next-payload %u", np){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("huge next-payload %u", np); } }; | |||
798 | summary.n = v2N_INVALID_SYNTAX; | |||
799 | break; | |||
800 | } | |||
801 | summary.repeated |= (summary.present & LELEM(np)((lset_t)1 << (np))); | |||
802 | summary.present |= LELEM(np)((lset_t)1 << (np)); | |||
803 | ||||
804 | /* | |||
805 | * Read in the payload recording what type it should | |||
806 | * be. | |||
807 | */ | |||
808 | pd->payload_type = np; | |||
809 | if (!in_struct(&pd->payload, sd, in_pbs, &pd->pbs)) { | |||
810 | log_message(RC_LOG_SERIOUS, log, | |||
811 | "malformed payload in packet"); | |||
812 | summary.n = v2N_INVALID_SYNTAX; | |||
813 | break; | |||
814 | } | |||
815 | ||||
816 | dbg("processing payload: %s (len=%zu)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processing payload: %s (len=%zu)", enum_show( &ikev2_payload_names, np), ((size_t)((&pd->pbs)-> roof - (&pd->pbs)->cur))); } } | |||
817 | enum_show(&ikev2_payload_names, np),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processing payload: %s (len=%zu)", enum_show( &ikev2_payload_names, np), ((size_t)((&pd->pbs)-> roof - (&pd->pbs)->cur))); } } | |||
818 | pbs_left(&pd->pbs)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processing payload: %s (len=%zu)", enum_show( &ikev2_payload_names, np), ((size_t)((&pd->pbs)-> roof - (&pd->pbs)->cur))); } }; | |||
819 | ||||
820 | /* | |||
821 | * Place payload at the end of the chain for this | |||
822 | * type. | |||
823 | */ | |||
824 | if (md->last[np] == NULL((void*)0)) { | |||
825 | /* first */ | |||
826 | md->chain[np] = md->last[np] = pd; | |||
827 | pd->next = NULL((void*)0); | |||
828 | } else { | |||
829 | /* append */ | |||
830 | md->last[np]->next = pd; | |||
831 | md->last[np] = pd; | |||
832 | pd->next = NULL((void*)0); | |||
833 | } | |||
834 | ||||
835 | /* | |||
836 | * Go deeper: | |||
837 | * | |||
838 | * XXX: should this do 'deeper' analysis of packets. | |||
839 | * For instance checking the SPI of a notification | |||
840 | * payload? Probably not as the value may be ignored. | |||
841 | * | |||
842 | * The exception is seems to be v2N - both cookie and | |||
843 | * redirect code happen early and use the values. | |||
844 | */ | |||
845 | ||||
846 | switch (np) { | |||
847 | case ISAKMP_NEXT_v2N: | |||
848 | decode_v2N_payload(log, md, pd); | |||
849 | break; | |||
850 | default: | |||
851 | break; | |||
852 | } | |||
853 | ||||
854 | /* | |||
855 | * Determine the next payload. | |||
856 | * | |||
857 | * SK and SKF are special - their next-payload field | |||
858 | * is for the first embedded payload - so force it to | |||
859 | * NONE: | |||
860 | * | |||
861 | * RFC 5996 2.14 "Encrypted Payload": | |||
862 | * | |||
863 | * Next Payload - The payload type of the first | |||
864 | * embedded payload. Note that this is an exception | |||
865 | * in the standard header format, since the Encrypted | |||
866 | * payload is the last payload in the message and | |||
867 | * therefore the Next Payload field would normally be | |||
868 | * zero. But because the content of this payload is | |||
869 | * embedded payloads and there was no natural place to | |||
870 | * put the type of the first one, that type is placed | |||
871 | * here. | |||
872 | */ | |||
873 | switch (np) { | |||
874 | case ISAKMP_NEXT_v2SK: | |||
875 | case ISAKMP_NEXT_v2SKF: | |||
876 | /* special */ | |||
877 | np = ISAKMP_NEXT_v2NONE; | |||
878 | break; | |||
879 | default: | |||
880 | np = pd->payload.generic.isag_np; | |||
881 | break; | |||
882 | } | |||
883 | ||||
884 | md->digest_roof++; | |||
885 | } | |||
886 | ||||
887 | return summary; | |||
888 | } | |||
889 | ||||
890 | static bool_Bool ikev2_check_fragment(struct msg_digest *md, struct state *st) | |||
891 | { | |||
892 | struct v2_incomming_fragments **frags = &st->st_v2_incomming[v2_msg_role(md)]; | |||
893 | struct ikev2_skf *skf = &md->chain[ISAKMP_NEXT_v2SKF]->payload.v2skf; | |||
894 | ||||
895 | /* ??? CLANG 3.5 thinks st might be NULL */ | |||
896 | if (!(st->st_connection->policy & POLICY_IKE_FRAG_ALLOW((lset_t)1 << (POLICY_IKE_FRAG_ALLOW_IX)))) { | |||
897 | dbg("discarding IKE encrypted fragment - fragmentation not allowed by local policy (ike_frag=no)"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("discarding IKE encrypted fragment - fragmentation not allowed by local policy (ike_frag=no)" ); } }; | |||
898 | return FALSE0; | |||
899 | } | |||
900 | ||||
901 | if (!(st->st_seen_fragmentation_supported)) { | |||
902 | dbg("discarding IKE encrypted fragment - remote never proposed fragmentation"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("discarding IKE encrypted fragment - remote never proposed fragmentation" ); } }; | |||
903 | return FALSE0; | |||
904 | } | |||
905 | ||||
906 | dbg("received IKE encrypted fragment number '%u', total number '%u', next payload '%u'",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received IKE encrypted fragment number '%u', total number '%u', next payload '%u'" , skf->isaskf_number, skf->isaskf_total, skf->isaskf_np ); } } | |||
907 | skf->isaskf_number, skf->isaskf_total, skf->isaskf_np){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received IKE encrypted fragment number '%u', total number '%u', next payload '%u'" , skf->isaskf_number, skf->isaskf_total, skf->isaskf_np ); } }; | |||
908 | ||||
909 | /* | |||
910 | * Sanity check: | |||
911 | * fragment number must be 1 or greater (not 0) | |||
912 | * fragment number must be no greater than the total number of fragments | |||
913 | * total number of fragments must be no more than MAX_IKE_FRAGMENTS | |||
914 | * first fragment's next payload must not be ISAKMP_NEXT_v2NONE. | |||
915 | * later fragments' next payload must be ISAKMP_NEXT_v2NONE. | |||
916 | */ | |||
917 | if (!(skf->isaskf_number != 0 && | |||
918 | skf->isaskf_number <= skf->isaskf_total && | |||
919 | skf->isaskf_total <= MAX_IKE_FRAGMENTS32 && | |||
920 | (skf->isaskf_number == 1) != (skf->isaskf_np == ISAKMP_NEXT_v2NONE))) | |||
921 | { | |||
922 | dbg("ignoring invalid IKE encrypted fragment"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring invalid IKE encrypted fragment"); } }; | |||
923 | return FALSE0; | |||
924 | } | |||
925 | ||||
926 | if (*frags == NULL((void*)0)) { | |||
927 | /* first fragment, so must be good */ | |||
928 | return TRUE1; | |||
929 | } | |||
930 | ||||
931 | if (skf->isaskf_total != (*frags)->total) { | |||
932 | /* | |||
933 | * total number of fragments changed. | |||
934 | * Either this fragment is wrong or all the | |||
935 | * stored fragments are wrong or superseded. | |||
936 | * The only reason the other end would have | |||
937 | * started over with a different number of fragments | |||
938 | * is because it decided to ratchet down the packet size | |||
939 | * (and thus increase total). | |||
940 | * OK: skf->isaskf_total > i->total | |||
941 | * Bad: skf->isaskf_total < i->total | |||
942 | */ | |||
943 | if (skf->isaskf_total > (*frags)->total) { | |||
944 | dbg("discarding saved fragments because this fragment has larger total"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("discarding saved fragments because this fragment has larger total" ); } }; | |||
945 | free_v2_incomming_fragments(frags); | |||
946 | return TRUE1; | |||
947 | } else { | |||
948 | dbg("ignoring odd IKE encrypted fragment (total shrank)"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring odd IKE encrypted fragment (total shrank)" ); } }; | |||
949 | return FALSE0; | |||
950 | } | |||
951 | } else if ((*frags)->frags[skf->isaskf_number].cipher.ptr != NULL((void*)0)) { | |||
952 | /* retain earlier fragment with same index */ | |||
953 | dbg("ignoring repeated IKE encrypted fragment"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring repeated IKE encrypted fragment"); } }; | |||
954 | return FALSE0; | |||
955 | } else { | |||
956 | return TRUE1; | |||
957 | } | |||
958 | } | |||
959 | ||||
960 | static bool_Bool ikev2_collect_fragment(struct msg_digest *md, struct state *st) | |||
961 | { | |||
962 | struct v2_incomming_fragments **frags = &st->st_v2_incomming[v2_msg_role(md)]; | |||
963 | struct ikev2_skf *skf = &md->chain[ISAKMP_NEXT_v2SKF]->payload.v2skf; | |||
964 | pb_stream *e_pbs = &md->chain[ISAKMP_NEXT_v2SKF]->pbs; | |||
965 | ||||
966 | if (!st->st_seen_fragmentation_supported) { | |||
967 | dbg(" fragments claiming to be from peer while peer did not signal fragmentation support - dropped"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log(" fragments claiming to be from peer while peer did not signal fragmentation support - dropped" ); } }; | |||
968 | return FALSE0; | |||
969 | } | |||
970 | ||||
971 | if (!ikev2_check_fragment(md, st)) { | |||
972 | return FALSE0; | |||
973 | } | |||
974 | ||||
975 | /* if receiving fragments, respond with fragments too */ | |||
976 | if (!st->st_seen_fragments) { | |||
977 | st->st_seen_fragments = TRUE1; | |||
978 | dbg(" updated IKE fragment state to respond using fragments without waiting for re-transmits"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log(" updated IKE fragment state to respond using fragments without waiting for re-transmits" ); } }; | |||
979 | } | |||
980 | ||||
981 | /* | |||
982 | * Since the fragment check above can result in all fragments | |||
983 | * so-far being discarded; always check/fix frags. | |||
984 | */ | |||
985 | if ((*frags) == NULL((void*)0)) { | |||
986 | *frags = alloc_thing(struct v2_incomming_fragments, "incoming v2_ike_rfrags")((struct v2_incomming_fragments*) alloc_bytes(sizeof(struct v2_incomming_fragments ), ("incoming v2_ike_rfrags"))); | |||
987 | (*frags)->total = skf->isaskf_total; | |||
988 | } | |||
989 | ||||
990 | passert(skf->isaskf_number < elemsof((*frags)->frags)){ _Bool assertion__ = skf->isaskf_number < (sizeof((*frags )->frags) / sizeof(*((*frags)->frags))); if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 990}, "%s", "skf->isaskf_number < elemsof((*frags)->frags)" ); } }; | |||
991 | struct v2_incomming_fragment *frag = &(*frags)->frags[skf->isaskf_number]; | |||
992 | passert(frag->cipher.ptr == NULL){ _Bool assertion__ = frag->cipher.ptr == ((void*)0); if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 992}, "%s", "frag->cipher.ptr == NULL" ); } }; | |||
993 | frag->iv = e_pbs->cur - md->packet_pbs.start; | |||
994 | frag->cipher = clone_bytes_as_chunk(md->packet_pbs.start, | |||
995 | e_pbs->roof - md->packet_pbs.start, | |||
996 | "incoming IKEv2 encrypted fragment"); | |||
997 | ||||
998 | if (skf->isaskf_number == 1) { | |||
999 | (*frags)->first_np = skf->isaskf_np; | |||
1000 | } | |||
1001 | ||||
1002 | passert((*frags)->count < (*frags)->total){ _Bool assertion__ = (*frags)->count < (*frags)->total ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 1002}, "%s", "(*frags)->count < (*frags)->total" ); } }; | |||
1003 | (*frags)->count++; | |||
1004 | return (*frags)->count == (*frags)->total; | |||
1005 | } | |||
1006 | ||||
1007 | static struct child_sa *process_v2_child_ix(struct ike_sa *ike, | |||
1008 | const struct state_v2_microcode *svm) | |||
1009 | { | |||
1010 | /* | |||
1011 | * XXX: Still a mess. Should call processor with the IKE SA. | |||
1012 | * The processor can then create a nested state. | |||
1013 | */ | |||
1014 | enum sa_type sa_type = (svm->state == STATE_V2_NEW_CHILD_R0 ? IPSEC_SA : | |||
1015 | svm->state == STATE_V2_REKEY_CHILD_R0 ? IPSEC_SA : | |||
1016 | pexpect(svm->state == STATE_V2_REKEY_IKE_R0)({ _Bool assertion__ = svm->state == STATE_V2_REKEY_IKE_R0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 1016}, "%s", "svm->state == STATE_V2_REKEY_IKE_R0" ); } assertion__; }) ? IKE_SA : | |||
1017 | IKE_SA); | |||
1018 | struct child_sa *child = new_v2_child_state(ike, sa_type, | |||
1019 | SA_RESPONDER, | |||
1020 | svm->state, | |||
1021 | null_fd((struct fd *) ((void*)0))); | |||
1022 | binlog_refresh_state(&child->sa)binlog_state((&child->sa), (&child->sa)->st_state ->kind); | |||
1023 | ||||
1024 | connection_buf ibuf; | |||
1025 | connection_buf cbuf; | |||
1026 | dbg(PRI_CONNECTION" #%lu received %s CREATE_CHILD_SA Child "PRI_CONNECTION" #%lu in %s will process it further",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("\"%s\"%s"" #%lu received %s CREATE_CHILD_SA Child " "\"%s\"%s"" #%lu in %s will process it further", (ike->sa. st_connection)->name, str_connection_instance(ike->sa.st_connection , &ibuf), ike->sa.st_serialno, svm->story, (child-> sa.st_connection)->name, str_connection_instance(child-> sa.st_connection, &cbuf), child->sa.st_serialno, child ->sa.st_state->name); } } | |||
1027 | pri_connection(ike->sa.st_connection, &ibuf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("\"%s\"%s"" #%lu received %s CREATE_CHILD_SA Child " "\"%s\"%s"" #%lu in %s will process it further", (ike->sa. st_connection)->name, str_connection_instance(ike->sa.st_connection , &ibuf), ike->sa.st_serialno, svm->story, (child-> sa.st_connection)->name, str_connection_instance(child-> sa.st_connection, &cbuf), child->sa.st_serialno, child ->sa.st_state->name); } } | |||
1028 | ike->sa.st_serialno, svm->story,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("\"%s\"%s"" #%lu received %s CREATE_CHILD_SA Child " "\"%s\"%s"" #%lu in %s will process it further", (ike->sa. st_connection)->name, str_connection_instance(ike->sa.st_connection , &ibuf), ike->sa.st_serialno, svm->story, (child-> sa.st_connection)->name, str_connection_instance(child-> sa.st_connection, &cbuf), child->sa.st_serialno, child ->sa.st_state->name); } } | |||
1029 | pri_connection(child->sa.st_connection, &cbuf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("\"%s\"%s"" #%lu received %s CREATE_CHILD_SA Child " "\"%s\"%s"" #%lu in %s will process it further", (ike->sa. st_connection)->name, str_connection_instance(ike->sa.st_connection , &ibuf), ike->sa.st_serialno, svm->story, (child-> sa.st_connection)->name, str_connection_instance(child-> sa.st_connection, &cbuf), child->sa.st_serialno, child ->sa.st_state->name); } } | |||
1030 | child->sa.st_serialno, child->sa.st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("\"%s\"%s"" #%lu received %s CREATE_CHILD_SA Child " "\"%s\"%s"" #%lu in %s will process it further", (ike->sa. st_connection)->name, str_connection_instance(ike->sa.st_connection , &ibuf), ike->sa.st_serialno, svm->story, (child-> sa.st_connection)->name, str_connection_instance(child-> sa.st_connection, &cbuf), child->sa.st_serialno, child ->sa.st_state->name); } }; | |||
1031 | ||||
1032 | return child; | |||
1033 | } | |||
1034 | ||||
1035 | /* | |||
1036 | * Find the SA (IKE or CHILD), within IKE's family, that is initiated | |||
1037 | * or is responding to Message ID. | |||
1038 | * | |||
1039 | * XXX: There's overlap between this and the is_duplicate_*() code. | |||
1040 | * For instance, there's little point in looking for a state when the | |||
1041 | * IKE SA's window shows it too old (at least if we ignore | |||
1042 | * record'n'send bugs). | |||
1043 | */ | |||
1044 | ||||
1045 | struct wip_filter { | |||
1046 | msgid_t msgid; | |||
1047 | }; | |||
1048 | ||||
1049 | static bool_Bool v2_sa_by_initiator_wip_p(struct state *st, void *context) | |||
1050 | { | |||
1051 | const struct wip_filter *filter = context; | |||
1052 | return st->st_v2_msgid_wip.initiator == filter->msgid; | |||
1053 | } | |||
1054 | ||||
1055 | static struct state *find_v2_sa_by_initiator_wip(struct ike_sa *ike, const msgid_t msgid) | |||
1056 | { | |||
1057 | /* | |||
1058 | * XXX: Would a linked list of CHILD SAs work better, would | |||
1059 | * mean reference counting? Should this also check that MSGID | |||
1060 | * is within the IKE SA's window? | |||
1061 | */ | |||
1062 | struct wip_filter filter = { | |||
1063 | .msgid = msgid, | |||
1064 | }; | |||
1065 | struct state *st; | |||
1066 | if (v2_sa_by_initiator_wip_p(&ike->sa, &filter)) { | |||
1067 | st = &ike->sa; | |||
1068 | } else { | |||
1069 | st = state_by_ike_spis(IKEv2, | |||
1070 | NULL((void*)0)/*ignore clonedfrom*/, | |||
1071 | NULL((void*)0)/*ignore v1 msgid*/, | |||
1072 | NULL((void*)0)/*ignore role*/, | |||
1073 | &ike->sa.st_ike_spis, | |||
1074 | v2_sa_by_initiator_wip_p, &filter, __func__); | |||
1075 | } | |||
1076 | pexpect(st == NULL ||({ _Bool assertion__ = st == ((void*)0) || st->st_clonedfrom == 0 || st->st_clonedfrom == ike->sa.st_serialno; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1078}, "%s", "st == NULL || st->st_clonedfrom == SOS_NOBODY || st->st_clonedfrom == ike->sa.st_serialno" ); } assertion__; }) | |||
1077 | st->st_clonedfrom == SOS_NOBODY ||({ _Bool assertion__ = st == ((void*)0) || st->st_clonedfrom == 0 || st->st_clonedfrom == ike->sa.st_serialno; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1078}, "%s", "st == NULL || st->st_clonedfrom == SOS_NOBODY || st->st_clonedfrom == ike->sa.st_serialno" ); } assertion__; }) | |||
1078 | st->st_clonedfrom == ike->sa.st_serialno)({ _Bool assertion__ = st == ((void*)0) || st->st_clonedfrom == 0 || st->st_clonedfrom == ike->sa.st_serialno; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1078}, "%s", "st == NULL || st->st_clonedfrom == SOS_NOBODY || st->st_clonedfrom == ike->sa.st_serialno" ); } assertion__; }); | |||
1079 | return st; | |||
1080 | } | |||
1081 | ||||
1082 | static bool_Bool v2_sa_by_responder_wip_p(struct state *st, void *context) | |||
1083 | { | |||
1084 | const struct wip_filter *filter = context; | |||
1085 | return st->st_v2_msgid_wip.responder == filter->msgid; | |||
1086 | } | |||
1087 | ||||
1088 | static struct state *find_v2_sa_by_responder_wip(struct ike_sa *ike, const msgid_t msgid) | |||
1089 | { | |||
1090 | /* | |||
1091 | * XXX: Would a linked list of CHILD SAs work better, would | |||
1092 | * mean reference counting? Should this also check that MSGID | |||
1093 | * is within the IKE SA's window? | |||
1094 | */ | |||
1095 | struct wip_filter filter = { | |||
1096 | .msgid = msgid, | |||
1097 | }; | |||
1098 | struct state *st; | |||
1099 | if (v2_sa_by_responder_wip_p(&ike->sa, &filter)) { | |||
1100 | st = &ike->sa; | |||
1101 | } else { | |||
1102 | st = state_by_ike_spis(IKEv2, | |||
1103 | NULL((void*)0)/*ignore clonedfrom*/, | |||
1104 | NULL((void*)0)/*ignore v1 msgid*/, | |||
1105 | NULL((void*)0)/*ignore role*/, | |||
1106 | &ike->sa.st_ike_spis, | |||
1107 | v2_sa_by_responder_wip_p, &filter, __func__); | |||
1108 | } | |||
1109 | pexpect(st == NULL ||({ _Bool assertion__ = st == ((void*)0) || st->st_clonedfrom == 0 || st->st_clonedfrom == ike->sa.st_serialno; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1111}, "%s", "st == NULL || st->st_clonedfrom == SOS_NOBODY || st->st_clonedfrom == ike->sa.st_serialno" ); } assertion__; }) | |||
1110 | st->st_clonedfrom == SOS_NOBODY ||({ _Bool assertion__ = st == ((void*)0) || st->st_clonedfrom == 0 || st->st_clonedfrom == ike->sa.st_serialno; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1111}, "%s", "st == NULL || st->st_clonedfrom == SOS_NOBODY || st->st_clonedfrom == ike->sa.st_serialno" ); } assertion__; }) | |||
1111 | st->st_clonedfrom == ike->sa.st_serialno)({ _Bool assertion__ = st == ((void*)0) || st->st_clonedfrom == 0 || st->st_clonedfrom == ike->sa.st_serialno; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1111}, "%s", "st == NULL || st->st_clonedfrom == SOS_NOBODY || st->st_clonedfrom == ike->sa.st_serialno" ); } assertion__; }); | |||
1112 | return st; | |||
1113 | } | |||
1114 | ||||
1115 | /* | |||
1116 | * Is this a duplicate message? | |||
1117 | * | |||
1118 | * XXX: | |||
1119 | * | |||
1120 | * record'n'send bypassing the send queue can result in pluto having | |||
1121 | * more outstanding messages then the negotiated window size. | |||
1122 | * | |||
1123 | * This and the find_v2_sa_by_*_wip() have some overlap. For | |||
1124 | * instance, little point in searching for a state when the IKE SA's | |||
1125 | * window shows the Message ID is too old (only record'n'send breakage | |||
1126 | * means it might still have a message, argh!). | |||
1127 | * | |||
1128 | * This code should use an explicit log function. libreswan_log() is | |||
1129 | * at the mercy of the caller so the messages might be logged against | |||
1130 | * ST and might be logged against IKE. This is one thing that | |||
1131 | * prevents find_v2_sa_by_*_wip() and this code being better | |||
1132 | * organized. | |||
1133 | */ | |||
1134 | ||||
1135 | /* | |||
1136 | * A duplicate request could be: | |||
1137 | * | |||
1138 | * - the request still being processed (for instance waiting on | |||
1139 | * crypto), which can be tossed | |||
1140 | * | |||
1141 | * - the request last processed, which should trigger a retransmit of | |||
1142 | * the response | |||
1143 | * | |||
1144 | * - an older request which can be tossed | |||
1145 | * | |||
1146 | * But if it is a fragment, much of this is skipped. | |||
1147 | */ | |||
1148 | static bool_Bool is_duplicate_request(struct ike_sa *ike, | |||
1149 | struct msg_digest *md) | |||
1150 | { | |||
1151 | passert(v2_msg_role(md) == MESSAGE_REQUEST){ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 1151}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } }; | |||
1152 | intmax_t msgid = md->hdr.isa_msgid; | |||
1153 | ||||
1154 | /* lie to keep test results happy */ | |||
1155 | dbg("#%lu st.st_msgid_lastrecv %jd md.hdr.isa_msgid %08jx",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu st.st_msgid_lastrecv %jd md.hdr.isa_msgid %08jx" , ike->sa.st_serialno, ike->sa.st_v2_msgid_windows.responder .recv, msgid); } } | |||
1156 | ike->sa.st_serialno, ike->sa.st_v2_msgid_windows.responder.recv, msgid){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu st.st_msgid_lastrecv %jd md.hdr.isa_msgid %08jx" , ike->sa.st_serialno, ike->sa.st_v2_msgid_windows.responder .recv, msgid); } }; | |||
1157 | ||||
1158 | /* the sliding window is really small?!? */ | |||
1159 | pexpect(ike->sa.st_v2_msgid_windows.responder.recv ==({ _Bool assertion__ = ike->sa.st_v2_msgid_windows.responder .recv == ike->sa.st_v2_msgid_windows.responder.sent; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1160}, "%s", "ike->sa.st_v2_msgid_windows.responder.recv == ike->sa.st_v2_msgid_windows.responder.sent" ); } assertion__; }) | |||
1160 | ike->sa.st_v2_msgid_windows.responder.sent)({ _Bool assertion__ = ike->sa.st_v2_msgid_windows.responder .recv == ike->sa.st_v2_msgid_windows.responder.sent; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1160}, "%s", "ike->sa.st_v2_msgid_windows.responder.recv == ike->sa.st_v2_msgid_windows.responder.sent" ); } assertion__; }); | |||
1161 | ||||
1162 | if (msgid < ike->sa.st_v2_msgid_windows.responder.sent) { | |||
1163 | /* | |||
1164 | * this is an OLD retransmit and out sliding window | |||
1165 | * holds only the most recent response. we can't do | |||
1166 | * anything | |||
1167 | */ | |||
1168 | log_state(RC_LOG, &ike->sa, | |||
1169 | "received too old retransmit: %jd < %jd", | |||
1170 | msgid, ike->sa.st_v2_msgid_windows.responder.sent); | |||
1171 | return true1; | |||
1172 | } else if (msgid == ike->sa.st_v2_msgid_windows.responder.sent) { | |||
1173 | /* | |||
1174 | * This was the last request processed and, | |||
1175 | * presumably, a response was sent. Retransmit the | |||
1176 | * saved response (the response was saved right?). | |||
1177 | */ | |||
1178 | if (ike->sa.st_v2_outgoing[MESSAGE_RESPONSE] == NULL((void*)0)) { | |||
1179 | FAIL_V2_MSGID(ike, &ike->sa,fail_v2_msgid((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1182}, ike, &ike->sa, "retransmission for message %jd exchange %s failed responder.sent %jd - there is no stored message or fragments to retransmit" , msgid, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg ), ike->sa.st_v2_msgid_windows.responder.sent) | |||
1180 | "retransmission for message %jd exchange %s failed responder.sent %jd - there is no stored message or fragments to retransmit",fail_v2_msgid((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1182}, ike, &ike->sa, "retransmission for message %jd exchange %s failed responder.sent %jd - there is no stored message or fragments to retransmit" , msgid, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg ), ike->sa.st_v2_msgid_windows.responder.sent) | |||
1181 | msgid, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg),fail_v2_msgid((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1182}, ike, &ike->sa, "retransmission for message %jd exchange %s failed responder.sent %jd - there is no stored message or fragments to retransmit" , msgid, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg ), ike->sa.st_v2_msgid_windows.responder.sent) | |||
1182 | ike->sa.st_v2_msgid_windows.responder.sent)fail_v2_msgid((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1182}, ike, &ike->sa, "retransmission for message %jd exchange %s failed responder.sent %jd - there is no stored message or fragments to retransmit" , msgid, enum_name(&ikev2_exchange_names, md->hdr.isa_xchg ), ike->sa.st_v2_msgid_windows.responder.sent); | |||
1183 | return true1; | |||
1184 | } | |||
1185 | /* | |||
1186 | * If things are fragmented, only respond to the first | |||
1187 | * fragment. | |||
1188 | */ | |||
1189 | unsigned fragment = 0; | |||
1190 | if (md->hdr.isa_np == ISAKMP_NEXT_v2SKF) { | |||
1191 | struct ikev2_skf skf; | |||
1192 | pb_stream in_pbs = md->message_pbs; /* copy */ | |||
1193 | if (!in_struct(&skf, &ikev2_skf_desc, &in_pbs, NULL((void*)0))) { | |||
1194 | return true1; | |||
1195 | } | |||
1196 | fragment = skf.isaskf_number; | |||
1197 | } | |||
1198 | if (fragment == 0) { | |||
1199 | log_state(RC_LOG, &ike->sa, | |||
1200 | "received duplicate %s message request (Message ID %jd); retransmitting response", | |||
1201 | enum_short_name(&ikev2_exchange_names, md->hdr.isa_xchg), | |||
1202 | msgid); | |||
1203 | send_recorded_v2_message(ike, "ikev2-responder-retransmit", | |||
1204 | MESSAGE_RESPONSE); | |||
1205 | } else if (fragment == 1) { | |||
1206 | log_state(RC_LOG, &ike->sa, | |||
1207 | "received duplicate %s message request (Message ID %jd, fragment %u); retransmitting response", | |||
1208 | enum_short_name(&ikev2_exchange_names, md->hdr.isa_xchg), | |||
1209 | msgid, fragment); | |||
1210 | send_recorded_v2_message(ike, "ikev2-responder-retransmt (fragment 1)", | |||
1211 | MESSAGE_RESPONSE); | |||
1212 | } else { | |||
1213 | dbg_v2_msgid(ike, &ike->sa, | |||
1214 | "received duplicate %s message request (Message ID %jd, fragment %u); discarded as not fragment 1", | |||
1215 | enum_short_name(&ikev2_exchange_names, md->hdr.isa_xchg), | |||
1216 | msgid, fragment); | |||
1217 | } | |||
1218 | return true1; | |||
1219 | } else { | |||
1220 | /* all that is left */ | |||
1221 | pexpect(msgid > ike->sa.st_v2_msgid_windows.responder.sent)({ _Bool assertion__ = msgid > ike->sa.st_v2_msgid_windows .responder.sent; if (!assertion__) { log_pexpect((where_t) { . func = __func__, .basename = "ikev2.c" , .line = 1221}, "%s", "msgid > ike->sa.st_v2_msgid_windows.responder.sent"); } assertion__; }); | |||
1222 | } | |||
1223 | ||||
1224 | /* | |||
1225 | * Is something already processing this request? | |||
1226 | * | |||
1227 | * Processing only starts for real once a responder has | |||
1228 | * accumulated all fragments and obtained KEYMAT. | |||
1229 | */ | |||
1230 | { | |||
1231 | struct state *responder = find_v2_sa_by_responder_wip(ike, md->hdr.isa_msgid); | |||
1232 | /* only a true responder */ | |||
1233 | pexpect(responder == NULL ||({ _Bool assertion__ = responder == ((void*)0) || responder-> st_v2_msgid_wip.responder == msgid; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1234}, "%s", "responder == NULL || responder->st_v2_msgid_wip.responder == msgid" ); } assertion__; }) | |||
1234 | responder->st_v2_msgid_wip.responder == msgid)({ _Bool assertion__ = responder == ((void*)0) || responder-> st_v2_msgid_wip.responder == msgid; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1234}, "%s", "responder == NULL || responder->st_v2_msgid_wip.responder == msgid" ); } assertion__; }); | |||
1235 | if (responder != NULL((void*)0)) { | |||
1236 | /* this generates the log message */ | |||
1237 | pexpect(verbose_state_busy(responder))({ _Bool assertion__ = verbose_state_busy(responder); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1237}, "%s", "verbose_state_busy(responder)"); } assertion__ ; }); | |||
1238 | return true1; | |||
1239 | } | |||
1240 | } | |||
1241 | ||||
1242 | /* | |||
1243 | * The IKE SA responder, having accumulated all the fragments | |||
1244 | * for the IKE_AUTH request, is computing the SKEYSEED. When | |||
1245 | * SKEYSEED finishes .st_v2_rfrags is wiped and the Message | |||
1246 | * IDs updated to flag that the message as work-in-progress | |||
1247 | * (so above check will have succeeded). | |||
1248 | */ | |||
1249 | if (state_is_busy(&ike->sa)) { | |||
1250 | /* | |||
1251 | * To keep tests happy, try to output text matching | |||
1252 | * verbose_state_busy(); but with some extra detail. | |||
1253 | */ | |||
1254 | #if 0 | |||
1255 | /* | |||
1256 | * XXX: hang onto this code for now - it shows how to | |||
1257 | * lightly unpack fragments. Will be useful when | |||
1258 | * fragmentation code is moved out of the state lookup | |||
1259 | * code. | |||
1260 | */ | |||
1261 | unsigned fragment = 0; | |||
1262 | if (md->hdr.isa_np == ISAKMP_NEXT_v2SKF) { | |||
1263 | struct ikev2_skf skf; | |||
1264 | pb_stream in_pbs = md->message_pbs; /* copy */ | |||
1265 | if (!in_struct(&skf, &ikev2_skf_desc, &in_pbs, NULL((void*)0))) { | |||
1266 | return true1; | |||
1267 | } | |||
1268 | fragment = skf.isaskf_number; | |||
1269 | } | |||
1270 | if (fragment == 0) { | |||
1271 | log_state(RC_LOG, &ike->sa, | |||
1272 | "discarding packet received during asynchronous work (DNS or crypto) in %s", | |||
1273 | ike->sa.st_state->name); | |||
1274 | } else if (fragment == 1) { | |||
1275 | log_state(RC_LOG, &ike->sa, | |||
1276 | "discarding fragments received during asynchronous work (DNS or crypto) in %s", | |||
1277 | ike->sa.st_state->name); | |||
1278 | } else { | |||
1279 | dbg_v2_msgid(ike, &ike->sa, | |||
1280 | "discarding fragment %u received during asynchronous work (DNS or crypto) in %s", | |||
1281 | fragment, ike->sa.st_state->name); | |||
1282 | } | |||
1283 | #else | |||
1284 | log_state(RC_LOG, &ike->sa, | |||
1285 | "discarding packet received during asynchronous work (DNS or crypto) in %s", | |||
1286 | ike->sa.st_state->name); | |||
1287 | #endif | |||
1288 | return true1; | |||
1289 | } | |||
1290 | ||||
1291 | struct v2_incomming_fragments *frags = ike->sa.st_v2_incomming[MESSAGE_REQUEST]; | |||
1292 | if (frags != NULL((void*)0)) { | |||
1293 | pexpect(frags->count < frags->total)({ _Bool assertion__ = frags->count < frags->total; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2.c" , .line = 1293}, "%s", "frags->count < frags->total" ); } assertion__; }); | |||
1294 | dbg_v2_msgid(ike, &ike->sa, | |||
1295 | "not a duplicate - responder is accumulating fragments for message request %jd", | |||
1296 | msgid); | |||
1297 | } else { | |||
1298 | dbg_v2_msgid(ike, &ike->sa, | |||
1299 | "not a duplicate - message request %jd is new", | |||
1300 | msgid); | |||
1301 | } | |||
1302 | ||||
1303 | return false0; | |||
1304 | } | |||
1305 | ||||
1306 | /* | |||
1307 | * A duplicate response could be: | |||
1308 | * | |||
1309 | * - for an old request where there's no longer an initiator waiting, | |||
1310 | * and can be dropped | |||
1311 | * | |||
1312 | * - the initiator is busy, presumably because this response is a | |||
1313 | * duplicate and the initiator is waiting on crypto to complete so | |||
1314 | * it can decrypt the response | |||
1315 | */ | |||
1316 | static bool_Bool is_duplicate_response(struct ike_sa *ike, | |||
1317 | struct state *initiator, | |||
1318 | struct msg_digest *md) | |||
1319 | { | |||
1320 | passert(v2_msg_role(md) == MESSAGE_RESPONSE){ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 1320}, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } }; | |||
1321 | intmax_t msgid = md->hdr.isa_msgid; | |||
1322 | ||||
1323 | /* only a true initiator */ | |||
1324 | pexpect(initiator == NULL ||({ _Bool assertion__ = initiator == ((void*)0) || initiator-> st_v2_msgid_wip.initiator == msgid; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1325}, "%s", "initiator == NULL || initiator->st_v2_msgid_wip.initiator == msgid" ); } assertion__; }) | |||
1325 | initiator->st_v2_msgid_wip.initiator == msgid)({ _Bool assertion__ = initiator == ((void*)0) || initiator-> st_v2_msgid_wip.initiator == msgid; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1325}, "%s", "initiator == NULL || initiator->st_v2_msgid_wip.initiator == msgid" ); } assertion__; }); | |||
1326 | ||||
1327 | /* the sliding window is really small?!? */ | |||
1328 | pexpect(ike->sa.st_v2_msgid_windows.responder.recv ==({ _Bool assertion__ = ike->sa.st_v2_msgid_windows.responder .recv == ike->sa.st_v2_msgid_windows.responder.sent; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1329}, "%s", "ike->sa.st_v2_msgid_windows.responder.recv == ike->sa.st_v2_msgid_windows.responder.sent" ); } assertion__; }) | |||
1329 | ike->sa.st_v2_msgid_windows.responder.sent)({ _Bool assertion__ = ike->sa.st_v2_msgid_windows.responder .recv == ike->sa.st_v2_msgid_windows.responder.sent; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1329}, "%s", "ike->sa.st_v2_msgid_windows.responder.recv == ike->sa.st_v2_msgid_windows.responder.sent" ); } assertion__; }); | |||
1330 | ||||
1331 | if (msgid <= ike->sa.st_v2_msgid_windows.initiator.recv) { | |||
1332 | /* | |||
1333 | * Processing of the response was completed so drop as | |||
1334 | * too old. | |||
1335 | * | |||
1336 | * XXX: Should be rate_log() but that shows up in the | |||
1337 | * whack output. While "correct" it messes with test | |||
1338 | * output. The old log line didn't show up because | |||
1339 | * current-state wasn't set. | |||
1340 | * | |||
1341 | * Here's roughly why INITIATOR can be non-NULL: | |||
1342 | * | |||
1343 | * - west.#8 needs a rekey, so west.#11 is created and | |||
1344 | * it sends a CREATE_CHILD_SA with Message ID 3. | |||
1345 | * | |||
1346 | * - west.#8 gives up on the re-key so it forces a | |||
1347 | * delete request (aka record'n'send), sending a | |||
1348 | * second message with ID 4 | |||
1349 | * | |||
1350 | * West has two outstanding messages yet its window | |||
1351 | * size of 1! | |||
1352 | * | |||
1353 | * - east receives the rekey with ID 3, creates | |||
1354 | * east.#11 and and sends it off for further | |||
1355 | * processing | |||
1356 | * | |||
1357 | * - east receives the delete with ID 4, forces a | |||
1358 | * message ID update and sends an ID 4 response | |||
1359 | * confirming the delete | |||
1360 | * | |||
1361 | * - east.#11 finishes its crypto so east sends back | |||
1362 | * its response with Message ID 3 for a re-keyed SA it | |||
1363 | * just deleted?!?! | |||
1364 | * | |||
1365 | * East has responded with two out-of-order messages | |||
1366 | * (if the window size was 2 this would be ok but it | |||
1367 | * isn't). | |||
1368 | * | |||
1369 | * - west receives the ID 4 response, tries to delete | |||
1370 | * the IKE SA but can't because west.#11 is lurking; | |||
1371 | * but regardless the ID window is forced 2->4 | |||
1372 | * | |||
1373 | * - west receives the ID 3 response, which is clearly | |||
1374 | * to-old so doesn't expect there to be a matching | |||
1375 | * initiator, arrg | |||
1376 | */ | |||
1377 | if (initiator != NULL((void*)0)) { | |||
1378 | dbg_v2_msgid(ike, initiator, "XXX: expecting initiator==NULL - suspect record'n'send with an out-of-order wrong packet response; discarding packet"); | |||
1379 | } else { | |||
1380 | dbg_v2_msgid(ike, initiator, "already processed response %jd (%s); discarding packet", | |||
1381 | msgid, enum_short_name(&ikev2_exchange_names, md->hdr.isa_xchg)); | |||
1382 | } | |||
1383 | return true1; | |||
1384 | } | |||
1385 | ||||
1386 | if (initiator == NULL((void*)0)) { | |||
1387 | /* | |||
1388 | * While there's an IKE SA matching the IKE SPIs, | |||
1389 | * there's no corresponding initiator for the message. | |||
1390 | * | |||
1391 | * XXX: rate_log() sends to whack which, while making | |||
1392 | * sense, but churns the test output. | |||
1393 | */ | |||
1394 | log_state(RC_LOG, &ike->sa, | |||
1395 | "%s message response with Message ID %jd has no matching SA", | |||
1396 | enum_name(&ikev2_exchange_names, md->hdr.isa_xchg), msgid); | |||
1397 | return true1; | |||
1398 | } | |||
1399 | ||||
1400 | /* | |||
1401 | * Sanity check the MSGID and initiator against the IKE SA | |||
1402 | * Message ID window. | |||
1403 | */ | |||
1404 | ||||
1405 | if (msgid > ike->sa.st_v2_msgid_windows.initiator.sent) { | |||
1406 | /* | |||
1407 | * There was an initiator waiting for a message that, | |||
1408 | * according to the IKE SA, has yet to be sent?!? | |||
1409 | */ | |||
1410 | FAIL_V2_MSGID(ike, initiator,fail_v2_msgid((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1412}, ike, initiator, "dropping response with Message ID %jd which is from the future - last request sent was %jd" , msgid, ike->sa.st_v2_msgid_windows.initiator.sent) | |||
1411 | "dropping response with Message ID %jd which is from the future - last request sent was %jd",fail_v2_msgid((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1412}, ike, initiator, "dropping response with Message ID %jd which is from the future - last request sent was %jd" , msgid, ike->sa.st_v2_msgid_windows.initiator.sent) | |||
1412 | msgid, ike->sa.st_v2_msgid_windows.initiator.sent)fail_v2_msgid((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1412}, ike, initiator, "dropping response with Message ID %jd which is from the future - last request sent was %jd" , msgid, ike->sa.st_v2_msgid_windows.initiator.sent); | |||
1413 | return true1; | |||
1414 | } | |||
1415 | ||||
1416 | /* | |||
1417 | * If the state is busy, presumably doing something like | |||
1418 | * crypto, skip further processing. | |||
1419 | * | |||
1420 | * For fragments, things only go busy once all fragments have | |||
1421 | * been received (and re-transmitted fragments are ignored). | |||
1422 | * If this changes then a lot more than this code will need to | |||
1423 | * be moved. | |||
1424 | * | |||
1425 | * XXX: Is there a better way to handle this? | |||
1426 | */ | |||
1427 | if (verbose_state_busy(initiator)) { | |||
1428 | return true1; | |||
1429 | } | |||
1430 | ||||
1431 | return false0; | |||
1432 | } | |||
1433 | ||||
1434 | /* | |||
1435 | * process an input packet, possibly generating a reply. | |||
1436 | * | |||
1437 | * If all goes well, this routine eventually calls a state-specific | |||
1438 | * transition function. | |||
1439 | * | |||
1440 | * This routine will not release_any_md(mdp). It is expected that its | |||
1441 | * caller will do this. In fact, it will zap *mdp to NULL if it thinks | |||
1442 | * **mdp should not be freed. So the caller should be prepared for | |||
1443 | * *mdp being set to NULL. | |||
1444 | * | |||
1445 | * Start by looking for (or creating) the IKE SA responsible for the | |||
1446 | * IKE SPIs group ..... | |||
1447 | */ | |||
1448 | ||||
1449 | static void ike_process_packet(struct msg_digest *mdp, struct ike_sa *ike); | |||
1450 | ||||
1451 | void ikev2_process_packet(struct msg_digest *md) | |||
1452 | { | |||
1453 | /* Look for an state that matches the various things we know: | |||
1454 | * | |||
1455 | * 1) exchange type received? | |||
1456 | * 2) is it initiator or not? | |||
1457 | */ | |||
1458 | const enum isakmp_xchg_types ix = md->hdr.isa_xchg; | |||
1459 | ||||
1460 | /* | |||
1461 | * If the IKE SA initiator sent the message then this end is | |||
1462 | * looking for the IKE SA responder (and vice versa). | |||
1463 | */ | |||
1464 | enum sa_role expected_local_ike_role = (md->hdr.isa_flags & ISAKMP_FLAGS_v2_IKE_I(1 << 3)) ? SA_RESPONDER : SA_INITIATOR; | |||
1465 | ||||
1466 | /* | |||
1467 | * Dump what the message says, once a state has been found | |||
1468 | * this can be checked against what is. | |||
1469 | */ | |||
1470 | 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_debug_stream (buf), buf = ((void*)0)) { | |||
1471 | switch (expected_local_ike_role) { | |||
1472 | case SA_RESPONDER: | |||
1473 | jam(buf, "I am the IKE SA Original Responder"); | |||
1474 | break; | |||
1475 | case SA_INITIATOR: | |||
1476 | jam(buf, "I am the IKE SA Original Initiator"); | |||
1477 | break; | |||
1478 | default: | |||
1479 | bad_case(expected_local_ike_role)libreswan_bad_case("expected_local_ike_role", (expected_local_ike_role ), (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1479}); | |||
1480 | } | |||
1481 | jam(buf, " receiving an IKEv2 "); | |||
1482 | jam_enum_short(buf, &ikev2_exchange_names, ix); | |||
1483 | switch (v2_msg_role(md)) { | |||
1484 | case MESSAGE_RESPONSE: | |||
1485 | jam(buf, " response "); | |||
1486 | break; | |||
1487 | case MESSAGE_REQUEST: | |||
1488 | jam(buf, " request "); | |||
1489 | break; | |||
1490 | default: | |||
1491 | bad_case(v2_msg_role(md))libreswan_bad_case("v2_msg_role(md)", (v2_msg_role(md)), (where_t ) { .func = __func__, .basename = "ikev2.c" , .line = 1491}); | |||
1492 | } | |||
1493 | } | |||
1494 | ||||
1495 | /* | |||
1496 | * Find the IKE SA that is looking after this IKE SPI family. | |||
1497 | * | |||
1498 | * If it's a new IKE_SA_INIT request (or previously discarded | |||
1499 | * request due to cookies) then a new IKE SA is created. | |||
1500 | */ | |||
1501 | ||||
1502 | if (ix == ISAKMP_v2_IKE_SA_INIT) { | |||
1503 | /* | |||
1504 | * The message ID of the initial exchange is always | |||
1505 | * zero. | |||
1506 | */ | |||
1507 | if (md->hdr.isa_msgid != 0) { | |||
1508 | rate_log(md, "dropping IKE_SA_INIT message containing non-zero message ID"); | |||
1509 | return; | |||
1510 | } | |||
1511 | /* | |||
1512 | * Now try to find the state | |||
1513 | */ | |||
1514 | switch (v2_msg_role(md)) { | |||
1515 | ||||
1516 | case MESSAGE_REQUEST: | |||
1517 | { | |||
1518 | ||||
1519 | /* | |||
1520 | * 3.1. The IKE Header (Flags) | |||
1521 | * | |||
1522 | * * I (Initiator) - This bit MUST be set in | |||
1523 | * messages sent by the original initiator | |||
1524 | * of the IKE SA and MUST be cleared in | |||
1525 | * messages sent by the original responder. | |||
1526 | * It is used by the recipient to determine | |||
1527 | * which eight octets of the SPI were | |||
1528 | * generated by the recipient. This bit | |||
1529 | * changes to reflect who initiated the last | |||
1530 | * rekey of the IKE SA. | |||
1531 | */ | |||
1532 | if (expected_local_ike_role != SA_RESPONDER) { | |||
1533 | rate_log(md, "IKE_SA_INIT request has conflicting I (Initiator) flag; dropping packet"); | |||
1534 | return; | |||
1535 | } | |||
1536 | ||||
1537 | /* | |||
1538 | * 3.1. The IKE Header (IKE SA Initiator SPI) | |||
1539 | * | |||
1540 | * o Initiator's SPI (8 octets) - A value | |||
1541 | * chosen by the initiator to identify a | |||
1542 | * unique IKE Security Association. This | |||
1543 | * value MUST NOT be zero. | |||
1544 | * | |||
1545 | * (it isn't obvious why this rule is needed; | |||
1546 | * exchanges still work) | |||
1547 | */ | |||
1548 | if (ike_spi_is_zero(&md->hdr.isa_ike_initiator_spiisa_ike_spis.initiator)) { | |||
1549 | rate_log(md, "IKE_SA_INIT request has zero IKE SA Initiator SPI; dropping packet"); | |||
1550 | return; | |||
1551 | } | |||
1552 | ||||
1553 | /* | |||
1554 | * 3.1. The IKE Header (IKE SA Responder SPI) | |||
1555 | * | |||
1556 | * o Responder's SPI (8 octets) - A value | |||
1557 | * chosen by the responder to identify a | |||
1558 | * unique IKE Security Association. This | |||
1559 | * value MUST be zero in the first message | |||
1560 | * of an IKE initial exchange (including | |||
1561 | * repeats of that message including a | |||
1562 | * cookie). | |||
1563 | * | |||
1564 | * (since this is the very first message, the | |||
1565 | * initiator can't know the responder's SPI). | |||
1566 | */ | |||
1567 | if (!ike_spi_is_zero(&md->hdr.isa_ike_responder_spiisa_ike_spis.responder)) { | |||
1568 | rate_log(md, "IKE_SA_INIT request has non-zero IKE SA Responder SPI; dropping packet"); | |||
1569 | return; | |||
1570 | } | |||
1571 | ||||
1572 | /* | |||
1573 | * Look for a pre-existing IKE SA responder | |||
1574 | * state using just the SPIi (SPIr in the | |||
1575 | * message is zero so can't be used). | |||
1576 | * | |||
1577 | * XXX: RFC 7296 says this isn't sufficient: | |||
1578 | * | |||
1579 | * 2.1. Use of Retransmission Timers | |||
1580 | * | |||
1581 | * Retransmissions of the IKE_SA_INIT | |||
1582 | * request require some special handling. | |||
1583 | * When a responder receives an IKE_SA_INIT | |||
1584 | * request, it has to determine whether the | |||
1585 | * packet is a retransmission belonging to | |||
1586 | * an existing "half-open" IKE SA (in which | |||
1587 | * case the responder retransmits the same | |||
1588 | * response), or a new request (in which | |||
1589 | * case the responder creates a new IKE SA | |||
1590 | * and sends a fresh response), or it | |||
1591 | * belongs to an existing IKE SA where the | |||
1592 | * IKE_AUTH request has been already | |||
1593 | * received (in which case the responder | |||
1594 | * ignores it). | |||
1595 | * | |||
1596 | * It is not sufficient to use the | |||
1597 | * initiator's SPI and/or IP address to | |||
1598 | * differentiate between these three cases | |||
1599 | * because two different peers behind a | |||
1600 | * single NAT could choose the same | |||
1601 | * initiator SPI. Instead, a robust | |||
1602 | * responder will do the IKE SA lookup using | |||
1603 | * the whole packet, its hash, or the Ni | |||
1604 | * payload. | |||
1605 | * | |||
1606 | * But realistically, either there's an IOT | |||
1607 | * device sending out a hardwired SPIi, or | |||
1608 | * there is a clash and a retry will generate | |||
1609 | * a new conflicting SPIi. | |||
1610 | * | |||
1611 | * If the lookup succeeds then there are | |||
1612 | * several possibilities: | |||
1613 | * | |||
1614 | * State has Message ID == 0: | |||
1615 | * | |||
1616 | * Either it really is a duplicate; or it's a | |||
1617 | * second (fake?) intiator sending the same | |||
1618 | * SPIi at exactly the same time as the first | |||
1619 | * (wow, what are the odds, it must be our | |||
1620 | * lucky day!). | |||
1621 | * | |||
1622 | * Either way, the duplicate code needs to | |||
1623 | * compare packets and decide if a retransmit | |||
1624 | * or drop is required. If the second | |||
1625 | * initiator is real, then it will timeout and | |||
1626 | * then retry with a new SPIi. | |||
1627 | * | |||
1628 | * State has Message ID > 0: | |||
1629 | * | |||
1630 | * Either it is an old duplicate; or, again, | |||
1631 | * it's a second intiator sending the same | |||
1632 | * SPIi only slightly later (again, what are | |||
1633 | * the odds!). | |||
1634 | * | |||
1635 | * Several choices: let the duplicate code | |||
1636 | * drop the packet, which is correct for an | |||
1637 | * old duplicate message; or ignore the | |||
1638 | * existing state and create a new one, which | |||
1639 | * is good for the second initiator but not so | |||
1640 | * good for an old duplicate. Given an old | |||
1641 | * duplicate is far more likely, handle that | |||
1642 | * cleenly - let the duplicate code drop the | |||
1643 | * packet. | |||
1644 | */ | |||
1645 | struct ike_sa *old = | |||
1646 | find_v2_ike_sa_by_initiator_spi(&md->hdr.isa_ike_initiator_spiisa_ike_spis.initiator, | |||
1647 | expected_local_ike_role); | |||
1648 | if (old != NULL((void*)0)) { | |||
1649 | intmax_t msgid = md->hdr.isa_msgid; | |||
1650 | pexpect(msgid == 0)({ _Bool assertion__ = msgid == 0; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1650}, "%s", "msgid == 0"); } assertion__; }); /* per above */ | |||
1651 | /* XXX: keep test results happy */ | |||
1652 | if (md->fake_clone) { | |||
1653 | log_state(RC_LOG, &old->sa, "IMPAIR: processing a fake (cloned) message"); | |||
1654 | } | |||
1655 | if (verbose_state_busy(&old->sa)) { | |||
1656 | /* already logged */; | |||
1657 | } else if (old->sa.st_state->kind == STATE_PARENT_R1 && | |||
1658 | old->sa.st_v2_msgid_windows.responder.recv == 0 && | |||
1659 | old->sa.st_v2_msgid_windows.responder.sent == 0 && | |||
1660 | hunk_eq(old->sa.st_firstpacket_peer,({ typeof(old->sa.st_firstpacket_peer) l_ = old->sa.st_firstpacket_peer ; typeof(pbs_in_as_shunk(&md->message_pbs)) r_ = pbs_in_as_shunk (&md->message_pbs); bytes_eq(l_.ptr, l_.len, r_.ptr, r_ .len); }) | |||
1661 | pbs_in_as_shunk(&md->message_pbs))({ typeof(old->sa.st_firstpacket_peer) l_ = old->sa.st_firstpacket_peer ; typeof(pbs_in_as_shunk(&md->message_pbs)) r_ = pbs_in_as_shunk (&md->message_pbs); bytes_eq(l_.ptr, l_.len, r_.ptr, r_ .len); })) { | |||
1662 | /* | |||
1663 | * It looks a lot like a shiny | |||
1664 | * new IKE SA that only just | |||
1665 | * responded to a message | |||
1666 | * identical to this one. | |||
1667 | * Re-transmit the response. | |||
1668 | * | |||
1669 | * XXX: Log message matches | |||
1670 | * is_duplicate_request() - | |||
1671 | * keep test results happy. | |||
1672 | */ | |||
1673 | log_state(RC_LOG, &old->sa, | |||
1674 | "received duplicate %s message request (Message ID %jd); retransmitting response", | |||
1675 | enum_short_name(&ikev2_exchange_names, md->hdr.isa_xchg), | |||
1676 | msgid); | |||
1677 | send_recorded_v2_message(old, "IKE_SA_INIT responder retransmit", | |||
1678 | MESSAGE_RESPONSE); | |||
1679 | } else { | |||
1680 | /* | |||
1681 | * Either: | |||
1682 | * | |||
1683 | * - it is an old duplicate | |||
1684 | * and the packet should be | |||
1685 | * dropped | |||
1686 | * | |||
1687 | * - it's a second intiator | |||
1688 | * using the same SPIi | |||
1689 | * (wow!) and a new IKE SA | |||
1690 | * should be created | |||
1691 | * | |||
1692 | * However the odds of the | |||
1693 | * later are essentially zero | |||
1694 | * so assume the former and | |||
1695 | * drop the packet. | |||
1696 | * | |||
1697 | * XXX: Log message matches | |||
1698 | * is_duplicate_request() - | |||
1699 | * keep test results happy. | |||
1700 | */ | |||
1701 | log_state(RC_LOG, &old->sa, | |||
1702 | "received too old retransmit: %jd < %jd", | |||
1703 | msgid, old->sa.st_v2_msgid_windows.responder.sent); | |||
1704 | } | |||
1705 | return; | |||
1706 | } | |||
1707 | ||||
1708 | if (drop_new_exchanges()) { | |||
1709 | /* only log for debug to prevent disk filling up */ | |||
1710 | dbg("pluto is overloaded with half-open IKE SAs; dropping new exchange"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("pluto is overloaded with half-open IKE SAs; dropping new exchange" ); } }; | |||
1711 | return; | |||
1712 | } | |||
1713 | ||||
1714 | /* | |||
1715 | * Always check for cookies! | |||
1716 | * | |||
1717 | * XXX: why? | |||
1718 | * | |||
1719 | * Because the v2N_COOKIE payload is first, | |||
1720 | * parsing and verifying it should be | |||
1721 | * relatively quick and cheap. Right? | |||
1722 | * | |||
1723 | * No. The equation uses v2Ni forcing the | |||
1724 | * entire payload to be parsed. | |||
1725 | * | |||
1726 | * The error notification is probably | |||
1727 | * INVALID_SYNTAX, but could be | |||
1728 | * v2N_UNSUPPORTED_CRITICAL_PAYLOAD. | |||
1729 | */ | |||
1730 | pexpect(!md->message_payloads.parsed)({ _Bool assertion__ = !md->message_payloads.parsed; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1730}, "%s", "!md->message_payloads.parsed" ); } assertion__; }); | |||
1731 | md->message_payloads = ikev2_decode_payloads(md->md_logger, md, | |||
1732 | &md->message_pbs, | |||
1733 | md->hdr.isa_np); | |||
1734 | if (md->message_payloads.n != v2N_NOTHING_WRONG) { | |||
1735 | if (require_ddos_cookies()) { | |||
1736 | dbg("DDOS so not responding to invalid packet"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("DDOS so not responding to invalid packet"); } }; | |||
1737 | } else { | |||
1738 | chunk_t data = chunk2(md->message_payloads.data, | |||
1739 | md->message_payloads.data_size); | |||
1740 | send_v2N_response_from_md(md, md->message_payloads.n, | |||
1741 | &data); | |||
1742 | } | |||
1743 | return; | |||
1744 | } | |||
1745 | ||||
1746 | /* | |||
1747 | * Do I want a cookie? | |||
1748 | */ | |||
1749 | if (v2_rejected_initiator_cookie(md, require_ddos_cookies())) { | |||
1750 | dbg("pluto is overloaded and demanding cookies; dropping new exchange"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("pluto is overloaded and demanding cookies; dropping new exchange" ); } }; | |||
1751 | return; | |||
1752 | } | |||
1753 | ||||
1754 | /* | |||
1755 | * Check for v2N_REDIRECT_SUPPORTED/v2N_REDIRECTED_FROM | |||
1756 | * notification. If redirection is a MUST, try to respond | |||
1757 | * with v2N_REDIRECT and don't continue further. | |||
1758 | * Otherwise continue as usual. | |||
1759 | * | |||
1760 | * The function below will do everything (and log the result). | |||
1761 | */ | |||
1762 | if (redirect_global(md)) { | |||
1763 | return; | |||
1764 | } | |||
1765 | ||||
1766 | /* | |||
1767 | * Check if we would drop the packet based on | |||
1768 | * VID before we create a state. Move this to | |||
1769 | * ikev2_oppo.c: drop_oppo_requests()? | |||
1770 | */ | |||
1771 | for (struct payload_digest *p = md->chain[ISAKMP_NEXT_v2V]; p != NULL((void*)0); p = p->next) { | |||
1772 | if (vid_is_oppo((char *)p->pbs.cur, pbs_left(&p->pbs)((size_t)((&p->pbs)->roof - (&p->pbs)->cur )))) { | |||
1773 | if (pluto_drop_oppo_null) { | |||
1774 | dbg("Dropped IKE request for Opportunistic IPsec by global policy"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Dropped IKE request for Opportunistic IPsec by global policy" ); } }; | |||
1775 | return; | |||
1776 | } | |||
1777 | dbg("Processing IKE request for Opportunistic IPsec"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Processing IKE request for Opportunistic IPsec" ); } }; | |||
1778 | break; | |||
1779 | } | |||
1780 | } | |||
1781 | ||||
1782 | /* | |||
1783 | * Does the message match the (only) expected | |||
1784 | * transition? | |||
1785 | */ | |||
1786 | const struct finite_state *start_state = finite_states[STATE_PARENT_R0]; | |||
1787 | const struct state_v2_microcode *transition = | |||
1788 | find_v2_state_transition(md->md_logger, start_state, md); | |||
1789 | if (transition == NULL((void*)0)) { | |||
1790 | /* already logged */ | |||
1791 | send_v2N_response_from_md(md, v2N_INVALID_SYNTAX, NULL((void*)0)); | |||
1792 | return; | |||
1793 | } | |||
1794 | ||||
1795 | /* | |||
1796 | * Is there a connection that matches the | |||
1797 | * message? | |||
1798 | */ | |||
1799 | lset_t policy = LEMPTY((lset_t)0); | |||
1800 | bool_Bool send_reject_response = true1; | |||
1801 | struct connection *c = find_v2_host_pair_connection(md, &policy, | |||
1802 | &send_reject_response); | |||
1803 | if (c == NULL((void*)0)) { | |||
1804 | if (send_reject_response) { | |||
1805 | /* | |||
1806 | * NO_PROPOSAL_CHOSEN is used | |||
1807 | * when the list of proposals | |||
1808 | * is empty, like when we did | |||
1809 | * not find any connection to | |||
1810 | * use. | |||
1811 | * | |||
1812 | * INVALID_SYNTAX is for | |||
1813 | * errors that a configuration | |||
1814 | * change could not fix. | |||
1815 | */ | |||
1816 | send_v2N_response_from_md(md, v2N_NO_PROPOSAL_CHOSEN, NULL((void*)0)); | |||
1817 | } | |||
1818 | return; | |||
1819 | } | |||
1820 | ||||
1821 | /* | |||
1822 | * We've committed to creating a state and, | |||
1823 | * presumably, dedicating real resources to | |||
1824 | * the connection. | |||
1825 | */ | |||
1826 | struct ike_sa *ike = new_v2_ike_state(transition, SA_RESPONDER, | |||
1827 | md->hdr.isa_ike_spis.initiator, | |||
1828 | ike_responder_spi(&md->sender, | |||
1829 | md->md_logger), | |||
1830 | c, policy, 0, null_fd((struct fd *) ((void*)0))); | |||
1831 | ||||
1832 | statetime_t start = statetime_backdate(&ike->sa, &md->md_inception); | |||
1833 | /* XXX: keep test results happy */ | |||
1834 | if (md->fake_clone) { | |||
1835 | log_state(RC_LOG, &ike->sa, "IMPAIR: processing a fake (cloned) message"); | |||
1836 | } | |||
1837 | push_cur_state(&ike->sa)log_push_state(&ike->sa, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1837}); | |||
1838 | v2_dispatch(ike, &ike->sa, md, transition); | |||
1839 | pop_cur_state(SOS_NOBODY)log_pop_state(0, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1839}); | |||
1840 | statetime_stop(&start, "%s()", __func__); | |||
1841 | return; | |||
1842 | } | |||
1843 | ||||
1844 | case MESSAGE_RESPONSE: | |||
1845 | { | |||
1846 | /* The responder must send: !IKE_I && MSG_R. */ | |||
1847 | if (expected_local_ike_role != SA_INITIATOR) { | |||
1848 | rate_log(md, "dropping IKE_SA_INIT response with conflicting IKE initiator flag"); | |||
1849 | return; | |||
1850 | } | |||
1851 | /* | |||
1852 | * 2.6. IKE SA SPIs and Cookies: When the | |||
1853 | * IKE_SA_INIT exchange does not result in the | |||
1854 | * creation of an IKE SA due to | |||
1855 | * INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN, or | |||
1856 | * COOKIE, the responder's SPI will be zero | |||
1857 | * also in the response message. However, if | |||
1858 | * the responder sends a non-zero responder | |||
1859 | * SPI, the initiator should not reject the | |||
1860 | * response for only that reason. | |||
1861 | * | |||
1862 | * i.e., can't check response for non-zero | |||
1863 | * SPIr. | |||
1864 | */ | |||
1865 | /* | |||
1866 | * Look for a pre-existing IKE SA responder | |||
1867 | * state using just the SPIi (SPIr in the | |||
1868 | * message isn't known so can't be used). | |||
1869 | * | |||
1870 | * An IKE_SA_INIT error notification response | |||
1871 | * (INVALID_KE, COOKIE) should contain a zero | |||
1872 | * SPIr (it must be ignored). | |||
1873 | * | |||
1874 | * An IKE_SA_INIT success response will | |||
1875 | * contain an as yet unknown but non-zero SPIr | |||
1876 | * so looking for it won't work. | |||
1877 | */ | |||
1878 | struct ike_sa *ike = | |||
1879 | find_v2_ike_sa_by_initiator_spi(&md->hdr.isa_ike_initiator_spiisa_ike_spis.initiator, | |||
1880 | expected_local_ike_role); | |||
1881 | if (ike == NULL((void*)0)) { | |||
1882 | /* | |||
1883 | * There should be a state matching | |||
1884 | * the original initiator's cookie. | |||
1885 | * Since there isn't someone's playing | |||
1886 | * games. Drop the packet. | |||
1887 | */ | |||
1888 | rate_log(md, "dropping IKE_SA_INIT response no matching IKE ISA"); | |||
1889 | return; | |||
1890 | } | |||
1891 | ||||
1892 | if (ike->sa.st_state->kind != STATE_PARENT_I1 || | |||
1893 | ike->sa.st_v2_msgid_windows.initiator.sent != 0 || | |||
1894 | ike->sa.st_v2_msgid_windows.initiator.recv != -1 || | |||
1895 | ike->sa.st_v2_msgid_wip.initiator != 0) { | |||
1896 | /* | |||
1897 | * This doesn't seem right; drop the | |||
1898 | * packet. | |||
1899 | */ | |||
1900 | rate_log(md, "dropping IKE_SA_INIT response as unexpected for matching IKE SA #%lu", | |||
1901 | ike->sa.st_serialno); | |||
1902 | return; | |||
1903 | } | |||
1904 | ||||
1905 | if (verbose_state_busy(&ike->sa)) { | |||
1906 | return; | |||
1907 | } | |||
1908 | ||||
1909 | dbg("unpacking clear payloads"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("unpacking clear payloads"); } }; | |||
1910 | md->message_payloads = ikev2_decode_payloads(ike->sa.st_logger, md, | |||
1911 | &md->message_pbs, | |||
1912 | md->hdr.isa_np); | |||
1913 | if (md->message_payloads.n != v2N_NOTHING_WRONG) { | |||
1914 | /* already logged */ | |||
1915 | return; | |||
1916 | } | |||
1917 | ||||
1918 | /* transition? */ | |||
1919 | const struct state_v2_microcode *transition = | |||
1920 | find_v2_state_transition(ike->sa.st_logger, ike->sa.st_state, md); | |||
1921 | if (transition == NULL((void*)0)) { | |||
1922 | /* already logged */ | |||
1923 | return; | |||
1924 | } | |||
1925 | ||||
1926 | statetime_t start = statetime_backdate(&ike->sa, &md->md_inception); | |||
1927 | push_cur_state(&ike->sa)log_push_state(&ike->sa, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1927}); | |||
1928 | v2_dispatch(ike, &ike->sa, md, transition); | |||
1929 | pop_cur_state(SOS_NOBODY)log_pop_state(0, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1929}); | |||
1930 | statetime_stop(&start, "%s()", __func__); | |||
1931 | return; | |||
1932 | } | |||
1933 | ||||
1934 | default: | |||
1935 | bad_case(v2_msg_role(md))libreswan_bad_case("v2_msg_role(md)", (v2_msg_role(md)), (where_t ) { .func = __func__, .basename = "ikev2.c" , .line = 1935}); | |||
1936 | } | |||
1937 | ||||
1938 | } | |||
1939 | ||||
1940 | passert(v2_msg_role(md) == MESSAGE_REQUEST ||{ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST || v2_msg_role (md) == MESSAGE_RESPONSE; if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1941}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST || v2_msg_role(md) == MESSAGE_RESPONSE" ); } } | |||
1941 | v2_msg_role(md) == MESSAGE_RESPONSE){ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST || v2_msg_role (md) == MESSAGE_RESPONSE; if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1941}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST || v2_msg_role(md) == MESSAGE_RESPONSE" ); } }; | |||
1942 | ||||
1943 | /* | |||
1944 | * Find the IKE SA with matching SPIs. | |||
1945 | * | |||
1946 | * The IKE SA's Message IDs can then be used to determine if | |||
1947 | * the message fits in the message window (new request, | |||
1948 | * expected response, or old message). | |||
1949 | */ | |||
1950 | struct ike_sa *ike = find_v2_ike_sa(&md->hdr.isa_ike_spis, | |||
1951 | expected_local_ike_role); | |||
1952 | if (ike == NULL((void*)0)) { | |||
1953 | struct esb_buf ixb; | |||
1954 | rate_log(md, "%s message %s has no corresponding IKE SA", | |||
1955 | enum_show_shortb(&ikev2_exchange_names, ix, &ixb), | |||
1956 | v2_msg_role(md) == MESSAGE_REQUEST ? "request" : "response"); | |||
1957 | return; | |||
1958 | } | |||
1959 | ||||
1960 | /* | |||
1961 | * There's at least an IKE SA, and possibly ST willing to | |||
1962 | * process the message. | |||
1963 | */ | |||
1964 | passert(ike != NULL){ _Bool assertion__ = ike != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1964}, "%s", "ike != NULL"); } }; | |||
1965 | ||||
1966 | /* | |||
1967 | * Re-check ST's IKE SA's role against the I(Initiator) flag | |||
1968 | * in the headers. Since above searches will only find an IKE | |||
1969 | * SA when the IKE SA's role is correct, this should always | |||
1970 | * work. | |||
1971 | */ | |||
1972 | if (!pexpect(ike->sa.st_sa_role == expected_local_ike_role)({ _Bool assertion__ = ike->sa.st_sa_role == expected_local_ike_role ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 1972}, "%s", "ike->sa.st_sa_role == expected_local_ike_role" ); } assertion__; })) { | |||
1973 | return; | |||
1974 | } | |||
1975 | ||||
1976 | /* | |||
1977 | * Since there's an IKE SA start billing and logging against | |||
1978 | * it. | |||
1979 | */ | |||
1980 | statetime_t start = statetime_backdate(&ike->sa, &md->md_inception); | |||
1981 | so_serial_t old = push_cur_state(&ike->sa)log_push_state(&ike->sa, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1981}); | |||
1982 | ike_process_packet(md, ike); | |||
1983 | pop_cur_state(old)log_pop_state(old, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 1983}); | |||
1984 | statetime_stop(&start, "%s()", __func__); | |||
1985 | } | |||
1986 | ||||
1987 | /* | |||
1988 | * The IKE SA for the message has been found (or created). Continue | |||
1989 | * verification, and identify the state (ST) that the message should | |||
1990 | * be sent to. | |||
1991 | */ | |||
1992 | ||||
1993 | static void ike_process_packet(struct msg_digest *md, struct ike_sa *ike) | |||
1994 | { | |||
1995 | /* | |||
1996 | * Deal with duplicate messages and busy states. | |||
1997 | */ | |||
1998 | struct state *st; | |||
1999 | switch (v2_msg_role(md)) { | |||
2000 | case MESSAGE_REQUEST: | |||
2001 | /* | |||
2002 | * The IKE SA always processes requests. | |||
2003 | * | |||
2004 | * XXX: except further down where the code creates a | |||
2005 | * new state when CREATE_CHILD_SA and switches to | |||
2006 | * that. | |||
2007 | * | |||
2008 | * The other quirk is with fragments; but the only | |||
2009 | * case that matters it when the IKE SA accumulating | |||
2010 | * them. | |||
2011 | */ | |||
2012 | if (md->fake_clone) { | |||
2013 | log_state(RC_LOG, &ike->sa, "IMPAIR: processing a fake (cloned) message"); | |||
2014 | } | |||
2015 | /* | |||
2016 | * Is this duplicate? | |||
2017 | * | |||
2018 | * If MD is a fragment then it isn't considered a | |||
2019 | * duplicate. | |||
2020 | */ | |||
2021 | if (is_duplicate_request(ike, md)) { | |||
2022 | return; | |||
2023 | } | |||
2024 | st = &ike->sa; | |||
2025 | break; | |||
2026 | case MESSAGE_RESPONSE: | |||
2027 | /* | |||
2028 | * This is the response to an earlier request; use the | |||
2029 | * IKE SA to find the state that initiated the | |||
2030 | * exchange (sent that request). | |||
2031 | * | |||
2032 | * If the response is a fragment then ST will be | |||
2033 | * non-NULL; is_duplicate_state() gets to figure out | |||
2034 | * if the fragments are complete or need to wait | |||
2035 | * longer. | |||
2036 | */ | |||
2037 | st = find_v2_sa_by_initiator_wip(ike, md->hdr.isa_msgid); | |||
2038 | if (md->fake_clone) { | |||
2039 | log_state(RC_LOG, st != NULL((void*)0) ? st : &ike->sa, | |||
2040 | "IMPAIR: processing a fake (cloned) message"); | |||
2041 | } | |||
2042 | if (is_duplicate_response(ike, st, md)) { | |||
2043 | return; | |||
2044 | } | |||
2045 | pexpect(st != NULL)({ _Bool assertion__ = st != ((void*)0); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2045}, "%s", "st != NULL"); } assertion__; }); | |||
2046 | break; | |||
2047 | default: | |||
2048 | bad_case(v2_msg_role(md))libreswan_bad_case("v2_msg_role(md)", (v2_msg_role(md)), (where_t ) { .func = __func__, .basename = "ikev2.c" , .line = 2048}); | |||
2049 | } | |||
2050 | ||||
2051 | /* | |||
2052 | * Now that the state that is to process the message has been | |||
2053 | * selected, switch logging to it. | |||
2054 | * | |||
2055 | * XXX: why the need to constantly pick a single winner and | |||
2056 | * switch to it? Because tests expect messages to be logged | |||
2057 | * against a specific state. It would be better of that code | |||
2058 | * specified that state as a parameter. | |||
2059 | */ | |||
2060 | passert(st != NULL){ _Bool assertion__ = st != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2060}, "%s", "st != NULL"); } }; | |||
2061 | /* XXX: debug-logging this is redundant */ | |||
2062 | push_cur_state(st)log_push_state(st, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2062}); | |||
2063 | ||||
2064 | /* | |||
2065 | * Have a state an and IKE SA, time to decode the payloads. | |||
2066 | */ | |||
2067 | dbg("unpacking clear payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("unpacking clear payload"); } }; | |||
2068 | passert(!md->message_payloads.parsed){ _Bool assertion__ = !md->message_payloads.parsed; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2068}, "%s", "!md->message_payloads.parsed" ); } }; | |||
2069 | pexpect(v2_msg_role(md) == MESSAGE_RESPONSE ||({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE || md->hdr.isa_xchg != ISAKMP_v2_IKE_SA_INIT; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2070}, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE || md->hdr.isa_xchg != ISAKMP_v2_IKE_SA_INIT" ); } assertion__; }) | |||
2070 | md->hdr.isa_xchg != ISAKMP_v2_IKE_SA_INIT)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE || md->hdr.isa_xchg != ISAKMP_v2_IKE_SA_INIT; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2070}, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE || md->hdr.isa_xchg != ISAKMP_v2_IKE_SA_INIT" ); } assertion__; }); | |||
2071 | md->message_payloads = | |||
2072 | ikev2_decode_payloads(st->st_logger, md, | |||
2073 | &md->message_pbs, | |||
2074 | md->hdr.isa_np); | |||
2075 | if (md->message_payloads.n != v2N_NOTHING_WRONG) { | |||
2076 | /* | |||
2077 | * Should only respond when the message is an | |||
2078 | * IKE_SA_INIT request. But that was handled above | |||
2079 | * when dealing with cookies so here, there's zero | |||
2080 | * reason to respond. | |||
2081 | * | |||
2082 | * decode calls packet code and that logs errors on | |||
2083 | * the spot | |||
2084 | */ | |||
2085 | /* already logged */ | |||
2086 | return; | |||
2087 | } | |||
2088 | ||||
2089 | ikev2_process_state_packet(ike, st, md); | |||
2090 | } | |||
2091 | ||||
2092 | /* | |||
2093 | * XXX: Hack to find the transition that would have been run if the | |||
2094 | * packet was ok, so it can be 'failed'. | |||
2095 | * | |||
2096 | * This is largely astetic. It could use the first transition but | |||
2097 | * often a later transition. Perhaps the last transition since, | |||
2098 | * presuably, that is the most generic? | |||
2099 | */ | |||
2100 | ||||
2101 | static void hack_error_transition(struct state *st) | |||
2102 | { | |||
2103 | const struct state_v2_microcode *transition; | |||
2104 | const struct finite_state *state = st->st_state; | |||
2105 | switch (state->kind) { | |||
2106 | case STATE_PARENT_R1: | |||
2107 | /* | |||
2108 | * Responding to IKE_AUTH request: it is the second | |||
2109 | * state because the first is the NOSKEYSEED | |||
2110 | * transition. Once SKEYSEED is off-loaded and | |||
2111 | * STATE_PARENT_I1 has only one transition, this is no | |||
2112 | * longer a hack. | |||
2113 | */ | |||
2114 | pexpect(state->nr_transitions == 2)({ _Bool assertion__ = state->nr_transitions == 2; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2114}, "%s", "state->nr_transitions == 2"); } assertion__ ; }); | |||
2115 | transition = &state->v2_transitions[1]; | |||
2116 | pexpect(transition->state == STATE_PARENT_R1 &&({ _Bool assertion__ = transition->state == STATE_PARENT_R1 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 2117}, "%s", "transition->state == STATE_PARENT_R1 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA" ); } assertion__; }) | |||
2117 | transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA)({ _Bool assertion__ = transition->state == STATE_PARENT_R1 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 2117}, "%s", "transition->state == STATE_PARENT_R1 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA" ); } assertion__; }); | |||
2118 | break; | |||
2119 | case STATE_PARENT_I2: | |||
2120 | /* | |||
2121 | * Receiving IKE_AUTH response: it is buried deep | |||
2122 | * down; would adding an extra transition that always | |||
2123 | * matches be better? | |||
2124 | */ | |||
2125 | pexpect(state->nr_transitions == 5)({ _Bool assertion__ = state->nr_transitions == 5; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2125}, "%s", "state->nr_transitions == 5"); } assertion__ ; }); | |||
2126 | transition = &state->v2_transitions[3]; | |||
2127 | pexpect(transition->state == STATE_PARENT_I2 &&({ _Bool assertion__ = transition->state == STATE_PARENT_I2 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 2128}, "%s", "transition->state == STATE_PARENT_I2 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA" ); } assertion__; }) | |||
2128 | transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA)({ _Bool assertion__ = transition->state == STATE_PARENT_I2 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 2128}, "%s", "transition->state == STATE_PARENT_I2 && transition->next_state == STATE_V2_ESTABLISHED_CHILD_SA" ); } assertion__; }); | |||
2129 | break; | |||
2130 | default: | |||
2131 | if (/*pexpect*/(state->nr_transitions > 0)) { | |||
2132 | transition = &state->v2_transitions[state->nr_transitions-1]; | |||
2133 | } else { | |||
2134 | static const struct state_v2_microcode undefined_transition = { | |||
2135 | .story = "suspect message", | |||
2136 | .state = STATE_UNDEFINED, | |||
2137 | .next_state = STATE_UNDEFINED, | |||
2138 | }; | |||
2139 | transition = &undefined_transition; | |||
2140 | } | |||
2141 | break; | |||
2142 | } | |||
2143 | /*pexpect(st->st_v2_transition == NULL);*/ | |||
2144 | st->st_v2_transition = transition; | |||
2145 | } | |||
2146 | ||||
2147 | /* | |||
2148 | * The SA the message is intended for has also been identified. | |||
2149 | * Continue ... | |||
2150 | * | |||
2151 | * XXX: Well except for a CREATE_CHILD_SA request where, after further | |||
2152 | * processing the SA may get created. Should this message instead be | |||
2153 | * sent to the IKE SA, which can then create a WIP child? | |||
2154 | */ | |||
2155 | ||||
2156 | void ikev2_process_state_packet(struct ike_sa *ike, struct state *st, | |||
2157 | struct msg_digest *md) | |||
2158 | { | |||
2159 | passert(ike != NULL){ _Bool assertion__ = ike != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2159}, "%s", "ike != NULL"); } }; | |||
2160 | passert(st != NULL){ _Bool assertion__ = st != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2160}, "%s", "st != NULL"); } }; | |||
2161 | ||||
2162 | /* | |||
2163 | * There is no "struct state" object if-and-only-if we're | |||
2164 | * responding to a shiny new SA_INIT message. The start-state | |||
2165 | * transition will (probably) create the object. | |||
2166 | * | |||
2167 | * But what about when pluto, as the initial responder, is | |||
2168 | * fending of an attack attack by sending back and requiring | |||
2169 | * cookies - won't the cookie need a "struct state"? | |||
2170 | * According to the RFC: no. Instead a small table of | |||
2171 | * constants can be used to generate cookies on the fly. | |||
2172 | */ | |||
2173 | const struct finite_state *from_state = st->st_state; | |||
2174 | dbg("#%lu in state %s: %s", st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu in state %s: %s", st->st_serialno, from_state ->short_name, from_state->story); } } | |||
2175 | from_state->short_name, from_state->story){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu in state %s: %s", st->st_serialno, from_state ->short_name, from_state->story); } }; | |||
2176 | ||||
2177 | struct ikev2_payload_errors message_payload_status = { .bad = false0 }; | |||
2178 | struct ikev2_payload_errors encrypted_payload_status = { .bad = false0 }; | |||
2179 | ||||
2180 | const enum isakmp_xchg_types ix = md->hdr.isa_xchg; | |||
2181 | ||||
2182 | /* | |||
2183 | * XXX: Unlike find_v2_state_transition(), the below scans | |||
2184 | * every single state transition and then, in the case of a | |||
2185 | * CREATE_CHILD_SA, ignores the "from" state. | |||
2186 | * | |||
2187 | * XXX: Unlike find_v2_state_transition(), this code detects | |||
2188 | * and decrypts packets and fragments in the middle of the | |||
2189 | * lookup. Being more aggressive with decrypting fragments | |||
2190 | * will likely force that logic to be moved to before this | |||
2191 | * lookup. | |||
2192 | */ | |||
2193 | ||||
2194 | const struct state_v2_microcode *svm; | |||
2195 | for (svm = v2_state_microcode_table; svm->state != STATE_IKEv2_ROOF; | |||
2196 | svm++) { | |||
2197 | /* | |||
2198 | * For CREATE_CHILD_SA exchanges, the from_state is | |||
2199 | * ignored. See further down. | |||
2200 | */ | |||
2201 | if (svm->state != from_state->kind && ix != ISAKMP_v2_CREATE_CHILD_SA) | |||
2202 | continue; | |||
2203 | if (svm->recv_type != ix) | |||
2204 | continue; | |||
2205 | ||||
2206 | /* | |||
2207 | * Does the message role match the state transition? | |||
2208 | */ | |||
2209 | if (svm->recv_role != v2_msg_role(md)) { | |||
2210 | continue; | |||
2211 | } | |||
2212 | ||||
2213 | /* | |||
2214 | * Check the message payloads are as expected. | |||
2215 | */ | |||
2216 | pexpect(md->message_payloads.parsed)({ _Bool assertion__ = md->message_payloads.parsed; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2216}, "%s", "md->message_payloads.parsed"); } assertion__ ; }); | |||
2217 | struct ikev2_payload_errors message_payload_errors | |||
2218 | = ikev2_verify_payloads(md, &md->message_payloads, | |||
2219 | &svm->message_payloads); | |||
2220 | if (message_payload_errors.bad) { | |||
2221 | /* Save this failure for later logging. */ | |||
2222 | message_payload_status = message_payload_errors; | |||
2223 | continue; | |||
2224 | } | |||
2225 | ||||
2226 | /* | |||
2227 | * If there is no SK (or SKF) payload then checking is | |||
2228 | * complete and things have matched. | |||
2229 | * | |||
2230 | * (.seen&(P(SK)|P(SKF))!=0 is equivalent. | |||
2231 | */ | |||
2232 | if (!(svm->message_payloads.required & P(SK)((lset_t)1 << (ISAKMP_NEXT_v2SK)))) { | |||
2233 | break; | |||
2234 | } | |||
2235 | ||||
2236 | /* | |||
2237 | * Since the encrypted payload appears plausible, deal | |||
2238 | * with fragmentation. | |||
2239 | */ | |||
2240 | if (!md->encrypted_payloads.parsed) { | |||
2241 | /* | |||
2242 | * Deal with fragmentation. The function | |||
2243 | * returns FALSE either when there are more | |||
2244 | * fragments, the fragment is corrupt, the | |||
2245 | * fragment is a duplicate, or the fragment | |||
2246 | * count changed (it also drops all | |||
2247 | * fragments). Either way stop processing. | |||
2248 | * | |||
2249 | * Only upon _first_ arrival of the last | |||
2250 | * fragment, does the function return TRUE. | |||
2251 | * The the processing flow below can then | |||
2252 | * continue to the SKEYSEED check. | |||
2253 | * | |||
2254 | * However, if SKEYSEED (g^{xy}) needed to be | |||
2255 | * computed then this code will be re-entered | |||
2256 | * with all fragments present (so "the" | |||
2257 | * function should not be called). | |||
2258 | */ | |||
2259 | struct v2_incomming_fragments *frags = | |||
2260 | st->st_v2_incomming[v2_msg_role(md)]; | |||
2261 | bool_Bool have_all_fragments = | |||
2262 | (frags != NULL((void*)0) && frags->count == frags->total); | |||
2263 | /* | |||
2264 | * XXX: Because fragments are only checked | |||
2265 | * all-at-once after they have all arrived, a | |||
2266 | * single corrupt fragment will cause all | |||
2267 | * fragments being thrown away, and the entire | |||
2268 | * process re-start (Is this tested?) | |||
2269 | * | |||
2270 | * XXX: This code should instead check | |||
2271 | * fragments as they arrive. That means | |||
2272 | * kicking off the g^{xy} calculation in the | |||
2273 | * background (if it were in the foreground, | |||
2274 | * the fragments would be dropped). Later. | |||
2275 | */ | |||
2276 | if (md->message_payloads.present & P(SKF)((lset_t)1 << (ISAKMP_NEXT_v2SKF))) { | |||
2277 | if (have_all_fragments) { | |||
2278 | dbg("already have all fragments, skipping fragment collection"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("already have all fragments, skipping fragment collection" ); } }; | |||
2279 | } else if (!ikev2_collect_fragment(md, st)) { | |||
2280 | return; | |||
2281 | } | |||
2282 | } | |||
2283 | /* | |||
2284 | * For this state transition, does it only | |||
2285 | * apply when there's no SKEYSEED? If so, and | |||
2286 | * SKEYSEED is missing, then things match; else | |||
2287 | * things can't match. | |||
2288 | */ | |||
2289 | if (svm->flags & SMF2_NO_SKEYSEED) { | |||
2290 | if (ike->sa.hidden_variables.st_skeyid_calculated) { | |||
2291 | continue; | |||
2292 | } else { | |||
2293 | break; | |||
2294 | } | |||
2295 | } | |||
2296 | /* | |||
2297 | * XXX: Shouldn't reach this point without | |||
2298 | * SKEYSEED so bail if somehow that hasn't | |||
2299 | * happened. No point in even calling | |||
2300 | * ikev2_decrypt_msg() (it will also fail). | |||
2301 | * | |||
2302 | * Suspect it would be cleaner if the state | |||
2303 | * machine included an explicit SMF2_SKEYSEED | |||
2304 | * flag and all states requiring integrity | |||
2305 | * were marked with that. Currently P(SK) and | |||
2306 | * P(SKF) imply this. | |||
2307 | */ | |||
2308 | if (!pexpect(ike->sa.hidden_variables.st_skeyid_calculated)({ _Bool assertion__ = ike->sa.hidden_variables.st_skeyid_calculated ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 2308}, "%s", "ike->sa.hidden_variables.st_skeyid_calculated" ); } assertion__; })) { | |||
2309 | return; | |||
2310 | } | |||
2311 | /* | |||
2312 | * Decrypt the packet, checking it for | |||
2313 | * integrity. Anything lacking integrity is | |||
2314 | * dropped. | |||
2315 | */ | |||
2316 | if (!ikev2_decrypt_msg(st, md)) { | |||
2317 | log_state(RC_LOG, st, "encrypted payload seems to be corrupt; dropping packet"); | |||
2318 | return; | |||
2319 | } | |||
2320 | /* | |||
2321 | * The message is protected - the integrity | |||
2322 | * check passed - so it was definitely sent by | |||
2323 | * the other end of the secured IKE SA. | |||
2324 | * | |||
2325 | * However, for an AUTH packet, the other end | |||
2326 | * hasn't yet been authenticated (and an | |||
2327 | * INFORMATIONAL exchange immediately | |||
2328 | * following AUTH be due to failed | |||
2329 | * authentication). | |||
2330 | * | |||
2331 | * If there's something wrong with the message | |||
2332 | * contents, then the IKE SA gets abandoned, | |||
2333 | * but a new new one may be initiated. | |||
2334 | * | |||
2335 | * See "2.21.2. Error Handling in IKE_AUTH" | |||
2336 | * and "2.21.3. Error Handling after IKE SA | |||
2337 | * is Authenticated". | |||
2338 | * | |||
2339 | * For UNSUPPORTED_CRITICAL_PAYLOAD, while the | |||
2340 | * RFC clearly states that for the initial | |||
2341 | * exchanges and an INFORMATIONAL exchange | |||
2342 | * immediately following, the notification | |||
2343 | * causes a delete, it says nothing for | |||
2344 | * exchanges that follow. | |||
2345 | * | |||
2346 | * For moment treat it the same. Given the | |||
2347 | * PAYLOAD ID that should identify the problem | |||
2348 | * isn't being returned this is the least of | |||
2349 | * our problems. | |||
2350 | */ | |||
2351 | struct payload_digest *sk = md->chain[ISAKMP_NEXT_v2SK]; | |||
2352 | md->encrypted_payloads = ikev2_decode_payloads(st->st_logger, md, &sk->pbs, | |||
2353 | sk->payload.generic.isag_np); | |||
2354 | if (md->encrypted_payloads.n != v2N_NOTHING_WRONG) { | |||
2355 | /* | |||
2356 | * XXX: Hack to get the | |||
2357 | * transition that would have | |||
2358 | * been run so it can be | |||
2359 | * 'failed'. | |||
2360 | */ | |||
2361 | hack_error_transition(st); | |||
2362 | switch (v2_msg_role(md)) { | |||
2363 | case MESSAGE_REQUEST: | |||
2364 | /* | |||
2365 | * Send back a protected error | |||
2366 | * response. Need to first | |||
2367 | * put the IKE SA into | |||
2368 | * responder mode. | |||
2369 | */ | |||
2370 | v2_msgid_start_responder(ike, st, md); | |||
2371 | chunk_t data = chunk2(md->encrypted_payloads.data, | |||
2372 | md->encrypted_payloads.data_size); | |||
2373 | record_v2N_response(st->st_logger, ike, md, | |||
2374 | md->encrypted_payloads.n, &data, | |||
2375 | ENCRYPTED_PAYLOAD); | |||
2376 | break; | |||
2377 | case MESSAGE_RESPONSE: | |||
2378 | /* | |||
2379 | * Can't respond so kill the | |||
2380 | * IKE SA. The secured | |||
2381 | * message contained crap so | |||
2382 | * there's little that can be | |||
2383 | * done. | |||
2384 | */ | |||
2385 | break; | |||
2386 | default: | |||
2387 | bad_case(v2_msg_role(md))libreswan_bad_case("v2_msg_role(md)", (v2_msg_role(md)), (where_t ) { .func = __func__, .basename = "ikev2.c" , .line = 2387}); | |||
2388 | } | |||
2389 | complete_v2_state_transition(st, md, STF_FATAL); | |||
2390 | return; | |||
2391 | } | |||
2392 | } /* else { go ahead } */ | |||
2393 | struct ikev2_payload_errors encrypted_payload_errors | |||
2394 | = ikev2_verify_payloads(md, &md->encrypted_payloads, | |||
2395 | &svm->encrypted_payloads); | |||
2396 | if (encrypted_payload_errors.bad) { | |||
2397 | /* Save this failure for later logging. */ | |||
2398 | encrypted_payload_status = encrypted_payload_errors; | |||
2399 | continue; | |||
2400 | } | |||
2401 | ||||
2402 | if (svm->state != from_state->kind && ix == ISAKMP_v2_CREATE_CHILD_SA) { | |||
2403 | /* | |||
2404 | * The IKE SA is receiving a CREATE_CHILD_SA | |||
2405 | * request. Unlike STATE_PARENT_R0 (and the | |||
2406 | * initial responder) the R0 state isn't | |||
2407 | * obvious - rekey IKE SA, rekey CHILD SA, and | |||
2408 | * create CHILD SA are all slightly different. | |||
2409 | * | |||
2410 | * The code deals with this by ignoring the | |||
2411 | * from_state, and then later, forcing MD's | |||
2412 | * from state to values in the table. | |||
2413 | */ | |||
2414 | dbg("state #%lu forced to match CREATE_CHILD_SA from %s->%s by ignoring from state",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu forced to match CREATE_CHILD_SA from %s->%s by ignoring from state" , st->st_serialno, finite_states[svm->state]->name, finite_states [svm->next_state]->name); } } | |||
2415 | st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu forced to match CREATE_CHILD_SA from %s->%s by ignoring from state" , st->st_serialno, finite_states[svm->state]->name, finite_states [svm->next_state]->name); } } | |||
2416 | finite_states[svm->state]->name,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu forced to match CREATE_CHILD_SA from %s->%s by ignoring from state" , st->st_serialno, finite_states[svm->state]->name, finite_states [svm->next_state]->name); } } | |||
2417 | finite_states[svm->next_state]->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu forced to match CREATE_CHILD_SA from %s->%s by ignoring from state" , st->st_serialno, finite_states[svm->state]->name, finite_states [svm->next_state]->name); } }; | |||
2418 | } | |||
2419 | ||||
2420 | /* must be the right state machine entry */ | |||
2421 | break; | |||
2422 | } | |||
2423 | ||||
2424 | dbg("selected state microcode %s", svm->story){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("selected state microcode %s", svm->story); } }; | |||
2425 | ||||
2426 | /* no useful state microcode entry? */ | |||
2427 | if (svm->state == STATE_IKEv2_ROOF) { | |||
2428 | /* count all the error notifications */ | |||
2429 | for (struct payload_digest *ntfy = md->chain[ISAKMP_NEXT_v2N]; | |||
2430 | ntfy != NULL((void*)0); ntfy = ntfy->next) { | |||
2431 | pstat(ikev2_recv_notifies_e, ntfy->payload.v2n.isan_type){ const unsigned pstat_ = (ntfy->payload.v2n.isan_type); 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]++; } }; | |||
2432 | } | |||
2433 | /* | |||
2434 | * All branches: log error, [complete transition] | |||
2435 | * (why), return so first error wins. | |||
2436 | */ | |||
2437 | if (message_payload_status.bad) { | |||
2438 | /* | |||
2439 | * A very messed up message - none of the | |||
2440 | * state transitions recognized it!. | |||
2441 | */ | |||
2442 | log_v2_payload_errors(st->st_logger, md, | |||
2443 | &message_payload_status); | |||
2444 | return; | |||
2445 | } | |||
2446 | if (encrypted_payload_status.bad) { | |||
2447 | /* | |||
2448 | * Payload decrypted and integrity was ok but | |||
2449 | * contents weren't valid. | |||
2450 | * | |||
2451 | * XXX: According to "2.21.2. Error Handling | |||
2452 | * in IKE_AUTH" and "2.21.3. Error Handling | |||
2453 | * after IKE SA is Authenticated" this should | |||
2454 | * be fatal, killing the IKE SA. Oops. | |||
2455 | * | |||
2456 | * XXX: how can one complete a state | |||
2457 | * transition on something that was never | |||
2458 | * started? Since this is fatal, the state | |||
2459 | * needs to be deleted. | |||
2460 | * | |||
2461 | * XXX: an alternative would be to treat this | |||
2462 | * like some new but as-of-yet not supported | |||
2463 | * message combination so just ignore it (but | |||
2464 | * update Message IDs). | |||
2465 | */ | |||
2466 | log_v2_payload_errors(st->st_logger, md, | |||
2467 | &encrypted_payload_status); | |||
2468 | /* | |||
2469 | * XXX: Hack to get the transition | |||
2470 | * that would have been run so it can | |||
2471 | * be 'failed'. | |||
2472 | */ | |||
2473 | hack_error_transition(st); | |||
2474 | switch (v2_msg_role(md)) { | |||
2475 | case MESSAGE_REQUEST: | |||
2476 | /* | |||
2477 | * Send back a protected error | |||
2478 | * response. Need to first put the | |||
2479 | * IKE SA into responder mode. | |||
2480 | */ | |||
2481 | v2_msgid_start_responder(ike, st, md); | |||
2482 | record_v2N_response(st->st_logger, ike, md, | |||
2483 | v2N_INVALID_SYNTAX, NULL((void*)0), | |||
2484 | ENCRYPTED_PAYLOAD); | |||
2485 | break; | |||
2486 | case MESSAGE_RESPONSE: | |||
2487 | /* | |||
2488 | * Can't respond so kill the IKE SA - | |||
2489 | * the secured message contained crap | |||
2490 | * so there's little that can be done. | |||
2491 | */ | |||
2492 | break; | |||
2493 | default: | |||
2494 | bad_case(v2_msg_role(md))libreswan_bad_case("v2_msg_role(md)", (v2_msg_role(md)), (where_t ) { .func = __func__, .basename = "ikev2.c" , .line = 2494}); | |||
2495 | } | |||
2496 | /* XXX: calls delete_state() */ | |||
2497 | complete_v2_state_transition(st, md, STF_FATAL); | |||
2498 | return; | |||
2499 | } | |||
2500 | /* | |||
2501 | * Presumably things are pretty messed up. While | |||
2502 | * there might be a state there probably isn't an | |||
2503 | * established IKE SA (so don't even consider trying | |||
2504 | * to send an encrypted response), for instance: | |||
2505 | * | |||
2506 | * - instead of an IKE_AUTH request, the initiator | |||
2507 | * sends something totally unexpected (such as an | |||
2508 | * informational) and things end up here | |||
2509 | * | |||
2510 | * - when an IKE_AUTH request's IKE SA succeeeds but | |||
2511 | * CHILD SA fails (and pluto screws up the IKE SA by | |||
2512 | * updating its state but not its Message ID and not | |||
2513 | * responding), the re-transmitted IKE_AUTH ends up | |||
2514 | * here | |||
2515 | * | |||
2516 | * If a request, should it send an un-encrypted | |||
2517 | * v2N_INVALID_SYNTAX? | |||
2518 | */ | |||
2519 | libreswan_log("no useful state microcode entry found for incoming packet")loglog(RC_LOG, "no useful state microcode entry found for incoming packet" ); | |||
2520 | /* "dropping message with no matching microcode" */ | |||
2521 | return; | |||
2522 | } | |||
2523 | ||||
2524 | if (ix == ISAKMP_v2_CREATE_CHILD_SA) { | |||
2525 | /* | |||
2526 | * XXX: This code was embedded in the end of the FSM | |||
2527 | * search loop. Since it was always executed when the | |||
2528 | * state matches, move it out of the loop. Suspect | |||
2529 | * this, and the code below, really belong in the | |||
2530 | * state transition function proper. | |||
2531 | */ | |||
2532 | /* going to switch to child st. before that update parent */ | |||
2533 | 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))) | |||
2534 | update_ike_endpoints(ike, md); | |||
2535 | ||||
2536 | /* bit further processing of create CREATE_CHILD_SA exchange */ | |||
2537 | ||||
2538 | /* | |||
2539 | * let's get a child state either new or existing to | |||
2540 | * proceed | |||
2541 | */ | |||
2542 | struct child_sa *child; | |||
2543 | if (v2_msg_role(md) == MESSAGE_RESPONSE) { | |||
2544 | child = pexpect_child_sa(st); | |||
2545 | } else { | |||
2546 | pexpect(IS_IKE_SA(st))({ _Bool assertion__ = ((st)->st_clonedfrom == 0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2546}, "%s", "IS_IKE_SA(st)"); } assertion__; }); | |||
2547 | child = process_v2_child_ix(ike, svm); | |||
2548 | } | |||
2549 | ||||
2550 | /* | |||
2551 | * Switch to child state (possibly from the same child | |||
2552 | * state, see above) | |||
2553 | */ | |||
2554 | dbg("forcing ST #%lu to CHILD #%lu.#%lu in FSM processor",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("forcing ST #%lu to CHILD #%lu.#%lu in FSM processor" , st->st_serialno, ike->sa.st_serialno, child->sa.st_serialno ); } } | |||
2555 | st->st_serialno, ike->sa.st_serialno, child->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("forcing ST #%lu to CHILD #%lu.#%lu in FSM processor" , st->st_serialno, ike->sa.st_serialno, child->sa.st_serialno ); } }; | |||
2556 | st = &child->sa; | |||
2557 | } | |||
2558 | ||||
2559 | v2_dispatch(ike, st, md, svm); | |||
2560 | } | |||
2561 | ||||
2562 | static void v2_dispatch(struct ike_sa *ike, struct state *st, | |||
2563 | struct msg_digest *md, | |||
2564 | const struct state_v2_microcode *svm) | |||
2565 | { | |||
2566 | md->st = st; | |||
2567 | md->svm = svm; | |||
2568 | ||||
2569 | /* | |||
2570 | * For the responder, update the work-in-progress Message ID | |||
2571 | * window (since work has commenced). | |||
2572 | * | |||
2573 | * Exclude the SKEYSEED calculation - the message has yet to | |||
2574 | * be decrypted so true work on the message is yet to comence. | |||
2575 | */ | |||
2576 | if (v2_msg_role(md) == MESSAGE_REQUEST && | |||
2577 | !(svm->flags & SMF2_NO_SKEYSEED)) { | |||
2578 | v2_msgid_start_responder(ike, st, md); | |||
2579 | } | |||
2580 | ||||
2581 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
2582 | if (pbs_left(&md->message_pbs)((size_t)((&md->message_pbs)->roof - (&md->message_pbs )->cur)) != 0) | |||
2583 | DBG_log("removing %d bytes of padding", | |||
2584 | (int) pbs_left(&md->message_pbs)((size_t)((&md->message_pbs)->roof - (&md->message_pbs )->cur))); | |||
2585 | } | |||
2586 | ||||
2587 | md->message_pbs.roof = md->message_pbs.cur; /* trim padding (not actually legit) */ | |||
2588 | ||||
2589 | dbg("calling processor %s", svm->story){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("calling processor %s", svm->story); } }; | |||
2590 | ||||
2591 | /* | |||
2592 | * XXX: for now pass in the possibly NULL child; suspect a | |||
2593 | * better model is to drop the child and instead have the IKE | |||
2594 | * SA run a nested state machine for the child. | |||
2595 | * | |||
2596 | * For instance, when a CREATE_CHILD_SA request arrives, pass | |||
2597 | * that to the IKE SA and then let it do all the create child | |||
2598 | * magic. | |||
2599 | */ | |||
2600 | statetime_t start = statetime_start(st); | |||
2601 | so_serial_t old_st = st->st_serialno; | |||
2602 | so_serial_t old_md_st = md != NULL((void*)0) && md->st != NULL((void*)0) ? md->st->st_serialno : SOS_NOBODY0; | |||
2603 | struct child_sa *child = IS_CHILD_SA(st)((st)->st_clonedfrom != 0) ? pexpect_child_sa(st) : NULL((void*)0); | |||
2604 | stf_status e = svm->processor(ike, child, md); | |||
2605 | statetime_stop(&start, "processing: %s in %s()", svm->story, __func__); | |||
2606 | ||||
2607 | /* | |||
2608 | * Processor may screw around with md->st, for instance | |||
2609 | * switching it to the CHILD SA, or a newly created state. | |||
2610 | * Hence use that version for now. | |||
2611 | */ | |||
2612 | ||||
2613 | if (e == STF_SKIP_COMPLETE_STATE_TRANSITION) { | |||
2614 | /* MD.ST may have been freed! */ | |||
2615 | dbg("processor '%s' for #%lu suppresed complete st_v2_transition%s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processor '%s' for #%lu suppresed complete st_v2_transition%s" , svm->story, st->st_serialno, (old_md_st != 0 && md->st == ((void*)0) ? "; MD.ST disappeared" : old_md_st != 0 && md->st != st ? "; MD.ST was switched" : "")) ; } } | |||
2616 | svm->story, st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processor '%s' for #%lu suppresed complete st_v2_transition%s" , svm->story, st->st_serialno, (old_md_st != 0 && md->st == ((void*)0) ? "; MD.ST disappeared" : old_md_st != 0 && md->st != st ? "; MD.ST was switched" : "")) ; } } | |||
2617 | (old_md_st != SOS_NOBODY && md->st == NULL ? "; MD.ST disappeared" :{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processor '%s' for #%lu suppresed complete st_v2_transition%s" , svm->story, st->st_serialno, (old_md_st != 0 && md->st == ((void*)0) ? "; MD.ST disappeared" : old_md_st != 0 && md->st != st ? "; MD.ST was switched" : "")) ; } } | |||
2618 | old_md_st != SOS_NOBODY && md->st != st ? "; MD.ST was switched" :{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processor '%s' for #%lu suppresed complete st_v2_transition%s" , svm->story, st->st_serialno, (old_md_st != 0 && md->st == ((void*)0) ? "; MD.ST disappeared" : old_md_st != 0 && md->st != st ? "; MD.ST was switched" : "")) ; } } | |||
2619 | "")){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("processor '%s' for #%lu suppresed complete st_v2_transition%s" , svm->story, st->st_serialno, (old_md_st != 0 && md->st == ((void*)0) ? "; MD.ST disappeared" : old_md_st != 0 && md->st != st ? "; MD.ST was switched" : "")) ; } }; | |||
2620 | return; | |||
2621 | } | |||
2622 | ||||
2623 | if (md->st == NULL((void*)0)) { | |||
2624 | if (old_md_st != SOS_NOBODY0) { | |||
2625 | /* MD.ST may have been freed! */ | |||
2626 | dbg("XXX: processor '%s' for #%lu deleted state MD.ST",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XXX: processor '%s' for #%lu deleted state MD.ST" , svm->story, old_st); } } | |||
2627 | svm->story, old_st){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XXX: processor '%s' for #%lu deleted state MD.ST" , svm->story, old_st); } }; | |||
2628 | return; | |||
2629 | } | |||
2630 | } else { | |||
2631 | if (md->st->st_serialno != old_st) { | |||
2632 | /* MD.ST may have been freed! */ | |||
2633 | dbg("XXX: processor '%s' for #%lu switched state to #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XXX: processor '%s' for #%lu switched state to #%lu" , svm->story, old_st, md->st->st_serialno); } } | |||
2634 | svm->story, old_st, md->st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XXX: processor '%s' for #%lu switched state to #%lu" , svm->story, old_st, md->st->st_serialno); } }; | |||
2635 | st = md->st; | |||
2636 | } | |||
2637 | } | |||
2638 | ||||
2639 | complete_v2_state_transition(st, md, e); | |||
2640 | /* our caller with release_any_md(mdp) */ | |||
2641 | } | |||
2642 | ||||
2643 | static bool_Bool decode_peer_id_counted(struct ike_sa *ike, | |||
2644 | struct msg_digest *md, int depth) | |||
2645 | { | |||
2646 | if (depth > 10) { | |||
2647 | /* should not happen, but it would be nice to survive */ | |||
2648 | libreswan_log("decoding IKEv2 peer ID failed due to confusion")loglog(RC_LOG, "decoding IKEv2 peer ID failed due to confusion" ); | |||
2649 | return FALSE0; | |||
2650 | } | |||
2651 | bool_Bool initiator = (md->hdr.isa_flags & ISAKMP_FLAGS_v2_MSG_R(1 << 5)) != 0; | |||
2652 | bool_Bool must_switch = FALSE0; | |||
2653 | ||||
2654 | struct payload_digest *const id_peer = initiator ? | |||
2655 | md->chain[ISAKMP_NEXT_v2IDr] : md->chain[ISAKMP_NEXT_v2IDi]; | |||
2656 | ||||
2657 | if (id_peer == NULL((void*)0)) { | |||
2658 | libreswan_log("IKEv2 mode no peer ID")loglog(RC_LOG, "IKEv2 mode no peer ID"); | |||
2659 | return FALSE0; | |||
2660 | } | |||
2661 | ||||
2662 | enum ike_id_type hik = id_peer->payload.v2id.isai_type; /* Peers Id Kind */ | |||
2663 | ||||
2664 | struct id peer_id; | |||
2665 | ||||
2666 | if (!extract_peer_id(hik, &peer_id, &id_peer->pbs)) { | |||
2667 | libreswan_log("IKEv2 mode peer ID extraction failed")loglog(RC_LOG, "IKEv2 mode peer ID extraction failed"); | |||
2668 | return FALSE0; | |||
2669 | } | |||
2670 | ||||
2671 | /* You Tarzan, me Jane? */ | |||
2672 | struct id tarzan_id; /* may be unset */ | |||
2673 | struct id *tip = NULL((void*)0); /* tarzan ID pointer (or NULL) */ | |||
2674 | ||||
2675 | { | |||
2676 | const struct payload_digest *const tarzan_pld = md->chain[ISAKMP_NEXT_v2IDr]; | |||
2677 | ||||
2678 | if (!initiator && tarzan_pld != NULL((void*)0)) { | |||
2679 | /* | |||
2680 | * ??? problem with diagnostics: what we're calling "peer ID" | |||
2681 | * is really our "peer's peer ID", in other words us! | |||
2682 | */ | |||
2683 | dbg("received IDr payload - extracting our alleged ID"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received IDr payload - extracting our alleged ID" ); } }; | |||
2684 | if (!extract_peer_id(tarzan_pld->payload.v2id.isai_type, | |||
2685 | &tarzan_id, &tarzan_pld->pbs)) | |||
2686 | { | |||
2687 | libreswan_log("Peer IDr payload extraction failed")loglog(RC_LOG, "Peer IDr payload extraction failed"); | |||
2688 | return FALSE0; | |||
2689 | } | |||
2690 | tip = &tarzan_id; | |||
2691 | } | |||
2692 | } | |||
2693 | ||||
2694 | /* start considering connection */ | |||
2695 | ||||
2696 | struct connection *c = ike->sa.st_connection; | |||
2697 | ||||
2698 | /* | |||
2699 | * If there are certs, try re-running the id check. | |||
2700 | */ | |||
2701 | if (!ike->sa.st_peer_alt_id && | |||
2702 | ike->sa.st_remote_certs.verified != NULL((void*)0)) { | |||
2703 | if (match_certs_id(ike->sa.st_remote_certs.verified, | |||
2704 | &c->spd.that.id /*ID_FROMCERT => updated*/, | |||
2705 | ike->sa.st_logger)) { | |||
2706 | dbg("X509: CERT and ID matches current connection"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("X509: CERT and ID matches current connection" ); } }; | |||
2707 | ike->sa.st_peer_alt_id = true1; | |||
2708 | } else { | |||
2709 | log_state(RC_LOG, &ike->sa, "Peer CERT payload SubjectAltName does not match peer ID for this connection"); | |||
2710 | if (!LIN(POLICY_ALLOW_NO_SAN, c->policy)(((((lset_t)1 << (POLICY_ALLOW_NO_SAN_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_ALLOW_NO_SAN_IX))))) { | |||
2711 | log_state(RC_LOG, &ike->sa, "X509: connection failed due to unmatched IKE ID in certificate SAN"); | |||
2712 | if (initiator) | |||
2713 | return FALSE0; /* cannot switch but switching required */ | |||
2714 | must_switch = TRUE1; | |||
2715 | } else { | |||
2716 | log_state(RC_LOG, &ike->sa, "X509: connection allows unmatched IKE ID and certificate SAN"); | |||
2717 | } | |||
2718 | } | |||
2719 | } | |||
2720 | ||||
2721 | /* process any CERTREQ payloads */ | |||
2722 | ikev2_decode_cr(md); | |||
2723 | ||||
2724 | /* | |||
2725 | * Now that we've decoded the ID payload, let's see if we | |||
2726 | * need to switch connections. | |||
2727 | * We must not switch horses if we initiated: | |||
2728 | * - if the initiation was explicit, we'd be ignoring user's intent | |||
2729 | * - if opportunistic, we'll lose our HOLD info | |||
2730 | */ | |||
2731 | if (initiator) { | |||
2732 | if (!ike->sa.st_peer_alt_id && | |||
2733 | !same_id(&c->spd.that.id, &peer_id) && | |||
2734 | c->spd.that.id.kind != ID_FROMCERT) { | |||
2735 | id_buf expect, found; | |||
2736 | ||||
2737 | loglog(RC_LOG_SERIOUS, | |||
2738 | "we require IKEv2 peer to have ID '%s', but peer declares '%s'", | |||
2739 | str_id(&c->spd.that.id, &expect), | |||
2740 | str_id(&peer_id, &found)); | |||
2741 | return FALSE0; | |||
2742 | } else if (c->spd.that.id.kind == ID_FROMCERT) { | |||
2743 | if (peer_id.kind != ID_DER_ASN1_DN) { | |||
2744 | loglog(RC_LOG_SERIOUS, "peer ID is not a certificate type"); | |||
2745 | return FALSE0; | |||
2746 | } | |||
2747 | duplicate_id(&c->spd.that.id, &peer_id); | |||
2748 | } | |||
2749 | } else { | |||
2750 | /* why should refine_host_connection() update this? We pulled it from their packet */ | |||
2751 | bool_Bool fromcert = peer_id.kind == ID_DER_ASN1_DN; | |||
2752 | uint16_t auth = md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method; | |||
2753 | enum keyword_authby authby = AUTHBY_NEVER; | |||
2754 | ||||
2755 | switch (auth) { | |||
2756 | case IKEv2_AUTH_RSA: | |||
2757 | authby = AUTHBY_RSASIG; | |||
2758 | break; | |||
2759 | case IKEv2_AUTH_PSK: | |||
2760 | authby = AUTHBY_PSK; | |||
2761 | break; | |||
2762 | case IKEv2_AUTH_NULL: | |||
2763 | authby = AUTHBY_NULL; | |||
2764 | break; | |||
2765 | case IKEv2_AUTH_DIGSIG: | |||
2766 | if (c->policy & POLICY_RSASIG((lset_t)1 << (POLICY_RSASIG_IX))) { | |||
2767 | authby = AUTHBY_RSASIG; | |||
2768 | break; | |||
2769 | } | |||
2770 | if (c->policy & POLICY_ECDSA((lset_t)1 << (POLICY_ECDSA_IX))) { | |||
2771 | authby = AUTHBY_ECDSA; | |||
2772 | break; | |||
2773 | } | |||
2774 | /* FALL THROUGH */ | |||
2775 | case IKEv2_AUTH_NONE: | |||
2776 | default: | |||
2777 | dbg("ikev2 skipping refine_host_connection due to unknown policy"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2 skipping refine_host_connection due to unknown policy" ); } }; | |||
2778 | } | |||
2779 | ||||
2780 | if (authby != AUTHBY_NEVER) { | |||
2781 | struct connection *r = NULL((void*)0); | |||
2782 | id_buf peer_str; | |||
2783 | ||||
2784 | if (authby != AUTHBY_NULL) { | |||
2785 | r = refine_host_connection( | |||
2786 | md->st, &peer_id, tip, FALSE0 /*initiator*/, | |||
2787 | LEMPTY((lset_t)0) /* auth_policy */, authby, &fromcert); | |||
2788 | } | |||
2789 | ||||
2790 | if (r == NULL((void*)0)) { | |||
2791 | /* no "improvement" on c found */ | |||
2792 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
2793 | id_buf peer_str; | |||
2794 | DBG_log("no suitable connection for peer '%s'", | |||
2795 | str_id(&peer_id, &peer_str)); | |||
2796 | } | |||
2797 | /* can we continue with what we had? */ | |||
2798 | if (must_switch) { | |||
2799 | loglog(RC_LOG_SERIOUS, "Peer ID '%s' is not specified on the certificate SubjectAltName (SAN) and no better connection found", | |||
2800 | str_id(&peer_id, &peer_str)); | |||
2801 | return FALSE0; | |||
2802 | } | |||
2803 | /* if X.509, we should have valid peer/san */ | |||
2804 | if (ike->sa.st_remote_certs.verified != NULL((void*)0) && ike->sa.st_peer_alt_id == FALSE0) { | |||
2805 | loglog(RC_LOG_SERIOUS, "Peer ID '%s' is not specified on the certificate SubjectAltName (SAN) and no better connection found", | |||
2806 | str_id(&peer_id, &peer_str)); | |||
2807 | return FALSE0; | |||
2808 | } | |||
2809 | if (!ike->sa.st_peer_alt_id && | |||
2810 | !same_id(&c->spd.that.id, &peer_id) && | |||
2811 | c->spd.that.id.kind != ID_FROMCERT) | |||
2812 | { | |||
2813 | if (LIN(POLICY_AUTH_NULL, c->policy)(((((lset_t)1 << (POLICY_AUTH_NULL_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_AUTH_NULL_IX)))) && | |||
2814 | tip != NULL((void*)0) && tip->kind == ID_NULL) { | |||
2815 | libreswan_log("Peer ID '%s' expects us to have ID_NULL and connection allows AUTH_NULL - allowing",loglog(RC_LOG, "Peer ID '%s' expects us to have ID_NULL and connection allows AUTH_NULL - allowing" , str_id(&peer_id, &peer_str)) | |||
2816 | str_id(&peer_id, &peer_str))loglog(RC_LOG, "Peer ID '%s' expects us to have ID_NULL and connection allows AUTH_NULL - allowing" , str_id(&peer_id, &peer_str)); | |||
2817 | ike->sa.st_peer_wants_null = TRUE1; | |||
2818 | } else { | |||
2819 | id_buf peer_str; | |||
2820 | loglog(RC_LOG_SERIOUS, "Peer ID '%s' mismatched on first found connection and no better connection found", | |||
2821 | str_id(&peer_id, &peer_str)); | |||
2822 | return FALSE0; | |||
2823 | } | |||
2824 | } else { | |||
2825 | dbg("peer ID matches and no better connection found - continuing with existing connection"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("peer ID matches and no better connection found - continuing with existing connection" ); } }; | |||
2826 | } | |||
2827 | } else if (r != c) { | |||
2828 | /* r is an improvement on c -- replace */ | |||
2829 | ||||
2830 | char b1[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)]; | |||
2831 | char b2[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)]; | |||
2832 | ||||
2833 | libreswan_log("switched from \"%s\"%s to \"%s\"%s",loglog(RC_LOG, "switched from \"%s\"%s to \"%s\"%s", c->name , fmt_conn_instance(c, b1), r->name, fmt_conn_instance(r, b2 )) | |||
2834 | c->name,loglog(RC_LOG, "switched from \"%s\"%s to \"%s\"%s", c->name , fmt_conn_instance(c, b1), r->name, fmt_conn_instance(r, b2 )) | |||
2835 | fmt_conn_instance(c, b1),loglog(RC_LOG, "switched from \"%s\"%s to \"%s\"%s", c->name , fmt_conn_instance(c, b1), r->name, fmt_conn_instance(r, b2 )) | |||
2836 | r->name,loglog(RC_LOG, "switched from \"%s\"%s to \"%s\"%s", c->name , fmt_conn_instance(c, b1), r->name, fmt_conn_instance(r, b2 )) | |||
2837 | fmt_conn_instance(r, b2))loglog(RC_LOG, "switched from \"%s\"%s to \"%s\"%s", c->name , fmt_conn_instance(c, b1), r->name, fmt_conn_instance(r, b2 )); | |||
2838 | if (r->kind == CK_TEMPLATE || r->kind == CK_GROUP) { | |||
2839 | /* instantiate it, filling in peer's ID */ | |||
2840 | r = rw_instantiate(r, &c->spd.that.host_addr, | |||
2841 | NULL((void*)0), &peer_id); | |||
2842 | } | |||
2843 | ||||
2844 | update_state_connection(md->st, r); | |||
2845 | /* redo from scratch so we read and check CERT payload */ | |||
2846 | dbg("retrying ikev2_decode_peer_id_and_certs() with new conn"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("retrying ikev2_decode_peer_id_and_certs() with new conn" ); } }; | |||
2847 | return decode_peer_id_counted(ike, md, depth + 1); | |||
2848 | } else if (must_switch) { | |||
2849 | id_buf peer_str; | |||
2850 | loglog(RC_LOG_SERIOUS, "Peer ID '%s' mismatched on first found connection and no better connection found", | |||
2851 | str_id(&peer_id, &peer_str)); | |||
2852 | return FALSE0; | |||
2853 | } | |||
2854 | ||||
2855 | if (c->spd.that.has_id_wildcards) { | |||
2856 | duplicate_id(&c->spd.that.id, &peer_id); | |||
2857 | c->spd.that.has_id_wildcards = FALSE0; | |||
2858 | } else if (fromcert) { | |||
2859 | dbg("copying ID for fromcert"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("copying ID for fromcert"); } }; | |||
2860 | duplicate_id(&c->spd.that.id, &peer_id); | |||
2861 | } | |||
2862 | } | |||
2863 | } | |||
2864 | ||||
2865 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
2866 | dn_buf b; | |||
2867 | DBG_log("offered CA: '%s'", | |||
2868 | str_dn_or_null(c->spd.this.ca, "%none", &b)); | |||
2869 | } | |||
2870 | ||||
2871 | if (!(c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))) { | |||
2872 | id_buf idbuf; | |||
2873 | libreswan_log("IKEv2 mode peer ID is %s: '%s'",loglog(RC_LOG, "IKEv2 mode peer ID is %s: '%s'", enum_show(& ikev2_idtype_names, hik), str_id(&peer_id, &idbuf)) | |||
2874 | enum_show(&ikev2_idtype_names, hik),loglog(RC_LOG, "IKEv2 mode peer ID is %s: '%s'", enum_show(& ikev2_idtype_names, hik), str_id(&peer_id, &idbuf)) | |||
2875 | str_id(&peer_id, &idbuf))loglog(RC_LOG, "IKEv2 mode peer ID is %s: '%s'", enum_show(& ikev2_idtype_names, hik), str_id(&peer_id, &idbuf)); | |||
2876 | } else if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
2877 | id_buf idbuf; | |||
2878 | DBG_log("IKEv2 mode peer ID is %s: '%s'", | |||
2879 | enum_show(&ikev2_idtype_names, hik), | |||
2880 | str_id(&peer_id, &idbuf)); | |||
2881 | } | |||
2882 | ||||
2883 | return TRUE1; | |||
2884 | } | |||
2885 | ||||
2886 | bool_Bool ikev2_decode_peer_id(struct msg_digest *md) | |||
2887 | { | |||
2888 | return decode_peer_id_counted(ike_sa(md->st, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 2888}), md, 0); | |||
2889 | } | |||
2890 | ||||
2891 | /* | |||
2892 | * This logs to the main log (including peerlog!) the authentication | |||
2893 | * and encryption keys for an IKEv2 SA. This is done in a format that | |||
2894 | * is compatible with tcpdump 4.0's -E option. | |||
2895 | * | |||
2896 | * The peerlog will be perfect. The syslog will require that a cut | |||
2897 | * command is used to remove the initial text. | |||
2898 | * DANGER: this intentionally leaks cryptographic secrets. | |||
2899 | */ | |||
2900 | void ikev2_log_parentSA(const struct state *st) | |||
2901 | { | |||
2902 | DBG(DBG_PRIVATE,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2903 | {{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2904 | if (st->st_oakley.ta_integ == NULL ||{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2905 | st->st_oakley.ta_encrypt == NULL){ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2906 | return;{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2907 | ||||
2908 | /* format initiator SPI */{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2909 | char tispi[3 + 2*IKE_SA_SPI_SIZE];{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2910 | (void)datatot(st->st_ike_spis.initiator.bytes, sizeof(st->st_ike_spis.initiator.bytes),{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2911 | 'x',{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2912 | tispi, sizeof(tispi));{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2913 | ||||
2914 | /* format responder SPI */{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2915 | char trspi[3 + 2*IKE_SA_SPI_SIZE];{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2916 | (void)datatot(st->st_ike_spis.responder.bytes, sizeof(st->st_ike_spis.responder.bytes),{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2917 | 'x',{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2918 | trspi, sizeof(trspi));{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2919 | ||||
2920 | const char *authalgo = st->st_oakley.ta_integ->integ_tcpdump_name;{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2921 | const char *encalgo = st->st_oakley.ta_encrypt->encrypt_tcpdump_name;{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2922 | ||||
2923 | /*{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2924 | * Text of encryption key length (suffix for encalgo).{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2925 | * No more than 3 digits, but compiler fears it might be 5.{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2926 | */{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2927 | char tekl[6] = "";{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2928 | if (st->st_oakley.enckeylen != 0){ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2929 | snprintf(tekl, sizeof(tekl), "%u",{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2930 | st->st_oakley.enckeylen);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2931 | ||||
2932 | /* v2 IKE authentication key for initiator (256 bit bound) */{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2933 | chunk_t ai = chunk_from_symkey("ai", st->st_skey_ai_nss,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2934 | st->st_logger);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2935 | char tai[3 + 2 * BYTES_FOR_BITS(256)] = "";{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2936 | (void)datatot(ai.ptr, ai.len, 'x', tai, sizeof(tai));{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2937 | free_chunk_content(&ai);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2938 | ||||
2939 | /* v2 IKE encryption key for initiator (256 bit bound) */{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2940 | chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2941 | st->st_logger);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2942 | char tei[3 + 2 * BYTES_FOR_BITS(256)] = "";{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2943 | (void)datatot(ei.ptr, ei.len, 'x', tei, sizeof(tei));{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2944 | free_chunk_content(&ei);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2945 | ||||
2946 | DBG_log("ikev2 I %s %s %s:%s %s%s:%s",{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2947 | tispi, trspi,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2948 | authalgo, tai,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2949 | encalgo, tekl, tei);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2950 | ||||
2951 | /* v2 IKE authentication key for responder (256 bit bound) */{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2952 | chunk_t ar = chunk_from_symkey("ar", st->st_skey_ar_nss,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2953 | st->st_logger);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2954 | char tar[3 + 2 * BYTES_FOR_BITS(256)] = "";{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2955 | (void)datatot(ar.ptr, ar.len, 'x', tar, sizeof(tar));{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2956 | free_chunk_content(&ar);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2957 | ||||
2958 | /* v2 IKE encryption key for responder (256 bit bound) */{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2959 | chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2960 | st->st_logger);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2961 | char ter[3 + 2 * BYTES_FOR_BITS(256)] = "";{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2962 | (void)datatot(er.ptr, er.len, 'x', ter, sizeof(ter));{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2963 | free_chunk_content(&er);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2964 | ||||
2965 | DBG_log("ikev2 R %s %s %s:%s %s%s:%s",{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2966 | tispi, trspi,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2967 | authalgo, tar,{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2968 | encalgo, tekl, ter);{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2969 | }{ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } } | |||
2970 | ){ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX ))))) { { if (st->st_oakley.ta_integ == ((void*)0) || st-> st_oakley.ta_encrypt == ((void*)0)) return; char tispi[3 + 2* 8]; (void)datatot(st->st_ike_spis.initiator.bytes, sizeof( st->st_ike_spis.initiator.bytes), 'x', tispi, sizeof(tispi )); char trspi[3 + 2*8]; (void)datatot(st->st_ike_spis.responder .bytes, sizeof(st->st_ike_spis.responder.bytes), 'x', trspi , sizeof(trspi)); const char *authalgo = st->st_oakley.ta_integ ->integ_tcpdump_name; const char *encalgo = st->st_oakley .ta_encrypt->encrypt_tcpdump_name; char tekl[6] = ""; if ( st->st_oakley.enckeylen != 0) snprintf(tekl, sizeof(tekl), "%u", st->st_oakley.enckeylen); chunk_t ai = chunk_from_symkey ("ai", st->st_skey_ai_nss, st->st_logger); char tai[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot(ai.ptr, ai.len , 'x', tai, sizeof(tai)); free_chunk_content(&ai); chunk_t ei = chunk_from_symkey("ei", st->st_skey_ei_nss, st->st_logger ); char tei[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (ei.ptr, ei.len, 'x', tei, sizeof(tei)); free_chunk_content(& ei); DBG_log("ikev2 I %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tai, encalgo, tekl, tei); chunk_t ar = chunk_from_symkey("ar" , st->st_skey_ar_nss, st->st_logger); char tar[3 + 2 * ( ((256) + 8 - 1) / 8)] = ""; (void)datatot(ar.ptr, ar.len, 'x' , tar, sizeof(tar)); free_chunk_content(&ar); chunk_t er = chunk_from_symkey("er", st->st_skey_er_nss, st->st_logger ); char ter[3 + 2 * (((256) + 8 - 1) / 8)] = ""; (void)datatot (er.ptr, er.len, 'x', ter, sizeof(ter)); free_chunk_content(& er); DBG_log("ikev2 R %s %s %s:%s %s%s:%s", tispi, trspi, authalgo , tar, encalgo, tekl, ter); }; } }; | |||
2971 | } | |||
2972 | ||||
2973 | void log_ipsec_sa_established(const char *m, const struct state *st) | |||
2974 | { | |||
2975 | /* log Child SA Traffic Selector details for admin's pleasure */ | |||
2976 | const struct traffic_selector *a = &st->st_ts_this; | |||
2977 | const struct traffic_selector *b = &st->st_ts_that; | |||
2978 | range_buf ba, bb; | |||
2979 | libreswan_log("%s [%s:%d-%d %d] -> [%s:%d-%d %d]",loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2980 | m,loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2981 | str_range(&a->net, &ba),loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2982 | a->startport,loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2983 | a->endport,loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2984 | a->ipprotoid,loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2985 | str_range(&b->net, &bb),loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2986 | b->startport,loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2987 | b->endport,loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid) | |||
2988 | b->ipprotoid)loglog(RC_LOG, "%s [%s:%d-%d %d] -> [%s:%d-%d %d]", m, str_range (&a->net, &ba), a->startport, a->endport, a-> ipprotoid, str_range(&b->net, &bb), b->startport , b->endport, b->ipprotoid); | |||
2989 | } | |||
2990 | ||||
2991 | static void ikev2_child_emancipate(struct ike_sa *from, struct child_sa *to, | |||
2992 | const struct state_v2_microcode *transition) | |||
2993 | { | |||
2994 | /* initialize the the new IKE SA. reset and message ID */ | |||
2995 | to->sa.st_clonedfrom = SOS_NOBODY0; | |||
2996 | v2_msgid_init_ike(pexpect_ike_sa(&to->sa)); | |||
2997 | ||||
2998 | /* Switch to the new IKE SPIs */ | |||
2999 | to->sa.st_ike_spis = to->sa.st_ike_rekey_spis; | |||
3000 | rehash_state_cookies_in_db(&to->sa); | |||
3001 | ||||
3002 | /* TO has correct IKE_SPI so can migrate */ | |||
3003 | v2_migrate_children(from, to); | |||
3004 | ||||
3005 | /* child is now a parent */ | |||
3006 | ikev2_ike_sa_established(pexpect_ike_sa(&to->sa), | |||
3007 | transition, transition->next_state); | |||
3008 | } | |||
3009 | ||||
3010 | static void success_v2_state_transition(struct state *st, struct msg_digest *md, | |||
3011 | const struct state_v2_microcode *transition) | |||
3012 | { | |||
3013 | /* | |||
3014 | * XXX: the transition's from state can lie - it may be | |||
3015 | * different to the ST's state! | |||
3016 | */ | |||
3017 | enum state_kind from_state = transition->state; | |||
3018 | struct connection *c = st->st_connection; | |||
3019 | struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3019}); | |||
3020 | ||||
3021 | if (from_state != transition->next_state) { | |||
3022 | dbg("transitioning from state %s to state %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("transitioning from state %s to state %s", finite_states [from_state]->name, finite_states[transition->next_state ]->name); } } | |||
3023 | finite_states[from_state]->name,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("transitioning from state %s to state %s", finite_states [from_state]->name, finite_states[transition->next_state ]->name); } } | |||
3024 | finite_states[transition->next_state]->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("transitioning from state %s to state %s", finite_states [from_state]->name, finite_states[transition->next_state ]->name); } }; | |||
3025 | } | |||
3026 | ||||
3027 | /* | |||
3028 | * Update counters, and if part of the transition, send the | |||
3029 | * new message. | |||
3030 | */ | |||
3031 | ||||
3032 | dbg("Message ID: updating counters for #%lu", st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Message ID: updating counters for #%lu", st-> st_serialno); } }; | |||
3033 | v2_msgid_update_recv(ike, st, md); | |||
3034 | v2_msgid_update_sent(ike, st, md, transition->send); | |||
3035 | v2_msgid_schedule_next_initiator(ike); | |||
3036 | ||||
3037 | if (from_state == STATE_V2_REKEY_IKE_R0 || | |||
3038 | from_state == STATE_V2_REKEY_IKE_I1) { | |||
3039 | ikev2_child_emancipate(ike, pexpect_child_sa(st), | |||
3040 | transition); | |||
3041 | } else { | |||
3042 | change_state(st, transition->next_state); | |||
3043 | } | |||
3044 | passert(st->st_state->kind >= STATE_IKEv2_FLOOR){ _Bool assertion__ = st->st_state->kind >= STATE_IKEv2_FLOOR ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 3044}, "%s", "st->st_state->kind >= STATE_IKEv2_FLOOR" ); } }; | |||
3045 | passert(st->st_state->kind < STATE_IKEv2_ROOF){ _Bool assertion__ = st->st_state->kind < STATE_IKEv2_ROOF ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 3045}, "%s", "st->st_state->kind < STATE_IKEv2_ROOF" ); } }; | |||
3046 | ||||
3047 | if (transition->flags & SMF2_ESTABLISHED) { | |||
3048 | /* | |||
3049 | * Count successful transition into an established state. | |||
3050 | * | |||
3051 | * Because IKE SAs and CHILD SAs share some state transitions | |||
3052 | * this only works for CHILD SAs. IKE SAs are accounted for | |||
3053 | * separately. | |||
3054 | */ | |||
3055 | pstat_sa_established(st); | |||
3056 | } | |||
3057 | ||||
3058 | /* | |||
3059 | * Tell whack and logs our progress - unless OE or a state | |||
3060 | * transition we're not telling anyone about, then be quiet. | |||
3061 | * | |||
3062 | * XXX: This code uses the new state, and not the state | |||
3063 | * transition to determine if things established :-( | |||
3064 | * | |||
3065 | * This should be a bit in the transition! | |||
3066 | */ | |||
3067 | ||||
3068 | dbg("announcing the state transition"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("announcing the state transition"); } }; | |||
3069 | enum rc_type w; | |||
3070 | void (*log_details)(struct jambuf *buf, struct state *st); | |||
3071 | struct state *log_st; | |||
3072 | if (transition->state == transition->next_state) { | |||
3073 | /* | |||
3074 | * HACK for seemingly going around in circles | |||
3075 | */ | |||
3076 | log_details = NULL((void*)0); | |||
3077 | log_st = st; | |||
3078 | w = RC_NEW_V2_STATE + st->st_state->kind; | |||
3079 | } else if (IS_CHILD_SA_ESTABLISHED(st)((st)->st_state->kind == STATE_V2_ESTABLISHED_CHILD_SA && ((st)->st_clonedfrom != 0))) { | |||
3080 | log_ipsec_sa_established("negotiated connection", st); | |||
3081 | log_details = lswlog_child_sa_established; | |||
3082 | log_st = st; | |||
3083 | /* log our success and trigger detach */ | |||
3084 | w = RC_SUCCESS; | |||
3085 | } else if (st->st_state->kind == STATE_PARENT_I2) { | |||
3086 | /* | |||
3087 | * Hack around md->st being forced to the CHILD_SA | |||
3088 | * with an IKE SA state. | |||
3089 | */ | |||
3090 | pexpect(IS_CHILD_SA(st))({ _Bool assertion__ = ((st)->st_clonedfrom != 0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3090}, "%s", "IS_CHILD_SA(st)"); } assertion__; }); | |||
3091 | pexpect(st != &ike->sa)({ _Bool assertion__ = st != &ike->sa; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3091}, "%s", "st != &ike->sa"); } assertion__ ; }); | |||
3092 | log_details = lswlog_ike_sa_established; | |||
3093 | log_st = &ike->sa; | |||
3094 | w = RC_NEW_V2_STATE + st->st_state->kind; | |||
3095 | } else if (st->st_state->kind == STATE_PARENT_R1) { | |||
3096 | log_details = lswlog_ike_sa_established; | |||
3097 | log_st = st; | |||
3098 | w = RC_NEW_V2_STATE + st->st_state->kind; | |||
3099 | } else if (transition->state == STATE_V2_REKEY_IKE_R0 && | |||
3100 | transition->next_state == STATE_V2_ESTABLISHED_IKE_SA) { | |||
3101 | pexpect(st->st_sa_role == SA_RESPONDER)({ _Bool assertion__ = st->st_sa_role == SA_RESPONDER; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3101}, "%s", "st->st_sa_role == SA_RESPONDER" ); } assertion__; }); | |||
3102 | pexpect(IS_IKE_SA(st))({ _Bool assertion__ = ((st)->st_clonedfrom == 0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3102}, "%s", "IS_IKE_SA(st)"); } assertion__; }); | |||
3103 | pexpect(st != &ike->sa)({ _Bool assertion__ = st != &ike->sa; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3103}, "%s", "st != &ike->sa"); } assertion__ ; }); | |||
3104 | log_details = lswlog_ike_sa_established; | |||
3105 | log_st = st; | |||
3106 | /* log our success and trigger detach */ | |||
3107 | w = RC_SUCCESS; | |||
3108 | } else if (transition->state == STATE_V2_REKEY_IKE_I1 && | |||
3109 | transition->next_state == STATE_V2_ESTABLISHED_IKE_SA) { | |||
3110 | pexpect(st->st_sa_role == SA_INITIATOR)({ _Bool assertion__ = st->st_sa_role == SA_INITIATOR; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3110}, "%s", "st->st_sa_role == SA_INITIATOR" ); } assertion__; }); | |||
3111 | pexpect(IS_IKE_SA(st))({ _Bool assertion__ = ((st)->st_clonedfrom == 0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3111}, "%s", "IS_IKE_SA(st)"); } assertion__; }); | |||
3112 | pexpect(st != &ike->sa)({ _Bool assertion__ = st != &ike->sa; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3112}, "%s", "st != &ike->sa"); } assertion__ ; }); | |||
3113 | log_details = lswlog_ike_sa_established; | |||
3114 | log_st = st; | |||
3115 | /* log our success and trigger detach */ | |||
3116 | w = RC_SUCCESS; | |||
3117 | } else { | |||
3118 | log_details = NULL((void*)0); | |||
3119 | log_st = st; | |||
3120 | w = RC_NEW_V2_STATE + st->st_state->kind; | |||
3121 | } | |||
3122 | ||||
3123 | if ((transition->flags & SMF2_SUPPRESS_SUCCESS_LOG) || | |||
3124 | (c != NULL((void*)0) && (c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))))) { | |||
3125 | 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_debug_stream (buf), buf = ((void*)0)) { | |||
3126 | jam(buf, "%s", st->st_state->story); | |||
3127 | /* document SA details for admin's pleasure */ | |||
3128 | if (log_details != NULL((void*)0)) { | |||
3129 | log_details(buf, st); | |||
3130 | } | |||
3131 | } | |||
3132 | } else { | |||
3133 | LOG_JAMBUF(w, log_st->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 (((w) & STREAM_MASK) != DEBUG_STREAM || (cur_debugging & (((lset_t )1 << (DBG_ADD_PREFIX_IX))))) { (log_st->st_logger)-> object_vec->jam_object_prefix(buf, (log_st->st_logger)-> object); } }); buf != ((void*)0); jambuf_to_logger(buf, (log_st ->st_logger), w), buf = ((void*)0)) { | |||
3134 | jam(buf, "%s", st->st_state->story); | |||
3135 | /* document SA details for admin's pleasure */ | |||
3136 | if (log_details != NULL((void*)0)) { | |||
3137 | log_details(buf, st); | |||
3138 | } | |||
3139 | } | |||
3140 | } | |||
3141 | ||||
3142 | /* | |||
3143 | * Adjust NAT but not for initial state (initial outbound | |||
3144 | * message?). | |||
3145 | * | |||
3146 | * ??? why should STATE_PARENT_I1 be excluded? | |||
3147 | * | |||
3148 | * XXX: and why, for that state, does ikev2_natd_lookup() call | |||
3149 | * it. | |||
3150 | * | |||
3151 | * XXX: STATE_PARENT_I1 is special in that, per the RFC, it | |||
3152 | * must switch the local and remote ports to :4500. | |||
3153 | * | |||
3154 | * XXX: The "initial outbound message" check was first added | |||
3155 | * by commit "pluto: various fixups associated with RFC 7383 | |||
3156 | * code". At the time a fake MD (created when an initiator | |||
3157 | * initiates) had the magic state STATE_IKEv2_BASE and so it | |||
3158 | * checked for that. What isn't clear is if the check was | |||
3159 | * intended to block just an IKE SA initiating, or also block | |||
3160 | * a CHILD SA initiate. | |||
3161 | * | |||
3162 | * XXX: STATE_PARENT_R1 (AUTH responder), in addition to the | |||
3163 | * below, will also call nat*() explicitly. Perhaps multiple | |||
3164 | * calls are benign? | |||
3165 | * | |||
3166 | * XXX: This is getting silly: | |||
3167 | * | |||
3168 | * - check for MD != NULL (aka NO_MESSAGE) - while initiators | |||
3169 | * don't have an incoming message | |||
3170 | * | |||
3171 | * - delete the call - IKE state transition code is already | |||
3172 | * somewhat doing this and why would nat need to be updated | |||
3173 | * during a child exchange | |||
3174 | * | |||
3175 | * - or what about an STF flag on the state? | |||
3176 | * | |||
3177 | * XXX: it would appear this is only for secure responder | |||
3178 | * states. | |||
3179 | * | |||
3180 | * XXX: It's a hack trying to implement the below: | |||
3181 | * | |||
3182 | * - the correct check for this end not being behind a NAT is | |||
3183 | * !NATED_HOST && NATED_PEER | |||
3184 | * | |||
3185 | * - the state checks wrongly assume the responder isn't | |||
3186 | * behind a NAT; and will completely fail if, after a REKEY, | |||
3187 | * the initiator and responder roles switch | |||
3188 | * | |||
3189 | * - ikev2_parent_inI2outR2_continue_tail()'s call can be | |||
3190 | * merged; suspect the thing to do is move the code to after | |||
3191 | * the message is decrypted? | |||
3192 | * | |||
3193 | * - is MOBIKE mutually excluded through policy flag checks? | |||
3194 | * | |||
3195 | * 2.23. NAT Traversal | |||
3196 | * | |||
3197 | * There are cases where a NAT box decides to remove mappings | |||
3198 | * that are still alive (for example, the keepalive interval | |||
3199 | * is too long, or the NAT box is rebooted). This will be | |||
3200 | * apparent to a host if it receives a packet whose integrity | |||
3201 | * protection validates, but has a different port, address, or | |||
3202 | * both from the one that was associated with the SA in the | |||
3203 | * validated packet. When such a validated packet is found, a | |||
3204 | * host that does not support other methods of recovery such | |||
3205 | * as IKEv2 Mobility and Multihoming (MOBIKE) [MOBIKE], and | |||
3206 | * that is not behind a NAT, SHOULD send all packets | |||
3207 | * (including retransmission packets) to the IP address and | |||
3208 | * port in the validated packet, and SHOULD store this as the | |||
3209 | * new address and port combination for the SA (that is, they | |||
3210 | * SHOULD dynamically update the address). A host behind a | |||
3211 | * NAT SHOULD NOT do this type of dynamic address update if a | |||
3212 | * validated packet has different port and/or address values | |||
3213 | * because it opens a possible DoS attack (such as allowing an | |||
3214 | * attacker to break the connection with a single packet). | |||
3215 | * Also, dynamic address update should only be done in | |||
3216 | * response to a new packet; otherwise, an attacker can revert | |||
3217 | * the addresses with old replayed packets. Because of this, | |||
3218 | * dynamic updates can only be done safely if replay | |||
3219 | * protection is enabled. When IKEv2 is used with MOBIKE, | |||
3220 | * dynamically updating the addresses described above | |||
3221 | * interferes with MOBIKE's way of recovering from the same | |||
3222 | * situation. See Section 3.8 of [MOBIKE] for more | |||
3223 | * information. | |||
3224 | */ | |||
3225 | if (transition->send != NO_MESSAGE && | |||
3226 | nat_traversal_enabled && | |||
3227 | from_state != STATE_PARENT_I0 && | |||
3228 | from_state != STATE_V2_NEW_CHILD_I0 && | |||
3229 | from_state != STATE_V2_REKEY_CHILD_I0 && | |||
3230 | from_state != STATE_V2_REKEY_IKE_I0 && | |||
3231 | from_state != STATE_PARENT_R0 && | |||
3232 | from_state != STATE_PARENT_I1 && | |||
3233 | from_state != STATE_V2_ESTABLISHED_CHILD_SA) { | |||
3234 | /* from_state = STATE_PARENT_R1 */ | |||
3235 | /* from_state = STATE_CREATE_R */ | |||
3236 | /* from_state = STATE_REKEY_IKE_R */ | |||
3237 | /* from_state = ??? */ | |||
3238 | /* adjust our destination port if necessary */ | |||
3239 | nat_traversal_change_port_lookup(md, &ike->sa); | |||
3240 | } | |||
3241 | ||||
3242 | /* if requested, send the new reply packet */ | |||
3243 | switch (transition->send) { | |||
3244 | case MESSAGE_REQUEST: | |||
3245 | case MESSAGE_RESPONSE: | |||
3246 | send_recorded_v2_message(ike, finite_states[from_state]->name, | |||
3247 | transition->send); | |||
3248 | break; | |||
3249 | case NO_MESSAGE: | |||
3250 | break; | |||
3251 | default: | |||
3252 | bad_case(transition->send)libreswan_bad_case("transition->send", (transition->send ), (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3252});; | |||
3253 | } | |||
3254 | ||||
3255 | if (w == RC_SUCCESS) { | |||
3256 | release_any_whack(st, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3256}, "IKEv2 transitions finished"); | |||
3257 | ||||
3258 | /* XXX should call unpend again on parent SA */ | |||
3259 | if (IS_CHILD_SA(st)((st)->st_clonedfrom != 0)) { | |||
3260 | /* with failed child sa, we end up here with an orphan?? */ | |||
3261 | struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3261}); | |||
3262 | dbg("unpending #%lu's IKE SA #%lu", st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("unpending #%lu's IKE SA #%lu", st->st_serialno , ike->sa.st_serialno); } } | |||
3263 | ike->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("unpending #%lu's IKE SA #%lu", st->st_serialno , ike->sa.st_serialno); } }; | |||
3264 | /* a better call unpend in ikev2_ike_sa_established? */ | |||
3265 | unpend(ike, c); | |||
3266 | ||||
3267 | /* | |||
3268 | * If this was an OE connection, check for removing a potential | |||
3269 | * matching bare shunt entry - bare shunts are always a %pass or | |||
3270 | * %hold SPI but are found regardless of whether we passed in | |||
3271 | * SPI_PASS or SPI_HOLD ? | |||
3272 | */ | |||
3273 | if (LIN(POLICY_OPPORTUNISTIC, c->policy)(((((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))))) { | |||
3274 | struct spd_route *sr = &c->spd; | |||
3275 | struct bare_shunt **bs = bare_shunt_ptr(&sr->this.client, &sr->that.client, sr->this.protocol); | |||
3276 | ||||
3277 | if (bs != NULL((void*)0)) { | |||
3278 | dbg("deleting old bare shunt"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting old bare shunt"); } }; | |||
3279 | if (!delete_bare_shunt(&c->spd.this.host_addr, | |||
3280 | &c->spd.that.host_addr, | |||
3281 | c->spd.this.protocol, | |||
3282 | SPI_PASS256 /* else its not bare */, | |||
3283 | /* this text is used to signal the low level :/ */ | |||
3284 | "IGNORE_ON_XFRM: installed IPsec SA replaced old bare shunt")) { | |||
3285 | loglog(RC_LOG_SERIOUS, "Failed to delete old bare shunt"); | |||
3286 | } | |||
3287 | } | |||
3288 | } | |||
3289 | release_any_whack(&ike->sa, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3289}, "IKEv2 transitions finished so releaseing IKE SA"); | |||
3290 | } | |||
3291 | } else if (transition->flags & SMF2_RELEASE_WHACK) { | |||
3292 | log_state(RC_COMMENT, st, "releasing whack"); | |||
3293 | release_any_whack(st, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3293}, "ST per transition"); | |||
3294 | if (st != &ike->sa) { | |||
3295 | release_any_whack(&ike->sa, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3295}, "IKE per transition"); | |||
3296 | } | |||
3297 | } | |||
3298 | ||||
3299 | /* Schedule for whatever timeout is specified */ | |||
3300 | { | |||
3301 | enum event_type kind = transition->timeout_event; | |||
3302 | struct connection *c = st->st_connection; | |||
3303 | ||||
3304 | switch (kind) { | |||
3305 | ||||
3306 | case EVENT_RETRANSMIT: | |||
3307 | /* | |||
3308 | * Event retransmit is really a secret code to | |||
3309 | * indicate that a request is being sent and a | |||
3310 | * retransmit should already be scheduled. | |||
3311 | */ | |||
3312 | dbg("checking that a retransmit timeout_event was already"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("checking that a retransmit timeout_event was already" ); } }; | |||
3313 | delete_event(st); /* relying on retransmit */ | |||
3314 | pexpect(st->st_retransmit_event != NULL)({ _Bool assertion__ = st->st_retransmit_event != ((void*) 0); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 3314}, "%s", "st->st_retransmit_event != NULL" ); } assertion__; }); | |||
3315 | pexpect(transition->send == MESSAGE_REQUEST)({ _Bool assertion__ = transition->send == MESSAGE_REQUEST ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 3315}, "%s", "transition->send == MESSAGE_REQUEST" ); } assertion__; }); | |||
3316 | break; | |||
3317 | ||||
3318 | case EVENT_SA_REPLACE: /* IKE or Child SA replacement event */ | |||
3319 | v2_schedule_replace_event(st); | |||
3320 | break; | |||
3321 | ||||
3322 | case EVENT_SO_DISCARD: | |||
3323 | delete_event(st); | |||
3324 | event_schedule(kind, MAXIMUM_RESPONDER_WAIT_DELAYdeltatime(200), st); | |||
3325 | break; | |||
3326 | ||||
3327 | case EVENT_NULL: | |||
3328 | /* | |||
3329 | * Is there really no case where we want to | |||
3330 | * set no timer? more likely an accident? | |||
3331 | */ | |||
3332 | pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3332}, | |||
3333 | "V2 microcode entry (%s) has unspecified timeout_event", | |||
3334 | transition->story); | |||
3335 | break; | |||
3336 | ||||
3337 | case EVENT_v2_REDIRECT: | |||
3338 | event_delete(EVENT_v2_REDIRECT, st); | |||
3339 | event_schedule(EVENT_v2_REDIRECT, deltatime(0), st); | |||
3340 | break; | |||
3341 | ||||
3342 | case EVENT_RETAIN: | |||
3343 | /* the previous event is retained */ | |||
3344 | dbg("#%lu is retaining %s with is previously set timeout",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is retaining %s with is previously set timeout" , st->st_serialno, (st->st_event == ((void*)0) ? "<no-event>" : enum_name(&timer_event_names, st->st_event->ev_type ))); } } | |||
3345 | st->st_serialno, (st->st_event == NULL ? "<no-event>" :{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is retaining %s with is previously set timeout" , st->st_serialno, (st->st_event == ((void*)0) ? "<no-event>" : enum_name(&timer_event_names, st->st_event->ev_type ))); } } | |||
3346 | enum_name(&timer_event_names, st->st_event->ev_type))){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is retaining %s with is previously set timeout" , st->st_serialno, (st->st_event == ((void*)0) ? "<no-event>" : enum_name(&timer_event_names, st->st_event->ev_type ))); } }; | |||
3347 | break; | |||
3348 | ||||
3349 | default: | |||
3350 | bad_case(kind)libreswan_bad_case("kind", (kind), (where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 3350}); | |||
3351 | break; | |||
3352 | } | |||
3353 | /* | |||
3354 | * start liveness checks if set, making sure we only | |||
3355 | * schedule once when moving from I2->I3 or R1->R2 | |||
3356 | */ | |||
3357 | if (st->st_state->kind != from_state && | |||
3358 | st->st_state->kind != STATE_UNDEFINED && | |||
3359 | IS_CHILD_SA_ESTABLISHED(st)((st)->st_state->kind == STATE_V2_ESTABLISHED_CHILD_SA && ((st)->st_clonedfrom != 0)) && | |||
3360 | dpd_active_locally(st)) { | |||
3361 | dbg("dpd enabled, scheduling ikev2 liveness checks"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("dpd enabled, scheduling ikev2 liveness checks" ); } }; | |||
3362 | deltatime_t delay = deltatime_max(c->dpd_delay, deltatime(MIN_LIVENESS1)); | |||
3363 | event_schedule(EVENT_v2_LIVENESS, delay, st); | |||
3364 | } | |||
3365 | } | |||
3366 | } | |||
3367 | ||||
3368 | /* | |||
3369 | * Dependent on RESULT, either complete, suspend, abandon, or abort | |||
3370 | * (delete state) the state transition started by the state-specific | |||
3371 | * state transition function. | |||
3372 | * | |||
3373 | * Since this is function is meaningless without a state, ST really | |||
3374 | * should be non-NULL. | |||
3375 | * | |||
3376 | * XXX: A broken exception is when responding to an IKE_SA_INIT | |||
3377 | * request - the state machine calls the state transition function | |||
3378 | * with no state (trusting that the transition function will do the | |||
3379 | * job, but that isn't always true). The fix is to create the state | |||
3380 | * before calling the state transition function (like is done for the | |||
3381 | * CHILD_SA code). | |||
3382 | * | |||
3383 | * Since, when initiating an exchange there is no message, code can't | |||
3384 | * assume that (*MDP) is non-NULL. | |||
3385 | * | |||
3386 | * XXX: Some state transition functions switch state part way (see | |||
3387 | * AUTH child code) and then tunnel the new state to this code via | |||
3388 | * (*MDP)->st and some callers passing in (*MDP)->st). The fix is for | |||
3389 | * the AUTH code to handle the CHILD SA as a nested or separate | |||
3390 | * transition. | |||
3391 | * | |||
3392 | * XXX: The state transition structure (microcode) is stored in (*MDP) | |||
3393 | * forcing that structure to be created. The fix is to store the | |||
3394 | * state's transition in the state. As a bonus this makes determining | |||
3395 | * if a state is busy really really easy - if there's a | |||
3396 | * state-transition then it must be. | |||
3397 | * | |||
3398 | * This routine does not free (*MDP) (using release_any_md(mdp)). | |||
3399 | * However, when suspending a state transition, it will save it in ST | |||
3400 | * and zap (*MDP) so that the caller can't free it. Hence, the caller | |||
3401 | * must be prepared for (*MDP) being set to NULL. | |||
3402 | * | |||
3403 | * XXX: At some point (*MDP) was being used for: | |||
3404 | * | |||
3405 | * - find st | |||
3406 | * - success_v2_state_transition(st, md); | |||
3407 | * - for svm: | |||
3408 | * - svm->next_state, | |||
3409 | * - svm->flags & SMF2_SEND, | |||
3410 | * - svm->timeout_event, | |||
3411 | * -svm->flags, story | |||
3412 | * - find from_state (st might be gone) | |||
3413 | * - ikev2_update_msgid_counters(md); | |||
3414 | * - nat_traversal_change_port_lookup(md, st) | |||
3415 | * - !(md->hdr.isa_flags & ISAKMP_FLAGS_v2_MSG_R) to gate Notify payloads/exchanges [WRONG] | |||
3416 | * - find note for STF_INTERNAL_ERROR | |||
3417 | * - find note for STF_FAIL (might not be part of result (STF_FAIL+note)) | |||
3418 | * | |||
3419 | * We don't use these but complete_v1_state_transition does: | |||
3420 | * - record md->event_already_set | |||
3421 | * - remember_received_packet(st, md); | |||
3422 | * - fragvid, dpd, nortel | |||
3423 | */ | |||
3424 | void complete_v2_state_transition(struct state *st, | |||
3425 | struct msg_digest *md, | |||
3426 | stf_status result) | |||
3427 | { | |||
3428 | passert(st != NULL){ _Bool assertion__ = st != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3428}, "%s", "st != NULL"); } }; | |||
| ||||
3429 | struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3429}); | |||
3430 | /* struct child_sa *child = IS_CHILD_SA(st) ? pexpect_child_sa(st) : NULL; */ | |||
3431 | set_cur_state(st)log_push_state(st, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3431}); /* might have changed */ /* XXX: huh? */ | |||
3432 | ||||
3433 | /* statistics */ | |||
3434 | /* this really depends on the type of error whether it is an IKE or IPsec fail */ | |||
3435 | if (result > STF_FAIL) { | |||
3436 | pstats(ike_stf, STF_FAIL){ const unsigned __pstat = (STF_FAIL); if (__pstat < (sizeof (pstats_ike_stf) / sizeof(*(pstats_ike_stf)))) { pstats_ike_stf [__pstat]++; } else if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { DBG_log("pstats %s %d", "ike_stf", __pstat ); } }; | |||
3437 | } else { | |||
3438 | pstats(ike_stf, result){ const unsigned __pstat = (result); if (__pstat < (sizeof (pstats_ike_stf) / sizeof(*(pstats_ike_stf)))) { pstats_ike_stf [__pstat]++; } else if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { DBG_log("pstats %s %d", "ike_stf", __pstat ); } }; | |||
3439 | } | |||
3440 | ||||
3441 | /* | |||
3442 | * XXX: If MD and MD.ST are non-NULL, expect MD.ST to point to | |||
3443 | * ST. | |||
3444 | * | |||
3445 | * An exchange initiator doesn't have an MD: | |||
3446 | * | |||
3447 | * - store the state transition; but that information really | |||
3448 | * belongs in ST | |||
3449 | * | |||
3450 | * - store the CHILD SA when created midway through a state | |||
3451 | * transition (see IKE_AUTH); but that should be either a | |||
3452 | * nested or separate transition | |||
3453 | * | |||
3454 | * - signal that the SA was deleted mid-transition by clearing | |||
3455 | * MD.ST (so presumably it was previously set); but that | |||
3456 | * should be handled by returning an STF_ZOMBIFY and having | |||
3457 | * this code delete the SA. | |||
3458 | */ | |||
3459 | if (md != NULL((void*)0) && md->st != NULL((void*)0) && md->st != st) { | |||
3460 | /* can't happen, must match */ | |||
3461 | pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3461}, | |||
3462 | "MD.ST contains the unknown %s SA #%lu; expecting the %s SA #%lu", | |||
3463 | IS_CHILD_SA(md->st)((md->st)->st_clonedfrom != 0) ? "CHILD" : "IKE", | |||
3464 | md->st->st_serialno, | |||
3465 | IS_CHILD_SA(st)((st)->st_clonedfrom != 0) ? "CHILD" : "IKE", | |||
3466 | st->st_serialno); | |||
3467 | return; | |||
3468 | } | |||
3469 | ||||
3470 | /* | |||
3471 | * Try to get the transition that is being completed ... | |||
3472 | * | |||
3473 | * For the moment this comes from the (presumably non-NULL) | |||
3474 | * MD.SVM. | |||
3475 | * | |||
3476 | * XXX: However, when a packet is bad and no transition is | |||
3477 | * selected, this code is still called: | |||
3478 | * | |||
3479 | * STF_IGNORE: to undo the v2_msgid_start_responder() call; | |||
3480 | * better would probably be to move that call to after a | |||
3481 | * transition has been found (but fragmentation makes this | |||
3482 | * messy). | |||
3483 | * | |||
3484 | * STF_FATAL: to discard a state in response to a bad exchange | |||
3485 | * (for instance a protected packet's contents are bogus). | |||
3486 | * | |||
3487 | * Long term, this value should be extracted from the state | |||
3488 | * and .st_v2_state_transition - it just isn't possible to | |||
3489 | * squeeze both the IKE and CHILD transitions into MD.ST. | |||
3490 | */ | |||
3491 | #if 0 | |||
3492 | const struct state_v2_microcode *transition = st->st_v2_transition; | |||
3493 | if (!pexpect(transition != NULL)({ _Bool assertion__ = transition != ((void*)0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3493}, "%s", "transition != NULL"); } assertion__; }) && md != NULL((void*)0)) { | |||
3494 | transition = md->svm; | |||
3495 | } | |||
3496 | #else | |||
3497 | const struct state_v2_microcode *transition = (md != NULL((void*)0) && md->svm != NULL((void*)0) ? md->svm : | |||
3498 | st->st_v2_transition); | |||
3499 | #endif | |||
3500 | static const struct state_v2_microcode undefined_transition = { | |||
3501 | .story = "suspect message", | |||
3502 | .state = STATE_UNDEFINED, | |||
3503 | .next_state = STATE_UNDEFINED, | |||
3504 | }; | |||
3505 | /* double negative */ | |||
3506 | if (!pexpect(transition != NULL)({ _Bool assertion__ = transition != ((void*)0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3506}, "%s", "transition != NULL"); } assertion__; })) { | |||
3507 | transition = &undefined_transition; | |||
3508 | } | |||
3509 | ||||
3510 | 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_debug_stream (buf), buf = ((void*)0)) { | |||
3511 | const struct finite_state *transition_from = finite_states[transition->state]; | |||
3512 | ||||
3513 | jam(buf, "#%lu complete_v2_state_transition()", st->st_serialno); | |||
3514 | if (st->st_state != transition_from) { | |||
3515 | jam(buf, " in state %s", st->st_state->short_name); | |||
3516 | } | |||
3517 | jam(buf, " "); | |||
3518 | jam_v2_transition(buf, transition); | |||
3519 | jam(buf, " with status "); | |||
3520 | jam_v2_stf_status(buf, result); | |||
3521 | /* does MD.SVM diverge? */ | |||
3522 | if (md != NULL((void*)0) && transition != md->svm) { | |||
3523 | jam(buf, "; md.svm="); | |||
3524 | jam_v2_transition(buf, md->svm); | |||
3525 | } | |||
3526 | /* does ST.ST_V2_TRANSITION diverge? */ | |||
3527 | if (transition != st->st_v2_transition) { | |||
3528 | jam(buf, "; .st_v2_transition="); | |||
3529 | jam_v2_transition(buf, st->st_v2_transition); | |||
3530 | } | |||
3531 | } | |||
3532 | ||||
3533 | /* audit log failures - success is audit logged in ikev2_ike_sa_established() */ | |||
3534 | if (result > STF_OK) { | |||
3535 | linux_audit_conn(st, IS_IKE_SA_ESTABLISHED(st)( ((((lset_t)1 << ((st)->st_state->kind)) & ( ((lset_t)1 << (STATE_MAIN_R3)) | ((lset_t)1 << (STATE_MAIN_I4 )) | ((lset_t)1 << (STATE_AGGR_I2)) | ((lset_t)1 << (STATE_AGGR_R2)) | ((lset_t)1 << (STATE_XAUTH_R0)) | ( (lset_t)1 << (STATE_XAUTH_R1)) | ((lset_t)1 << (STATE_MODE_CFG_R0 )) | ((lset_t)1 << (STATE_MODE_CFG_R1)) | ((lset_t)1 << (STATE_MODE_CFG_R2)) | ((lset_t)1 << (STATE_MODE_CFG_I1 )) | ((lset_t)1 << (STATE_XAUTH_I0)) | ((lset_t)1 << (STATE_XAUTH_I1)) | ((lset_t)1 << (STATE_V2_ESTABLISHED_IKE_SA )))) != ((lset_t)0)) || ((((st)->st_state->kind == STATE_V2_ESTABLISHED_IKE_SA ) && !((st)->st_clonedfrom != 0)) && ((st) ->st_clonedfrom == 0))) ? LAK_CHILD_FAIL : LAK_PARENT_FAIL); | |||
3536 | } | |||
3537 | ||||
3538 | switch (result) { | |||
3539 | ||||
3540 | case STF_SUSPEND: | |||
3541 | /* | |||
3542 | * If this transition was triggered by an | |||
3543 | * incoming packet, save it. | |||
3544 | * | |||
3545 | * XXX: some initiator code creates a fake MD | |||
3546 | * (there isn't a real one); save that as | |||
3547 | * well. | |||
3548 | * | |||
3549 | * XXX: should the helper code be responsible for | |||
3550 | * saving an MD reference? | |||
3551 | */ | |||
3552 | suspend_any_md(st, md){ if (md != ((void*)0)) { { if ((cur_debugging & (((lset_t )1 << (DBG_BASE_IX))))) { DBG_log("suspending state #%lu and saving MD %p" , (st)->st_serialno, md); } }; { _Bool assertion__ = (st)-> st_suspended_md == ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3552}, "%s", "(st)->st_suspended_md == NULL"); } }; (st)-> st_suspended_md = md_addref(md, (where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3552}); (st)->st_suspended_md_func = __func__; (st)->st_suspended_md_line = 3552; { _Bool assertion__ = state_is_busy(st); if (!assertion__) { lsw_passert_fail((where_t ) { .func = __func__, .basename = "ikev2.c" , .line = 3552}, "%s" , "state_is_busy(st)"); } }; } else { { if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { DBG_log("no MD to suspend" ); } }; } }; | |||
3553 | return; | |||
3554 | ||||
3555 | case STF_IGNORE: | |||
3556 | /* | |||
3557 | * logged above | |||
3558 | * | |||
3559 | * XXX: really? Suspect this means to say logged | |||
3560 | * where STF_IGNORE is returned. | |||
3561 | * | |||
3562 | * XXX: even when a packet is invalid and no | |||
3563 | * transition is selected (TRANSITION==NULL) this code | |||
3564 | * is executed - caller needs to cancel the responder | |||
3565 | * processing the message. | |||
3566 | */ | |||
3567 | if (v2_msg_role(md) == MESSAGE_REQUEST) { | |||
3568 | v2_msgid_cancel_responder(ike, st, md); | |||
3569 | } | |||
3570 | return; | |||
3571 | ||||
3572 | case STF_OK: | |||
3573 | /* advance the state */ | |||
3574 | success_v2_state_transition(st, md, transition); | |||
3575 | break; | |||
3576 | ||||
3577 | case STF_INTERNAL_ERROR: | |||
3578 | log_state(RC_INTERNALERR, st, "state transition function for %s had internal error", | |||
3579 | st->st_state->name); | |||
3580 | release_pending_whacks(st, "internal error"); | |||
3581 | break; | |||
3582 | ||||
3583 | case STF_V2_DELETE_EXCHANGE_INITIATOR_IKE_SA: | |||
3584 | /* initiator processing response */ | |||
3585 | pexpect(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2.c" , .line = 3585}, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } assertion__; }); | |||
3586 | /* lie -- the delete _hopefully_ does what is wanted? */ | |||
3587 | log_state(RC_LOG, &ike->sa, "sending IKE SA delete"); | |||
3588 | dbg("Message ID: forcing a response received update"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Message ID: forcing a response received update" ); } }; | |||
3589 | v2_msgid_update_recv(ike, NULL((void*)0), md); | |||
3590 | /* | |||
3591 | * XXX: this call will fire and forget. It should | |||
3592 | * call v2_msgid_queue_initiator() with high priority | |||
3593 | * so this is performed as a separate transition? | |||
3594 | */ | |||
3595 | delete_ike_family(ike, PROBABLY_SEND_DELETE); | |||
3596 | /* get out of here -- everthing is invalid */ | |||
3597 | return; | |||
3598 | ||||
3599 | case STF_FATAL: | |||
3600 | /* | |||
3601 | * XXX: even when a packet is invalid and no | |||
3602 | * transition is selected (TRANSITION==NULL) this code | |||
3603 | * is executed - caller needs to kill the state. | |||
3604 | */ | |||
3605 | log_state(RC_FATAL, st, "encountered fatal error in state %s", | |||
3606 | st->st_state->name); | |||
3607 | switch (v2_msg_role(md)) { | |||
3608 | case MESSAGE_RESPONSE: | |||
3609 | dbg("Message ID: forcing a response received update"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Message ID: forcing a response received update" ); } }; | |||
3610 | v2_msgid_update_recv(ike, NULL((void*)0), md); | |||
3611 | break; | |||
3612 | case MESSAGE_REQUEST: | |||
3613 | dbg("Message ID: responding with recorded fatal error"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Message ID: responding with recorded fatal error" ); } }; | |||
3614 | pexpect(transition->send == MESSAGE_RESPONSE)({ _Bool assertion__ = transition->send == MESSAGE_RESPONSE ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 3614}, "%s", "transition->send == MESSAGE_RESPONSE" ); } assertion__; }); | |||
3615 | if (ike->sa.st_v2_outgoing[MESSAGE_RESPONSE] != NULL((void*)0)) { | |||
3616 | v2_msgid_update_recv(ike, st, md); | |||
3617 | v2_msgid_update_sent(ike, st, md, transition->send); | |||
3618 | send_recorded_v2_message(ike, "STF_FATAL", | |||
3619 | MESSAGE_RESPONSE); | |||
3620 | release_pending_whacks(st, "fatal error"); | |||
3621 | delete_ike_family(ike, DONT_SEND_DELETE); | |||
3622 | return; | |||
3623 | } | |||
3624 | dbg("Message ID: exchange zombie as no response?"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Message ID: exchange zombie as no response?") ; } }; | |||
3625 | break; | |||
3626 | case NO_MESSAGE: | |||
3627 | break; | |||
3628 | } | |||
3629 | release_pending_whacks(st, "fatal error"); | |||
3630 | delete_state(st); | |||
3631 | /* kill all st pointers */ | |||
3632 | st = NULL((void*)0); ike = NULL((void*)0); if (md != NULL((void*)0)) md->st = NULL((void*)0); | |||
3633 | break; | |||
3634 | ||||
3635 | case STF_FAIL: | |||
3636 | log_state(RC_NOTIFICATION, st, "state transition '%s' failed", | |||
3637 | transition->story); | |||
3638 | switch (v2_msg_role(md)) { | |||
3639 | case MESSAGE_RESPONSE: | |||
3640 | dbg("Message ID: forcing a response received update making space for delete"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Message ID: forcing a response received update making space for delete" ); } }; | |||
3641 | v2_msgid_update_recv(ike, st, md); | |||
3642 | break; | |||
3643 | case MESSAGE_REQUEST: | |||
3644 | dbg("Message ID: responding with recorded error"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Message ID: responding with recorded error"); } }; | |||
3645 | pexpect(transition->send == MESSAGE_RESPONSE)({ _Bool assertion__ = transition->send == MESSAGE_RESPONSE ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2.c" , .line = 3645}, "%s", "transition->send == MESSAGE_RESPONSE" ); } assertion__; }); | |||
3646 | v2_msgid_update_recv(ike, st, md); | |||
3647 | v2_msgid_update_sent(ike, st, md, transition->send); | |||
3648 | send_recorded_v2_message(ike, "STF_FAIL", MESSAGE_RESPONSE); | |||
3649 | break; | |||
3650 | case NO_MESSAGE: | |||
3651 | break; | |||
3652 | } | |||
3653 | release_pending_whacks(st, "fatal error"); | |||
3654 | delete_state(st); | |||
3655 | /* kill all st pointers */ | |||
3656 | st = NULL((void*)0); ike = NULL((void*)0); if (md != NULL((void*)0)) md->st = NULL((void*)0); | |||
3657 | break; | |||
3658 | ||||
3659 | default: /* STF_FAIL+notification */ | |||
3660 | passert(result > STF_FAIL){ _Bool assertion__ = result > STF_FAIL; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3660}, "%s", "result > STF_FAIL"); } }; | |||
3661 | /* | |||
3662 | * XXX: For IKEv2, this code path isn't sufficient - a | |||
3663 | * message request can result in a response that | |||
3664 | * contains both a success and a fail. Better to | |||
3665 | * record the responses and and then return | |||
3666 | * STF_ZOMBIFY signaling both that the message should | |||
3667 | * be sent and the state deleted. | |||
3668 | */ | |||
3669 | v2_notification_t notification = result - STF_FAIL; | |||
3670 | /* Only the responder sends a notification */ | |||
3671 | if (v2_msg_role(md) == MESSAGE_REQUEST) { | |||
3672 | dbg("sending a notification reply"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("sending a notification reply"); } }; | |||
3673 | v2_msgid_update_recv(ike, st, md); | |||
3674 | record_v2N_response(st->st_logger, ike, md, | |||
3675 | notification, NULL((void*)0)/*no data*/, | |||
3676 | ENCRYPTED_PAYLOAD); | |||
3677 | v2_msgid_update_sent(ike, st, md, transition->send); | |||
3678 | send_recorded_v2_message(ike, "STF_FAIL", | |||
3679 | MESSAGE_RESPONSE); | |||
3680 | /* | |||
3681 | * XXX: is this always false; if true above | |||
3682 | * record would pexpect()? | |||
3683 | */ | |||
3684 | if (md->hdr.isa_xchg == ISAKMP_v2_IKE_SA_INIT) { | |||
| ||||
3685 | delete_state(st); | |||
3686 | /* kill all st pointers */ | |||
3687 | st = NULL((void*)0); ike = NULL((void*)0); md->st = NULL((void*)0); | |||
3688 | } else { | |||
3689 | dbg("forcing #%lu to a discard event",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("forcing #%lu to a discard event", st->st_serialno ); } } | |||
3690 | st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("forcing #%lu to a discard event", st->st_serialno ); } }; | |||
3691 | delete_event(st); | |||
3692 | event_schedule(EVENT_SO_DISCARD, | |||
3693 | MAXIMUM_RESPONDER_WAIT_DELAYdeltatime(200), | |||
3694 | st); | |||
3695 | } | |||
3696 | } else { | |||
3697 | log_state(RC_NOTIFICATION+notification, st, | |||
3698 | "state transition '%s' failed with %s", | |||
3699 | transition->story, enum_name(&ikev2_notify_names, notification)); | |||
3700 | } | |||
3701 | break; | |||
3702 | } | |||
3703 | } | |||
3704 | ||||
3705 | void jam_v2_stf_status(struct jambuf *buf, unsigned status) | |||
3706 | { | |||
3707 | if (status <= STF_FAIL) { | |||
3708 | jam_enum(buf, &stf_status_names, status); | |||
3709 | } else { | |||
3710 | jam(buf, "STF_FAIL+"); | |||
3711 | jam_enum(buf, &ikev2_notify_names, status - STF_FAIL); | |||
3712 | } | |||
3713 | } | |||
3714 | ||||
3715 | /* used by parent and child to emit v2N_IPCOMP_SUPPORTED if appropriate */ | |||
3716 | bool_Bool emit_v2N_compression(struct state *cst, | |||
3717 | bool_Bool OK, | |||
3718 | pb_stream *s) | |||
3719 | { | |||
3720 | const struct connection *c = cst->st_connection; | |||
3721 | ||||
3722 | if ((c->policy & POLICY_COMPRESS((lset_t)1 << (POLICY_COMPRESS_IX))) && OK) { | |||
3723 | uint16_t c_spi; | |||
3724 | ||||
3725 | dbg("Initiator child policy is compress=yes, sending v2N_IPCOMP_SUPPORTED for DEFLATE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initiator child policy is compress=yes, sending v2N_IPCOMP_SUPPORTED for DEFLATE" ); } }; | |||
3726 | ||||
3727 | /* calculate and keep our CPI */ | |||
3728 | if (cst->st_ipcomp.our_spi == 0) { | |||
3729 | /* CPI is stored in network low order end of an ipsec_spi_t */ | |||
3730 | cst->st_ipcomp.our_spi = get_my_cpi(&c->spd, LIN(POLICY_TUNNEL, c->policy)(((((lset_t)1 << (POLICY_TUNNEL_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_TUNNEL_IX))))); | |||
3731 | c_spi = (uint16_t)ntohl(cst->st_ipcomp.our_spi); | |||
3732 | if (c_spi < IPCOMP_FIRST_NEGOTIATED256) { | |||
3733 | /* get_my_cpi() failed */ | |||
3734 | loglog(RC_LOG_SERIOUS, "kernel failed to calculate compression CPI (CPI=%d)", c_spi); | |||
3735 | return false0; | |||
3736 | } | |||
3737 | dbg("calculated compression CPI=%d", c_spi){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("calculated compression CPI=%d", c_spi); } }; | |||
3738 | } else { | |||
3739 | c_spi = (uint16_t)ntohl(cst->st_ipcomp.our_spi); | |||
3740 | } | |||
3741 | ||||
3742 | struct ikev2_notify_ipcomp_data d = { | |||
3743 | .ikev2_cpi = c_spi, | |||
3744 | .ikev2_notify_ipcomp_trans = IPCOMP_DEFLATE, | |||
3745 | }; | |||
3746 | pb_stream d_pbs; | |||
3747 | ||||
3748 | bool_Bool r = | |||
3749 | emit_v2Npl(v2N_IPCOMP_SUPPORTED, s, &d_pbs) && | |||
3750 | out_struct(&d, &ikev2notify_ipcomp_data_desc, &d_pbs, NULL((void*)0)); | |||
3751 | close_output_pbs(&d_pbs); | |||
3752 | return r; | |||
3753 | } else { | |||
3754 | dbg("initiator child policy is compress=no, NOT sending v2N_IPCOMP_SUPPORTED"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("initiator child policy is compress=no, NOT sending v2N_IPCOMP_SUPPORTED" ); } }; | |||
3755 | return true1; | |||
3756 | } | |||
3757 | } | |||
3758 | ||||
3759 | static void reinitiate_ike_sa_init(struct state *st, void *arg) | |||
3760 | { | |||
3761 | if (st == NULL((void*)0)) { | |||
3762 | dbg("re-initiate lost state"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("re-initiate lost state"); } }; | |||
3763 | return; | |||
3764 | } | |||
3765 | struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3765}); | |||
3766 | if (ike == NULL((void*)0)) { | |||
3767 | /* already logged */ | |||
3768 | return; | |||
3769 | } | |||
3770 | stf_status (*resume)(struct ike_sa *ike) = arg; | |||
3771 | ||||
3772 | /* | |||
3773 | * Need to wind back the Message ID counters so that the send | |||
3774 | * code things it is creating Message 0. | |||
3775 | */ | |||
3776 | v2_msgid_init_ike(ike); | |||
3777 | ||||
3778 | /* | |||
3779 | * Pretend to be running the initiate state. | |||
3780 | */ | |||
3781 | set_v2_transition(&ike->sa, finite_states[STATE_PARENT_I0]->v2_transitions, HERE(where_t) { .func = __func__, .basename = "ikev2.c" , .line = 3781}); /* first */ | |||
3782 | complete_v2_state_transition(&ike->sa, NULL((void*)0)/*no-MD*/, resume(ike)); | |||
3783 | } | |||
3784 | ||||
3785 | void schedule_reinitiate_v2_ike_sa_init(struct ike_sa *ike, | |||
3786 | stf_status (*resume)(struct ike_sa *ike)) | |||
3787 | { | |||
3788 | schedule_callback("reinitiating IKE_SA_INIT", ike->sa.st_serialno, | |||
3789 | reinitiate_ike_sa_init, resume); | |||
3790 | } | |||
3791 |