File: | programs/pluto/state.c |
Warning: | line 2268, column 4 Value stored to 'mbcp' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* routines for state objects, for libreswan |
2 | * |
3 | * Copyright (C) 1997 Angelos D. Keromytis. |
4 | * Copyright (C) 1998-2001, 2013-2017 D. Hugh Redelmeier <hugh@mimosa.com> |
5 | * Copyright (C) 2003-2008 Michael C Richardson <mcr@xelerance.com> |
6 | * Copyright (C) 2003-2010 Paul Wouters <paul@xelerance.com> |
7 | * Copyright (C) 2008-2009 David McCullough <david_mccullough@securecomputing.com> |
8 | * Copyright (C) 2009, 2012 Avesh Agarwal <avagarwa@redhat.com> |
9 | * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com> |
10 | * Copyright (C) 2012 Wes Hardaker <opensource@hardakers.net> |
11 | * Copyright (C) 2012 Bram <bram-bcrafjna-erqzvar@spam.wizbit.be> |
12 | * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org> |
13 | * Copyright (C) 2013 Tuomo Soini <tis@foobar.fi> |
14 | * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com> |
15 | * Copyright (C) 2013 Florian Weimer <fweimer@redhat.com> |
16 | * Copyright (C) 2015-2019 Andrew Cagney <cagney@gnu.org> |
17 | * Copyright (C) 2015-2018 Antony Antony <antony@phenome.org> |
18 | * Copyright (C) 2015-2019 Paul Wouters <pwouters@redhat.com> |
19 | * Copyright (C) 2017 Richard Guy Briggs <rgb@tricolour.ca> |
20 | * Copyright (C) 2017 Vukasin Karadzic <vukasin.karadzic@gmail.com> |
21 | * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com> |
22 | * |
23 | * This program is free software; you can redistribute it and/or modify it |
24 | * under the terms of the GNU General Public License as published by the |
25 | * Free Software Foundation; either version 2 of the License, or (at your |
26 | * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>. |
27 | * |
28 | * This program is distributed in the hope that it will be useful, but |
29 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
30 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
31 | * for more details. |
32 | * |
33 | */ |
34 | |
35 | #include <stdio.h> |
36 | #include <stdlib.h> |
37 | #include <string.h> |
38 | #include <unistd.h> |
39 | #include <sys/types.h> |
40 | #include <sys/socket.h> |
41 | #include <netinet/in.h> |
42 | #include <arpa/inet.h> |
43 | #include <fcntl.h> |
44 | #include <event2/bufferevent.h> /* TCP: for bufferevent_free()? */ |
45 | |
46 | #include "sysdep.h" |
47 | #include "constants.h" |
48 | #include "defs.h" |
49 | #include "id.h" |
50 | #include "x509.h" |
51 | #include "certs.h" |
52 | #include "xauth.h" /* for xauth_cancel() */ |
53 | #include "connections.h" /* needs id.h */ |
54 | #include "state.h" |
55 | #include "state_db.h" |
56 | #include "ikev1_msgid.h" |
57 | #include "kernel.h" /* needs connections.h */ |
58 | #include "log.h" |
59 | #include "packet.h" /* so we can calculate sizeof(struct isakmp_hdr) */ |
60 | #include "keys.h" /* for free_public_key */ |
61 | #include "rnd.h" |
62 | #include "timer.h" |
63 | #include "whack.h" |
64 | #include "demux.h" /* needs packet.h */ |
65 | #include "pending.h" |
66 | #include "ipsec_doi.h" /* needs demux.h and state.h */ |
67 | #include "crypto.h" |
68 | #include "crypt_symkey.h" |
69 | #include "spdb.h" |
70 | #include "pluto_crypt.h" /* for pluto_crypto_req & pluto_crypto_req_cont */ |
71 | #include "ikev2.h" |
72 | #include "ikev2_redirect.h" |
73 | #include "secrets.h" /* unreference_key() */ |
74 | #include "enum_names.h" |
75 | #include "crypt_dh.h" |
76 | #include "hostpair.h" |
77 | #include "initiate.h" |
78 | #include "kernel.h" |
79 | #include "kernel_xfrm_interface.h" |
80 | #include "iface.h" |
81 | #include "ikev1_send.h" /* for free_v1_messages() */ |
82 | #include "ikev2_send.h" /* for free_v2_messages() */ |
83 | |
84 | #include <pk11pub.h> |
85 | #include <keyhi.h> |
86 | |
87 | #include "ikev2_msgid.h" |
88 | #include "pluto_stats.h" |
89 | #include "ikev2_ipseckey.h" |
90 | #include "ip_address.h" |
91 | #include "ip_info.h" |
92 | #include "ip_selector.h" |
93 | |
94 | bool_Bool uniqueIDs = FALSE0; |
95 | |
96 | /* |
97 | * default global NFLOG group - 0 means no logging |
98 | * Note: variable is only used to display in ipsec status |
99 | * actual work is done outside pluto, by ipsec --checknflog |
100 | */ |
101 | uint16_t pluto_nflog_group = 0; |
102 | |
103 | /* |
104 | * Note: variable is only used to display in ipsec status |
105 | * actual work is done outside pluto, by ipsec _stackmanager |
106 | */ |
107 | uint16_t pluto_xfrmlifetime = 300; |
108 | |
109 | /* |
110 | * Handle for each and every state. |
111 | * |
112 | * XXX: The array finite_states[] is something of a hack until it is |
113 | * figured out if the array or separate objects for each state is |
114 | * better. |
115 | */ |
116 | |
117 | static struct finite_state state_undefined = { |
118 | .kind = STATE_UNDEFINED, |
119 | .name = "STATE_UNDEFINED", |
120 | .short_name = "UNDEFINED", |
121 | .story = "not defined - either very new or dead (internal)", |
122 | .category = CAT_IGNORE, |
123 | }; |
124 | |
125 | static struct finite_state state_ikev1_roof = { |
126 | .kind = STATE_IKEv1_ROOF, |
127 | .name = "STATE_IKEv1_ROOF", |
128 | .short_name = "IKEv1_ROOF", |
129 | .story = "invalid state - IKEv1 roof", |
130 | .category = CAT_IGNORE, |
131 | }; |
132 | |
133 | static struct finite_state state_ikev2_roof = { |
134 | .kind = STATE_IKEv2_ROOF, |
135 | .name = "STATE_IKEv2_ROOF", |
136 | .short_name = "IKEv2_ROOF", |
137 | .story = "invalid state - IKEv2 roof", |
138 | .category = CAT_IGNORE, |
139 | }; |
140 | |
141 | const struct finite_state *finite_states[STATE_IKE_ROOF(STATE_IKEv2_ROOF+1)] = { |
142 | [STATE_UNDEFINED] = &state_undefined, |
143 | [STATE_IKEv1_ROOF] &state_ikev1_roof, |
144 | [STATE_IKEv2_ROOF] &state_ikev2_roof, |
145 | }; |
146 | |
147 | /* |
148 | * Revival mechanism: keep track of connections |
149 | * that should be kept up, even though all their |
150 | * states have been deleted. |
151 | * |
152 | * We record the connection names. |
153 | * Each name is recorded only once. |
154 | * |
155 | * XXX: This functionality totally overlaps both "initiate" and |
156 | * "pending" and should be merged (however, this simple code might |
157 | * prove to be a better starting point). |
158 | */ |
159 | |
160 | struct revival { |
161 | char *name; |
162 | struct revival *next; |
163 | }; |
164 | |
165 | static struct revival *revivals = NULL((void*)0); |
166 | |
167 | /* |
168 | * XXX: Return connection C's revival object's link, if found. If the |
169 | * connection C can't be found, then the address of the revival list's |
170 | * tail is returned. Perhaps, exiting the loop and returning NULL |
171 | * would be more obvious. |
172 | */ |
173 | static struct revival **find_revival(const struct connection *c) |
174 | { |
175 | for (struct revival **rp = &revivals; ; rp = &(*rp)->next) { |
176 | if (*rp == NULL((void*)0) || streq((*rp)->name, c->name)(strcmp(((*rp)->name), (c->name)) == 0)) { |
177 | return rp; |
178 | } |
179 | } |
180 | } |
181 | |
182 | /* |
183 | * XXX: In addition to freeing RP (and killing the pointer), this |
184 | * "free" function has the side effect of unlinks RP from the revival |
185 | * list. Perhaps free*() isn't the best name. |
186 | */ |
187 | static void free_revival(struct revival **rp) |
188 | { |
189 | struct revival *r = *rp; |
190 | *rp = r->next; |
191 | pfree(r->name); |
192 | pfree(r); |
193 | } |
194 | |
195 | void flush_revival(const struct connection *c) |
196 | { |
197 | struct revival **rp = find_revival(c); |
198 | |
199 | if (*rp == NULL((void*)0)) { |
200 | dbg("flush revival: connection '%s' wasn't on the list",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("flush revival: connection '%s' wasn't on the list" , c->name); } } |
201 | c->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("flush revival: connection '%s' wasn't on the list" , c->name); } }; |
202 | } else { |
203 | dbg("flush revival: connection '%s' revival flushed",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("flush revival: connection '%s' revival flushed" , c->name); } } |
204 | c->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("flush revival: connection '%s' revival flushed" , c->name); } }; |
205 | free_revival(rp); |
206 | } |
207 | } |
208 | |
209 | static void add_revival(struct connection *c) |
210 | { |
211 | if (*find_revival(c) == NULL((void*)0)) { |
212 | struct revival *r = alloc_thing(struct revival,((struct revival*) alloc_bytes(sizeof(struct revival), ("revival struct" ))) |
213 | "revival struct")((struct revival*) alloc_bytes(sizeof(struct revival), ("revival struct" ))); |
214 | |
215 | r->name = clone_str(c->name, "revival conn name")((c->name) == ((void*)0) ? ((void*)0) : clone_bytes((c-> name), strlen((c->name)) + 1, ("revival conn name"))); |
216 | r->next = revivals; |
217 | revivals = r; |
218 | int delay = c->temp_vars.revive_delay; |
219 | dbg("add revival: connection '%s' added to the list and scheduled for %d seconds",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("add revival: connection '%s' added to the list and scheduled for %d seconds" , c->name, delay); } } |
220 | c->name, delay){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("add revival: connection '%s' added to the list and scheduled for %d seconds" , c->name, delay); } }; |
221 | c->temp_vars.revive_delay = min(delay + REVIVE_CONN_DELAY,({ typeof(delay + 5) _min1 = (delay + 5); typeof(300) _min2 = (300); (void) (&_min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }) |
222 | REVIVE_CONN_DELAY_MAX)({ typeof(delay + 5) _min1 = (delay + 5); typeof(300) _min2 = (300); (void) (&_min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); |
223 | /* |
224 | * XXX: Schedule the next revival using this |
225 | * connection's revival delay and not the most urgent |
226 | * connection's revival delay. Trying to fix this |
227 | * here just is annoying and probably of marginal |
228 | * benefit: it is something better handled with a |
229 | * proper connection event so that the event loop deal |
230 | * with all the math (this code would then be |
231 | * deleted); and would encroach even further on |
232 | * "initiate" and "pending" functionality. |
233 | */ |
234 | schedule_oneshot_timer(EVENT_REVIVE_CONNS, deltatime(delay)); |
235 | } |
236 | } |
237 | |
238 | void revive_conns(struct fd *unused_whackfd UNUSED__attribute__ ((unused))) |
239 | { |
240 | /* |
241 | * XXX: Revive all listed connections regardless of their |
242 | * DELAY. See note above in add_revival(). |
243 | * |
244 | * XXX: since this is called from the event loop, the global |
245 | * whack_log_fd is invalid so specifying RC isn't exactly |
246 | * useful. |
247 | */ |
248 | while (revivals != NULL((void*)0)) { |
249 | struct connection *c = conn_by_name(revivals->name, |
250 | true1/*strict: don't accept CK_INSTANCE*/); |
251 | /* |
252 | * Above call. with quiet=false, would try to log |
253 | * using whack_log(); but that's useless as the global |
254 | * whack_log_fd is only valid while in the whack |
255 | * handler. |
256 | */ |
257 | if (c == NULL((void*)0)) { |
258 | loglog(RC_UNKNOWN_NAME, "failed to initiate connection \"%s\" which received a Delete/Notify but must remain up per local policy; connection no longer exists", revivals->name); |
259 | } else { |
260 | log_connection(RC_LOG, null_fd((struct fd *) ((void*)0)), c, |
261 | "initiating connection which received a Delete/Notify but must remain up per local policy"); |
262 | if (!initiate_connection(c, NULL((void*)0), null_fd((struct fd *) ((void*)0)), true1/*background*/)) { |
263 | log_connection(RC_FATAL, null_fd((struct fd *) ((void*)0)), c, |
264 | "failed to initiate connection"); |
265 | } |
266 | } |
267 | /* |
268 | * Danger! The free_revival() call removes head, |
269 | * replacing it with the next in the list. |
270 | */ |
271 | free_revival(&revivals); |
272 | } |
273 | } |
274 | |
275 | /* end of revival mechanism */ |
276 | |
277 | void lswlog_finite_state(struct jambuf *buf, const struct finite_state *fs) |
278 | { |
279 | if (fs == NULL((void*)0)) { |
280 | jam_string(buf, "NULL-FINITE_STATE"); |
281 | } else { |
282 | jam(buf, "%s:", fs->short_name); |
283 | jam(buf, " category: "); |
284 | jam_enum_short(buf, &state_category_names, fs->category); |
285 | /* no enum_name available? */ |
286 | jam(buf, "; flags: "PRI_LSET"%""l" "x", fs->flags); |
287 | } |
288 | } |
289 | |
290 | /* state categories */ |
291 | |
292 | static const char *const cat_name[] = { |
293 | [CAT_UNKNOWN] = "unknown", |
294 | [CAT_HALF_OPEN_IKE_SA] = "half-open IKE SA", |
295 | [CAT_OPEN_IKE_SA] = "open IKE SA", |
296 | [CAT_ESTABLISHED_IKE_SA] = "established IKE SA", |
297 | [CAT_ESTABLISHED_CHILD_SA] = "established CHILD SA", |
298 | [CAT_INFORMATIONAL] = "informational", |
299 | [CAT_IGNORE] = "ignore", |
300 | }; |
301 | |
302 | enum_names state_category_names = { |
303 | 0, elemsof(cat_name)(sizeof(cat_name) / sizeof(*(cat_name))) - 1, |
304 | ARRAY_REF(cat_name)(cat_name), (sizeof(cat_name) / sizeof(*(cat_name))), |
305 | "", |
306 | NULL((void*)0) |
307 | }; |
308 | |
309 | /* |
310 | * Track the categories and for ESTABLISHED, also track if the SA was |
311 | * AUTHENTICATED or ANONYMOUS. Among other things used for DDoS |
312 | * tracking. |
313 | * |
314 | * Hack: CAT_T is unsigned (like values it gets compared against), and |
315 | * assumed to be implemented using 2's complement. However, the value |
316 | * is printed as a "signed" value - so that should underflow occur it |
317 | * is displayed as -ve (rather than a huge positive). |
318 | */ |
319 | |
320 | typedef unsigned long cat_t; |
321 | #define PRI_CAT"%ld" "%ld" |
322 | |
323 | static cat_t cat_count[elemsof(cat_name)(sizeof(cat_name) / sizeof(*(cat_name)))] = { 0 }; |
324 | |
325 | /* see .st_ikev2_anon, enum would be better */ |
326 | #define CAT_AUTHENTICATED0 false0 |
327 | #define CAT_ANONYMOUS1 true1 |
328 | static cat_t cat_count_ike_sa[2]; |
329 | static cat_t cat_count_child_sa[2]; |
330 | static cat_t state_count[STATE_IKE_ROOF(STATE_IKEv2_ROOF+1)]; |
331 | |
332 | static cat_t total_ike_sa(void) |
333 | { |
334 | return (cat_count[CAT_HALF_OPEN_IKE_SA] + |
335 | cat_count[CAT_OPEN_IKE_SA] + |
336 | cat_count[CAT_ESTABLISHED_IKE_SA]); |
337 | } |
338 | |
339 | static cat_t total_sa(void) |
340 | { |
341 | return total_ike_sa() + cat_count[CAT_ESTABLISHED_CHILD_SA]; |
342 | } |
343 | |
344 | /* |
345 | * Count everything except STATE_UNDEFINED (CAT_IGNORE) et.al. All |
346 | * states start and end in those states. |
347 | */ |
348 | static void update_state_stat(struct state *st, |
349 | const struct finite_state *state, |
350 | int delta) |
351 | { |
352 | if (state->category != CAT_IGNORE) { |
353 | state_count[state->kind] += delta; |
354 | cat_count[state->category] += delta; |
355 | /* |
356 | * When deleting, st->st_connection can be NULL, so we |
357 | * cannot look at the policy to determine |
358 | * anonymity. We therefore use a scratchpad at |
359 | * st->st_ikev2_anon (a bool) which is copied from |
360 | * parent to child states |
361 | */ |
362 | switch (state->category) { |
363 | case CAT_ESTABLISHED_IKE_SA: |
364 | cat_count_ike_sa[st->st_ikev2_anon] += delta; |
365 | break; |
366 | case CAT_ESTABLISHED_CHILD_SA: |
367 | cat_count_child_sa[st->st_ikev2_anon] += delta; |
368 | break; |
369 | default: /* ignore */ |
370 | break; |
371 | } |
372 | } |
373 | } |
374 | |
375 | static void update_state_stats(struct state *st, |
376 | const struct finite_state *old_state, |
377 | const struct finite_state *new_state) |
378 | { |
379 | /* catch / log unexpected cases */ |
380 | pexpect(old_state->category != CAT_UNKNOWN)({ _Bool assertion__ = old_state->category != CAT_UNKNOWN; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "state.c" , .line = 380}, "%s", "old_state->category != CAT_UNKNOWN" ); } assertion__; }); |
381 | pexpect(new_state->category != CAT_UNKNOWN)({ _Bool assertion__ = new_state->category != CAT_UNKNOWN; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "state.c" , .line = 381}, "%s", "new_state->category != CAT_UNKNOWN" ); } assertion__; }); |
382 | |
383 | update_state_stat(st, old_state, -1); |
384 | update_state_stat(st, new_state, +1); |
385 | |
386 | /* |
387 | * ??? this seems expensive: on each state change we do this |
388 | * whole rigamarole. |
389 | * |
390 | * XXX: It's an assertion check only executed when debugging. |
391 | */ |
392 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { |
393 | DBG_log("%s state #%lu: %s(%s) => %s(%s)", |
394 | IS_IKE_SA(st)((st)->st_clonedfrom == 0) ? "parent" : "child", st->st_serialno, |
395 | old_state->short_name, |
396 | enum_name(&state_category_names, old_state->category), |
397 | new_state->short_name, |
398 | enum_name(&state_category_names, new_state->category)); |
399 | |
400 | cat_t category_states = 0; |
401 | for (unsigned cat = 0; cat < elemsof(cat_count)(sizeof(cat_count) / sizeof(*(cat_count))); cat++) { |
402 | category_states += cat_count[cat]; |
403 | } |
404 | |
405 | cat_t count_states = 0; |
406 | for (unsigned s = 0; s < elemsof(state_count)(sizeof(state_count) / sizeof(*(state_count))); s++) { |
407 | count_states += state_count[s]; |
408 | } |
409 | |
410 | if (category_states != count_states) { |
411 | /* not really ST's fault? */ |
412 | pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 412}, |
413 | "category states: "PRI_CAT"%ld"" != count states: "PRI_CAT"%ld", |
414 | category_states, count_states); |
415 | } |
416 | |
417 | if (cat_count[CAT_ESTABLISHED_IKE_SA] != |
418 | (cat_count_ike_sa[CAT_AUTHENTICATED0] + cat_count_ike_sa[CAT_ANONYMOUS1])) { |
419 | /* not really ST's fault? */ |
420 | pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 420}, |
421 | "established IKE SA: "PRI_CAT"%ld"" != authenticated: "PRI_CAT"%ld"" + anoynmous: "PRI_CAT"%ld", |
422 | cat_count[CAT_ESTABLISHED_IKE_SA], |
423 | cat_count_ike_sa[CAT_AUTHENTICATED0], |
424 | cat_count_ike_sa[CAT_ANONYMOUS1]); |
425 | } |
426 | |
427 | if (cat_count[CAT_ESTABLISHED_CHILD_SA] != |
428 | (cat_count_child_sa[CAT_AUTHENTICATED0] + cat_count_child_sa[CAT_ANONYMOUS1])) { |
429 | /* not really ST's fault? */ |
430 | pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 430}, |
431 | "established CHILD SA: "PRI_CAT"%ld"" != authenticated: "PRI_CAT"%ld"" + anoynmous: "PRI_CAT"%ld", |
432 | cat_count[CAT_ESTABLISHED_CHILD_SA], |
433 | cat_count_child_sa[CAT_AUTHENTICATED0], |
434 | cat_count_child_sa[CAT_ANONYMOUS1]); |
435 | } |
436 | } |
437 | } |
438 | |
439 | /* |
440 | * This file has the functions that handle the |
441 | * state hash table and the Message ID list. |
442 | */ |
443 | |
444 | void change_state(struct state *st, enum state_kind new_state_kind) |
445 | { |
446 | const struct finite_state *old_state = st->st_state; |
447 | const struct finite_state *new_state = finite_states[new_state_kind]; |
448 | passert(new_state != NULL){ _Bool assertion__ = new_state != ((void*)0); if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 448}, "%s", "new_state != NULL"); } }; |
449 | if (new_state != old_state) { |
450 | update_state_stats(st, old_state, new_state); |
451 | binlog_state(st, new_state_kind /* XXX */); |
452 | st->st_state = new_state; |
453 | } |
454 | } |
455 | |
456 | /* |
457 | * readable_humber: make large numbers clearer by expressing them as KB or MB, |
458 | * as appropriate. |
459 | * The prefix is literally copied into the output. |
460 | * Tricky representation: if the prefix starts with !, the number |
461 | * is taken as kilobytes. Thus the caller can avoid scaling, with its |
462 | * risk of overflow. The ! is not printed. |
463 | */ |
464 | static char *readable_humber(uint64_t num, |
465 | char *buf, |
466 | const char *buf_roof, |
467 | const char *prefix) |
468 | { |
469 | size_t buf_len = buf_roof - buf; |
470 | uint64_t to_print = num; |
471 | const char *suffix; |
472 | int ret; |
473 | bool_Bool kilos = prefix[0] == '!'; |
474 | |
475 | if (!kilos && num < 1024) { |
476 | suffix = "B"; |
477 | } else { |
478 | if (!kilos) |
479 | to_print /= 1024; |
480 | |
481 | if (to_print < 1024) { |
482 | suffix = "KB"; |
483 | } else { |
484 | to_print /= 1024; |
485 | suffix = "MB"; |
486 | } |
487 | } |
488 | |
489 | ret = snprintf(buf, buf_len, "%s%" PRIu64"l" "u" "%s", prefix, to_print, |
490 | suffix + kilos); |
491 | if (ret < 0 || (size_t) ret >= buf_len) |
492 | return buf; |
493 | |
494 | return buf + ret; |
495 | } |
496 | |
497 | /* |
498 | * Get the IKE SA managing the security association. |
499 | */ |
500 | |
501 | struct ike_sa *ike_sa(struct state *st, where_t where) |
502 | { |
503 | if (st != NULL((void*)0) && IS_CHILD_SA(st)((st)->st_clonedfrom != 0)) { |
504 | struct state *pst = state_by_serialno(st->st_clonedfrom); |
505 | if (pst == NULL((void*)0)) { |
506 | pexpect_fail(st->st_logger, where, "child state #%lu missing parent state #%lu", |
507 | st->st_serialno, st->st_clonedfrom); |
508 | /* about to crash with an NPE */ |
509 | } |
510 | return (struct ike_sa*) pst; |
511 | } |
512 | return (struct ike_sa*) st; |
513 | } |
514 | |
515 | struct ike_sa *pexpect_ike_sa(struct state *st) |
516 | { |
517 | if (st == NULL((void*)0)) { |
518 | return NULL((void*)0); |
519 | } |
520 | if (!IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { |
521 | pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 521}, |
522 | "state #%lu is not an IKE SA", st->st_serialno); |
523 | return NULL((void*)0); /* kaboom */ |
524 | } |
525 | return (struct ike_sa*) st; |
526 | } |
527 | |
528 | struct child_sa *pexpect_child_sa(struct state *st) |
529 | { |
530 | if (st == NULL((void*)0)) { |
531 | return NULL((void*)0); |
532 | } |
533 | if (!IS_CHILD_SA(st)((st)->st_clonedfrom != 0)) { |
534 | /* In IKEv2 a re-keying IKE SA starts life as a child */ |
535 | pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 535}, |
536 | "state #%lu is not a CHILD", st->st_serialno); |
537 | return NULL((void*)0); /* kaboom */ |
538 | } |
539 | return (struct child_sa*) st; |
540 | } |
541 | |
542 | union sas { struct child_sa child; struct ike_sa ike; struct state st; }; |
543 | |
544 | /* |
545 | * Get a state object. |
546 | * Caller must schedule an event for this object so that it doesn't leak. |
547 | * Caller must insert_state(). |
548 | */ |
549 | |
550 | static struct state *new_state(enum ike_version ike_version, |
551 | const ike_spi_t ike_initiator_spi, |
552 | const ike_spi_t ike_responder_spi, |
553 | enum sa_type sa_type, struct fd *whackfd) |
554 | { |
555 | static so_serial_t next_so = SOS_FIRST1; |
556 | union sas *sas = alloc_thing(union sas, "struct state in new_state()")((union sas*) alloc_bytes(sizeof(union sas), ("struct state in new_state()" ))); |
557 | passert(&sas->st == &sas->child.sa){ _Bool assertion__ = &sas->st == &sas->child.sa ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "state.c" , .line = 557}, "%s", "&sas->st == &sas->child.sa" ); } }; |
558 | passert(&sas->st == &sas->ike.sa){ _Bool assertion__ = &sas->st == &sas->ike.sa; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "state.c" , .line = 558}, "%s", "&sas->st == &sas->ike.sa" ); } }; |
559 | struct state *st = &sas->st; |
560 | *st = (struct state) { |
561 | .st_state = &state_undefined, |
562 | .st_serialno = next_so++, |
563 | .st_inception = realnow(), |
564 | .st_ike_version = ike_version, |
565 | .st_establishing_sa = sa_type, |
566 | .st_ike_spis = { |
567 | .initiator = ike_initiator_spi, |
568 | .responder = ike_responder_spi, |
569 | }, |
570 | }; |
571 | passert(next_so > SOS_FIRST){ _Bool assertion__ = next_so > 1; if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "state.c" , .line = 571}, "%s", "next_so > SOS_FIRST"); } }; /* overflow can't happen! */ |
572 | |
573 | st->st_logger = alloc_logger(st, &logger_state_vec, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 573}); |
574 | st->st_logger->object_whackfd = dup_any(whackfd)dup_any_fd((whackfd), (where_t) { .func = __func__, .basename = "state.c" , .line = 574}); |
575 | |
576 | st->hidden_variables.st_nat_oa = address_any(&ipv4_info); |
577 | st->hidden_variables.st_natd = address_any(&ipv4_info); |
578 | |
579 | dbg("creating state object #%lu at %p", st->st_serialno, (void *) st){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("creating state object #%lu at %p", st->st_serialno , (void *) st); } }; |
580 | add_state_to_db(st); |
581 | pstat_sa_started(st, sa_type); |
582 | |
583 | return st; |
584 | } |
585 | |
586 | struct ike_sa *new_v1_istate(struct fd *whackfd) |
587 | { |
588 | struct state *st = new_state(IKEv1, ike_initiator_spi(), |
589 | zero_ike_spi, IKE_SA, whackfd); |
590 | struct ike_sa *ike = pexpect_ike_sa(st); |
591 | return ike; |
592 | } |
593 | |
594 | struct ike_sa *new_v1_rstate(struct msg_digest *md) |
595 | { |
596 | struct state *st = new_state(IKEv1, md->hdr.isa_ike_spis.initiator, |
597 | ike_responder_spi(&md->sender, md->md_logger), |
598 | IKE_SA, null_fd((struct fd *) ((void*)0))); |
599 | struct ike_sa *ike = pexpect_ike_sa(st); |
600 | update_ike_endpoints(ike, md); |
601 | return ike; |
602 | } |
603 | |
604 | struct ike_sa *new_v2_ike_state(const struct state_v2_microcode *transition, |
605 | enum sa_role sa_role, |
606 | const ike_spi_t ike_initiator_spi, |
607 | const ike_spi_t ike_responder_spi, |
608 | struct connection *c, lset_t policy, |
609 | int try, struct fd *whack_sock) |
610 | { |
611 | struct state *st = new_state(IKEv2, ike_initiator_spi, ike_responder_spi, |
612 | IKE_SA, whack_sock); |
613 | struct ike_sa *ike = pexpect_ike_sa(st); |
614 | ike->sa.st_sa_role = sa_role; |
615 | const struct finite_state *fs = finite_states[transition->state]; |
616 | change_state(&ike->sa, fs->kind); |
617 | set_v2_transition(&ike->sa, transition, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 617}); |
618 | v2_msgid_init_ike(ike); |
619 | initialize_new_state(&ike->sa, c, policy, try); |
620 | return ike; |
621 | } |
622 | |
623 | /* |
624 | * Initialize the state table. |
625 | */ |
626 | void init_states(void) |
627 | { |
628 | /* did IKEv1/IKEv2 do their job? */ |
629 | for (unsigned kind = 0; kind < elemsof(finite_states)(sizeof(finite_states) / sizeof(*(finite_states))); kind++) { |
630 | const struct finite_state *s = finite_states[kind]; |
631 | passert(s != NULL){ _Bool assertion__ = s != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "state.c" , .line = 631}, "%s", "s != NULL"); } }; |
632 | passert(s->name != NULL){ _Bool assertion__ = s->name != ((void*)0); if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 632}, "%s", "s->name != NULL"); } }; |
633 | passert(s->short_name != NULL){ _Bool assertion__ = s->short_name != ((void*)0); if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 633}, "%s", "s->short_name != NULL"); } }; |
634 | passert(s->story != NULL){ _Bool assertion__ = s->story != ((void*)0); if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 634}, "%s", "s->story != NULL"); } }; |
635 | passert(s->kind == kind){ _Bool assertion__ = s->kind == kind; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 635}, "%s", "s->kind == kind"); } }; |
636 | passert(s->category != CAT_UNKNOWN){ _Bool assertion__ = s->category != CAT_UNKNOWN; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 636}, "%s", "s->category != CAT_UNKNOWN" ); } }; |
637 | } |
638 | init_oneshot_timer(EVENT_REVIVE_CONNS, revive_conns); |
639 | } |
640 | |
641 | void delete_state_by_id_name(struct state *st, void *name) |
642 | { |
643 | struct connection *c = st->st_connection; |
644 | |
645 | if (!IS_IKE_SA(st)((st)->st_clonedfrom == 0)) |
646 | return; |
647 | |
648 | id_buf thatidb; |
649 | const char *thatidbuf = str_id(&c->spd.that.id, &thatidb); |
650 | if (streq(thatidbuf, name)(strcmp((thatidbuf), (name)) == 0)) { |
651 | delete_ike_family(pexpect_ike_sa(st), PROBABLY_SEND_DELETE); |
652 | /* note: no md->st to clear */ |
653 | } |
654 | } |
655 | |
656 | void v1_delete_state_by_username(struct state *st, void *name) |
657 | { |
658 | /* only support deleting ikev1 with XAUTH username */ |
659 | if (st->st_ike_version == IKEv2) |
660 | return; |
661 | |
662 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0) && streq(st->st_xauth_username, name)(strcmp((st->st_xauth_username), (name)) == 0)) { |
663 | delete_ike_family(pexpect_ike_sa(st), PROBABLY_SEND_DELETE); |
664 | /* note: no md->st to clear */ |
665 | } |
666 | } |
667 | |
668 | /* |
669 | * Find the state object with this serial number. This allows state |
670 | * object references that don't turn into dangerous dangling pointers: |
671 | * reference a state by its serial number. Returns NULL if there is |
672 | * no such state. |
673 | */ |
674 | struct state *state_with_serialno(so_serial_t sn) |
675 | { |
676 | return state_by_serialno(sn); |
677 | } |
678 | |
679 | /* |
680 | * Re-insert the state in the database after updating the RCOOKIE, and |
681 | * possibly the ICOOKIE. |
682 | * |
683 | * ICOOKIE is only updated if icookie != NULL |
684 | */ |
685 | void rehash_state(struct state *st, const ike_spi_t *ike_responder_spi) |
686 | { |
687 | /* update the responder's SPI */ |
688 | st->st_ike_spis.responder = *ike_responder_spi; |
689 | /* now, update the state */ |
690 | rehash_state_cookies_in_db(st); |
691 | /* just logs change */ |
692 | binlog_refresh_state(st)binlog_state((st), (st)->st_state->kind); |
693 | } |
694 | |
695 | /* |
696 | * Free the Whack socket file descriptor. |
697 | * This has the side effect of telling Whack that we're done. |
698 | */ |
699 | void release_any_whack(struct state *st, where_t where, const char *why) |
700 | { |
701 | dbg("releasing #%lu's "PRI_FD" because %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("releasing #%lu's ""fd-fd@%p"" because %s", st ->st_serialno, (st->st_logger->object_whackfd), why) ; } } |
702 | st->st_serialno, pri_fd(st->st_whack_sock), why){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("releasing #%lu's ""fd-fd@%p"" because %s", st ->st_serialno, (st->st_logger->object_whackfd), why) ; } }; |
703 | close_any_fd(&st->st_logger->object_whackfd, where); |
704 | close_any_fd(&st->st_logger->global_whackfd, where); |
705 | } |
706 | |
707 | void v2_expire_unused_ike_sa(struct ike_sa *ike) |
708 | { |
709 | passert(ike != NULL){ _Bool assertion__ = ike != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "state.c" , .line = 709}, "%s", "ike != NULL"); } }; |
710 | passert(ike->sa.st_ike_version == IKEv2){ _Bool assertion__ = ike->sa.st_ike_version == IKEv2; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "state.c" , .line = 710}, "%s", "ike->sa.st_ike_version == IKEv2" ); } }; |
711 | |
712 | if (!IS_PARENT_SA_ESTABLISHED(&ike->sa)(((&ike->sa)->st_state->kind == STATE_V2_ESTABLISHED_IKE_SA ) && !((&ike->sa)->st_clonedfrom != 0))) { |
713 | dbg("can't expire unused IKE SA #%lu; not established - strange",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("can't expire unused IKE SA #%lu; not established - strange" , ike->sa.st_serialno); } } |
714 | ike->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("can't expire unused IKE SA #%lu; not established - strange" , ike->sa.st_serialno); } }; |
715 | return; /* only deal with established parent SA */ |
716 | } |
717 | |
718 | /* Any children? */ |
719 | struct state *st = state_by_ike_spis(IKEv2, |
720 | &ike->sa.st_serialno, |
721 | NULL((void*)0)/* ignore v1 msgid */, |
722 | NULL((void*)0)/* ignore role */, |
723 | &ike->sa.st_ike_spis, |
724 | NULL((void*)0), NULL((void*)0) /* no predicate */, |
725 | __func__); |
726 | if (st != NULL((void*)0)) { |
727 | dbg("can't expire unused IKE SA #%lu; it has the child #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("can't expire unused IKE SA #%lu; it has the child #%lu" , ike->sa.st_serialno, st->st_serialno); } } |
728 | ike->sa.st_serialno, st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("can't expire unused IKE SA #%lu; it has the child #%lu" , ike->sa.st_serialno, st->st_serialno); } }; |
729 | return; |
730 | } |
731 | |
732 | { |
733 | char cib[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)]; |
734 | struct connection *c = ike->sa.st_connection; |
735 | loglog(RC_INFORMATIONAL, "expire unused IKE SA #%lu \"%s\"%s", |
736 | ike->sa.st_serialno, c->name, |
737 | fmt_conn_instance(c, cib)); |
738 | event_force(EVENT_SA_EXPIRE, &ike->sa); |
739 | } |
740 | } |
741 | |
742 | |
743 | /* |
744 | * XXX: This is broken on IKEv2. It schedules a replace event for |
745 | * each child except that fires _after_ the IKE SA has been deleted. |
746 | * Should it schedule pending events? |
747 | */ |
748 | |
749 | static bool_Bool flush_incomplete_child(struct state *st, void *pst UNUSED__attribute__ ((unused))) |
750 | { |
751 | if (!IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA))) { |
752 | |
753 | char cib[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)]; |
754 | struct connection *c = st->st_connection; |
755 | |
756 | so_serial_t newest_sa; |
757 | switch (st->st_establishing_sa) { |
758 | case IKE_SA: newest_sa = c->newest_isakmp_sa; break; |
759 | case IPSEC_SA: newest_sa = c->newest_ipsec_sa; break; |
760 | default: bad_case(st->st_establishing_sa)libreswan_bad_case("st->st_establishing_sa", (st->st_establishing_sa ), (where_t) { .func = __func__, .basename = "state.c" , .line = 760}); |
761 | } |
762 | |
763 | if (st->st_serialno > newest_sa && |
764 | (c->policy & POLICY_UP((lset_t)1 << (POLICY_UP_IX))) && |
765 | (c->policy & POLICY_DONT_REKEY((lset_t)1 << (POLICY_DONT_REKEY_IX))) == LEMPTY((lset_t)0)) { |
766 | loglog(RC_LOG_SERIOUS, "reschedule pending child #%lu %s of " |
767 | "connection \"%s\"%s - the parent is going away", |
768 | st->st_serialno, st->st_state->name, |
769 | c->name, fmt_conn_instance(c, cib)); |
770 | |
771 | st->st_policy = c->policy; /* for pick_initiator */ |
772 | event_force(EVENT_SA_REPLACE, st); |
773 | } else { |
774 | loglog(RC_LOG_SERIOUS, "expire pending child #%lu %s of " |
775 | "connection \"%s\"%s - the parent is going away", |
776 | st->st_serialno, st->st_state->name, |
777 | c->name, fmt_conn_instance(c, cib)); |
778 | |
779 | event_force(EVENT_SA_EXPIRE, st); |
780 | } |
781 | /* |
782 | * Shut down further logging for the child, above are |
783 | * the last whack will hear from them. |
784 | */ |
785 | release_any_whack(st, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 785}, "IKE going away"); |
786 | } |
787 | /* |
788 | * XXX: why was this non-conditional? probably doesn't matter |
789 | * as it is idenpotent? |
790 | */ |
791 | delete_cryptographic_continuation(st); |
792 | return false0; /* keep going */ |
793 | } |
794 | |
795 | static void flush_incomplete_children(struct ike_sa *ike) |
796 | { |
797 | state_by_ike_spis(ike->sa.st_ike_version, |
798 | &ike->sa.st_serialno, |
799 | NULL((void*)0) /* ignore MSGID */, |
800 | NULL((void*)0) /* ignore role */, |
801 | &ike->sa.st_ike_spis, |
802 | flush_incomplete_child, NULL((void*)0)/*arg*/, __func__); |
803 | } |
804 | |
805 | static bool_Bool should_send_delete(const struct state *st) |
806 | { |
807 | if (st->st_dont_send_delete) { |
808 | dbg("%s: no, just because", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: no, just because", __func__); } }; |
809 | return false0; |
810 | } |
811 | |
812 | if (!IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA)) && |
813 | !IS_ISAKMP_SA_ESTABLISHED(st->st_state)((((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))) { |
814 | dbg("%s: no, not established", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: no, not established", __func__); } }; |
815 | return false0; |
816 | } |
817 | |
818 | if ((st->st_ike_version == IKEv2) && |
819 | IS_CHILD_SA(st)((st)->st_clonedfrom != 0) && |
820 | state_with_serialno(st->st_clonedfrom) == NULL((void*)0)) { |
821 | /* |
822 | * ??? in v2, there must be a parent |
823 | * |
824 | * XXX: except when delete_state(ike), instead of |
825 | * delete_ike_family(ike), is called ... |
826 | * |
827 | * Without an IKE SA sending the notify isn't |
828 | * possible. |
829 | */ |
830 | dbg("%s: no, lost parent; suspect IKE SA was deleted without deleting children", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: no, lost parent; suspect IKE SA was deleted without deleting children" , __func__); } }; |
831 | return false0; |
832 | } |
833 | |
834 | dbg("%s: yes", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: yes", __func__); } }; |
835 | return true1; |
836 | } |
837 | |
838 | static void delete_state_log(struct state *st, struct state *cur_state) |
839 | { |
840 | struct connection *const c = st->st_connection; |
841 | bool_Bool del_notify = !impair.send_no_delete && should_send_delete(st); |
842 | |
843 | if (cur_state != NULL((void*)0) && cur_state == st) { |
844 | /* |
845 | * Don't log state and connection if it is the same as |
846 | * the message prefix. |
847 | */ |
848 | deltatime_buf dtb; |
849 | libreswan_log("deleting state (%s) aged %ss and %ssending notification",loglog(RC_LOG, "deleting state (%s) aged %ss and %ssending notification" , st->st_state->name, str_deltatime(realtimediff(realnow (), st->st_inception), &dtb), del_notify ? "" : "NOT " ) |
850 | st->st_state->name,loglog(RC_LOG, "deleting state (%s) aged %ss and %ssending notification" , st->st_state->name, str_deltatime(realtimediff(realnow (), st->st_inception), &dtb), del_notify ? "" : "NOT " ) |
851 | str_deltatime(realtimediff(realnow(), st->st_inception), &dtb),loglog(RC_LOG, "deleting state (%s) aged %ss and %ssending notification" , st->st_state->name, str_deltatime(realtimediff(realnow (), st->st_inception), &dtb), del_notify ? "" : "NOT " ) |
852 | del_notify ? "" : "NOT ")loglog(RC_LOG, "deleting state (%s) aged %ss and %ssending notification" , st->st_state->name, str_deltatime(realtimediff(realnow (), st->st_inception), &dtb), del_notify ? "" : "NOT " ); |
853 | } else if (cur_state != NULL((void*)0) && cur_state->st_connection == st->st_connection) { |
854 | deltatime_buf dtb; |
855 | libreswan_log("deleting other state #%lu (%s) aged %ss and %ssending notification",loglog(RC_LOG, "deleting other state #%lu (%s) aged %ss and %ssending notification" , st->st_serialno, st->st_state->name, str_deltatime (realtimediff(realnow(), st->st_inception), &dtb), del_notify ? "" : "NOT ") |
856 | st->st_serialno, st->st_state->name,loglog(RC_LOG, "deleting other state #%lu (%s) aged %ss and %ssending notification" , st->st_serialno, st->st_state->name, str_deltatime (realtimediff(realnow(), st->st_inception), &dtb), del_notify ? "" : "NOT ") |
857 | str_deltatime(realtimediff(realnow(), st->st_inception), &dtb),loglog(RC_LOG, "deleting other state #%lu (%s) aged %ss and %ssending notification" , st->st_serialno, st->st_state->name, str_deltatime (realtimediff(realnow(), st->st_inception), &dtb), del_notify ? "" : "NOT ") |
858 | del_notify ? "" : "NOT ")loglog(RC_LOG, "deleting other state #%lu (%s) aged %ss and %ssending notification" , st->st_serialno, st->st_state->name, str_deltatime (realtimediff(realnow(), st->st_inception), &dtb), del_notify ? "" : "NOT "); |
859 | } else { |
860 | deltatime_buf dtb; |
861 | connection_buf cib; |
862 | libreswan_log("deleting other state #%lu connection (%s) "PRI_CONNECTION" aged %ss and %ssending notification",loglog(RC_LOG, "deleting other state #%lu connection (%s) ""\"%s\"%s" " aged %ss and %ssending notification", st->st_serialno, st ->st_state->name, (c)->name, str_connection_instance (c, &cib), str_deltatime(realtimediff(realnow(), st->st_inception ), &dtb), del_notify ? "" : "NOT ") |
863 | st->st_serialno, st->st_state->name,loglog(RC_LOG, "deleting other state #%lu connection (%s) ""\"%s\"%s" " aged %ss and %ssending notification", st->st_serialno, st ->st_state->name, (c)->name, str_connection_instance (c, &cib), str_deltatime(realtimediff(realnow(), st->st_inception ), &dtb), del_notify ? "" : "NOT ") |
864 | pri_connection(c, &cib),loglog(RC_LOG, "deleting other state #%lu connection (%s) ""\"%s\"%s" " aged %ss and %ssending notification", st->st_serialno, st ->st_state->name, (c)->name, str_connection_instance (c, &cib), str_deltatime(realtimediff(realnow(), st->st_inception ), &dtb), del_notify ? "" : "NOT ") |
865 | str_deltatime(realtimediff(realnow(), st->st_inception), &dtb),loglog(RC_LOG, "deleting other state #%lu connection (%s) ""\"%s\"%s" " aged %ss and %ssending notification", st->st_serialno, st ->st_state->name, (c)->name, str_connection_instance (c, &cib), str_deltatime(realtimediff(realnow(), st->st_inception ), &dtb), del_notify ? "" : "NOT ") |
866 | del_notify ? "" : "NOT ")loglog(RC_LOG, "deleting other state #%lu connection (%s) ""\"%s\"%s" " aged %ss and %ssending notification", st->st_serialno, st ->st_state->name, (c)->name, str_connection_instance (c, &cib), str_deltatime(realtimediff(realnow(), st->st_inception ), &dtb), del_notify ? "" : "NOT "); |
867 | } |
868 | |
869 | dbg("%s state #%lu: %s(%s) => delete",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s state #%lu: %s(%s) => delete", ((st)-> st_clonedfrom == 0) ? "parent" : "child", st->st_serialno, st->st_state->short_name, enum_name(&state_category_names , st->st_state->category)); } } |
870 | IS_IKE_SA(st) ? "parent" : "child", st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s state #%lu: %s(%s) => delete", ((st)-> st_clonedfrom == 0) ? "parent" : "child", st->st_serialno, st->st_state->short_name, enum_name(&state_category_names , st->st_state->category)); } } |
871 | st->st_state->short_name,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s state #%lu: %s(%s) => delete", ((st)-> st_clonedfrom == 0) ? "parent" : "child", st->st_serialno, st->st_state->short_name, enum_name(&state_category_names , st->st_state->category)); } } |
872 | enum_name(&state_category_names, st->st_state->category)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s state #%lu: %s(%s) => delete", ((st)-> st_clonedfrom == 0) ? "parent" : "child", st->st_serialno, st->st_state->short_name, enum_name(&state_category_names , st->st_state->category)); } }; |
873 | } |
874 | |
875 | static v2_msgid_pending_cb ikev2_send_delete_continue; |
876 | |
877 | static stf_status ikev2_send_delete_continue(struct ike_sa *ike UNUSED__attribute__ ((unused)), |
878 | struct state *st, |
879 | struct msg_digest *md UNUSED__attribute__ ((unused))) |
880 | { |
881 | if (should_send_delete(st)) { |
882 | send_delete(st); |
883 | st->st_dont_send_delete = true1; |
884 | dbg("%s Marked IPSEC state #%lu to suppress sending delete notify", __func__, st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s Marked IPSEC state #%lu to suppress sending delete notify" , __func__, st->st_serialno); } }; |
885 | } |
886 | |
887 | delete_state(st); |
888 | return STF_OK; |
889 | } |
890 | |
891 | void schedule_next_child_delete(struct state *st, struct ike_sa *ike) |
892 | { |
893 | if (st->st_ike_version == IKEv2 && |
894 | should_send_delete(st)) { |
895 | /* pre delete check for slot to send delete message */ |
896 | struct v2_msgid_window *initiator = &ike->sa.st_v2_msgid_windows.initiator; |
897 | intmax_t unack = (initiator->sent - initiator->recv); |
898 | if (unack >= ike->sa.st_connection->ike_window) { |
899 | dbg_v2_msgid(ike, st, "next initiator (send delete) blocked by outstanding response (unack %jd). add delete to Q", unack); |
900 | v2_msgid_queue_initiator(ike, st, ISAKMP_v2_INFORMATIONAL, |
901 | NULL((void*)0), ikev2_send_delete_continue); |
902 | return; |
903 | } |
904 | } |
905 | delete_state(st); |
906 | st = NULL((void*)0); |
907 | v2_expire_unused_ike_sa(ike); |
908 | } |
909 | |
910 | /* delete a state object */ |
911 | void delete_state(struct state *st) |
912 | { |
913 | struct connection *const c = st->st_connection; |
914 | pstat_sa_deleted(st); |
915 | |
916 | /* |
917 | * Even though code tries to always track CPU time, only log |
918 | * it when debugging - values range from very approximate to |
919 | * (in the case of IKEv1) simply wrong. |
920 | */ |
921 | if (DBGP(DBG_CPU_USAGE)(cur_debugging & (((lset_t)1 << (DBG_CPU_USAGE_IX)) )) || DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { |
922 | DBG_log("#%lu main thread "PRI_CPU_USAGE"spent %.3g (%.3g) milliseconds"" helper thread "PRI_CPU_USAGE"spent %.3g (%.3g) milliseconds"" in total", |
923 | st->st_serialno, |
924 | pri_cpu_usage(st->st_timing.main_usage)((st->st_timing.main_usage).thread_seconds * 1000), ((st-> st_timing.main_usage).wall_seconds * 1000), |
925 | pri_cpu_usage(st->st_timing.helper_usage)((st->st_timing.helper_usage).thread_seconds * 1000), ((st ->st_timing.helper_usage).wall_seconds * 1000)); |
926 | } |
927 | |
928 | so_serial_t old_serialno = push_cur_state(st)log_push_state(st, (where_t) { .func = __func__, .basename = "state.c" , .line = 928}); |
929 | delete_state_log(st, state_by_serialno(old_serialno)); |
930 | |
931 | /* |
932 | * IKEv2 IKE failures are logged in the state transition conpletion. |
933 | * IKEv1 IKE failures do not go through a transition, so we catch |
934 | * these in delete_state() |
935 | */ |
936 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0) && st->st_ike_version == IKEv1 && |
937 | !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)))) { |
938 | linux_audit_conn(st, LAK_PARENT_FAIL); |
939 | } |
940 | |
941 | /* |
942 | * only log parent state deletes, we log children in |
943 | * ipsec_delete_sa() |
944 | */ |
945 | if (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))) || st->st_state->kind == STATE_IKESA_DEL) |
946 | linux_audit_conn(st, LAK_PARENT_DESTROY); |
947 | |
948 | /* If we are failed OE initiator, make shunt bare */ |
949 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0) && (c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) && |
950 | (st->st_state->kind == STATE_PARENT_I1 || |
951 | st->st_state->kind == STATE_PARENT_I2)) { |
952 | ipsec_spi_t failure_shunt = shunt_policy_spi(c, FALSE0 /* failure_shunt */); |
953 | ipsec_spi_t nego_shunt = shunt_policy_spi(c, TRUE1 /* negotiation shunt */); |
954 | |
955 | dbg("OE: delete_state orphaning hold with failureshunt %s (negotiation shunt would have been %s)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("OE: delete_state orphaning hold with failureshunt %s (negotiation shunt would have been %s)" , enum_short_name(&spi_names, failure_shunt), enum_short_name (&spi_names, nego_shunt)); } } |
956 | enum_short_name(&spi_names, failure_shunt),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("OE: delete_state orphaning hold with failureshunt %s (negotiation shunt would have been %s)" , enum_short_name(&spi_names, failure_shunt), enum_short_name (&spi_names, nego_shunt)); } } |
957 | enum_short_name(&spi_names, nego_shunt)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("OE: delete_state orphaning hold with failureshunt %s (negotiation shunt would have been %s)" , enum_short_name(&spi_names, failure_shunt), enum_short_name (&spi_names, nego_shunt)); } }; |
958 | |
959 | if (!orphan_holdpass(c, &c->spd, c->spd.this.protocol, failure_shunt)) { |
960 | loglog(RC_LOG_SERIOUS, "orphan_holdpass() failure ignored"); |
961 | } |
962 | } |
963 | |
964 | if (IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA))) { |
965 | /* pull in the traffic counters into state before they're lost */ |
966 | if (!get_sa_info(st, FALSE0, NULL((void*)0))) { |
967 | libreswan_log("failed to pull traffic counters from outbound IPsec SA")loglog(RC_LOG, "failed to pull traffic counters from outbound IPsec SA" ); |
968 | } |
969 | if (!get_sa_info(st, TRUE1, NULL((void*)0))) { |
970 | libreswan_log("failed to pull traffic counters from inbound IPsec SA")loglog(RC_LOG, "failed to pull traffic counters from inbound IPsec SA" ); |
971 | } |
972 | |
973 | /* |
974 | * Note that a state/SA can have more then one of |
975 | * ESP/AH/IPCOMP |
976 | */ |
977 | if (st->st_esp.present) { |
978 | char statebuf[1024]; |
979 | char *sbcp = readable_humber(st->st_esp.our_bytes, |
980 | statebuf, |
981 | statebuf + sizeof(statebuf), |
982 | "ESP traffic information: in="); |
983 | |
984 | (void)readable_humber(st->st_esp.peer_bytes, |
985 | sbcp, |
986 | statebuf + sizeof(statebuf), |
987 | " out="); |
988 | loglog(RC_INFORMATIONAL, "%s%s%s", |
989 | statebuf, |
990 | st->st_xauth_username[0] != '\0' ? " XAUTHuser=" : "", |
991 | st->st_xauth_username); |
992 | pstats_ipsec_in_bytes += st->st_esp.our_bytes; |
993 | pstats_ipsec_out_bytes += st->st_esp.peer_bytes; |
994 | } |
995 | |
996 | if (st->st_ah.present) { |
997 | char statebuf[1024]; |
998 | char *sbcp = readable_humber(st->st_ah.peer_bytes, |
999 | statebuf, |
1000 | statebuf + sizeof(statebuf), |
1001 | "AH traffic information: in="); |
1002 | |
1003 | (void)readable_humber(st->st_ah.our_bytes, |
1004 | sbcp, |
1005 | statebuf + sizeof(statebuf), |
1006 | " out="); |
1007 | loglog(RC_INFORMATIONAL, "%s%s%s", |
1008 | statebuf, |
1009 | st->st_xauth_username[0] != '\0' ? " XAUTHuser=" : "", |
1010 | st->st_xauth_username); |
1011 | pstats_ipsec_in_bytes += st->st_ah.peer_bytes; |
1012 | pstats_ipsec_out_bytes += st->st_ah.our_bytes; |
1013 | } |
1014 | |
1015 | if (st->st_ipcomp.present) { |
1016 | char statebuf[1024]; |
1017 | char *sbcp = readable_humber(st->st_ipcomp.peer_bytes, |
1018 | statebuf, |
1019 | statebuf + sizeof(statebuf), |
1020 | "IPCOMP traffic information: in="); |
1021 | |
1022 | (void)readable_humber(st->st_ipcomp.our_bytes, |
1023 | sbcp, |
1024 | statebuf + sizeof(statebuf), |
1025 | " out="); |
1026 | loglog(RC_INFORMATIONAL, "%s%s%s", |
1027 | statebuf, |
1028 | st->st_xauth_username[0] != '\0' ? " XAUTHuser=" : "", |
1029 | st->st_xauth_username); |
1030 | pstats_ipsec_in_bytes += st->st_ipcomp.peer_bytes; |
1031 | pstats_ipsec_out_bytes += st->st_ipcomp.our_bytes; |
1032 | } |
1033 | } |
1034 | |
1035 | #ifdef XAUTH_HAVE_PAM1 |
1036 | if (st->st_xauth != NULL((void*)0)) { |
1037 | xauth_pam_abort(st); |
1038 | } |
1039 | #endif |
1040 | |
1041 | event_delete(EVENT_DPD, st); |
1042 | event_delete(EVENT_v2_LIVENESS, st); |
1043 | event_delete(EVENT_v2_RELEASE_WHACK, st); |
1044 | event_delete(EVENT_v1_SEND_XAUTH, st); |
1045 | event_delete(EVENT_v2_ADDR_CHANGE, st); |
1046 | |
1047 | /* if there is a suspended state transition, disconnect us */ |
1048 | struct msg_digest *md = unsuspend_md(st); |
1049 | if (md != NULL((void*)0)) { |
1050 | dbg("disconnecting state #%lu from md", st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("disconnecting state #%lu from md", st->st_serialno ); } }; |
1051 | release_any_md(&md)md_delref(&md, (where_t) { .func = __func__, .basename = "state.c" , .line = 1051}); |
1052 | } |
1053 | |
1054 | if (should_send_delete(st)) { |
1055 | /* |
1056 | * tell the other side of any IPSEC SAs that are going down |
1057 | * |
1058 | * ??? in IKEv2, we should not immediately delete: |
1059 | * we should use an Informational Exchange to |
1060 | * co-ordinate deletion. |
1061 | * ikev2_delete_out doesn't really accomplish this. |
1062 | */ |
1063 | send_delete(st); |
1064 | } else if (IS_CHILD_SA(st)((st)->st_clonedfrom != 0)) { |
1065 | change_state(st, STATE_CHILDSA_DEL); |
1066 | } |
1067 | |
1068 | delete_event(st); /* delete any pending timer event */ |
1069 | clear_retransmits(st); |
1070 | |
1071 | /* |
1072 | * Ditch anything pending on ISAKMP SA being established. |
1073 | * Note: this must be done before the unhash_state to prevent |
1074 | * flush_pending_by_state inadvertently and prematurely |
1075 | * deleting our connection. |
1076 | */ |
1077 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { |
1078 | flush_pending_by_state(pexpect_ike_sa(st)); |
1079 | } |
1080 | |
1081 | /* flush unestablished child states */ |
1082 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { |
1083 | flush_incomplete_children(pexpect_ike_sa(st)); |
1084 | } |
1085 | |
1086 | /* |
1087 | * if there is anything in the cryptographic queue, then remove this |
1088 | * state from it. |
1089 | */ |
1090 | delete_cryptographic_continuation(st); |
1091 | |
1092 | /* |
1093 | * tell kernel to delete any IPSEC SA |
1094 | */ |
1095 | if (IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA)) || |
1096 | IS_CHILD_SA_ESTABLISHED(st)((st)->st_state->kind == STATE_V2_ESTABLISHED_CHILD_SA && ((st)->st_clonedfrom != 0)) || |
1097 | st->st_state->kind == STATE_CHILDSA_DEL) { |
1098 | delete_ipsec_sa(st); |
1099 | } |
1100 | |
1101 | if (c->newest_ipsec_sa == st->st_serialno) |
1102 | c->newest_ipsec_sa = SOS_NOBODY0; |
1103 | |
1104 | if (c->newest_isakmp_sa == st->st_serialno) |
1105 | c->newest_isakmp_sa = SOS_NOBODY0; |
1106 | |
1107 | /* |
1108 | * If policy dictates, try to keep the connection alive. |
1109 | * DONT_REKEY overrides UP. |
1110 | * |
1111 | * XXX: need more info from someone knowing what the problem |
1112 | * is. |
1113 | * ??? What problem is this referring to? |
1114 | */ |
1115 | if ((c->policy & (POLICY_UP((lset_t)1 << (POLICY_UP_IX)) | POLICY_DONT_REKEY((lset_t)1 << (POLICY_DONT_REKEY_IX)))) == POLICY_UP((lset_t)1 << (POLICY_UP_IX)) && |
1116 | IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { |
1117 | /* XXX: break it down so it can be logged */ |
1118 | so_serial_t newer_sa = get_newer_sa_from_connection(st); |
1119 | if (state_by_serialno(newer_sa) != NULL((void*)0)) { |
1120 | /* |
1121 | * Presumably this is an old state that has |
1122 | * either been rekeyed or replaced. |
1123 | * |
1124 | * XXX: Should not even be here though! The |
1125 | * old IKE SA should be going through delete |
1126 | * state transition that, at the end, cleanly |
1127 | * deletes it with none of this guff. |
1128 | */ |
1129 | dbg("IKE delete_state() for #%lu and connection '%s' that is supposed to remain up; not a problem - have newer #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("IKE delete_state() for #%lu and connection '%s' that is supposed to remain up; not a problem - have newer #%lu" , st->st_serialno, c->name, newer_sa); } } |
1130 | st->st_serialno, c->name, newer_sa){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("IKE delete_state() for #%lu and connection '%s' that is supposed to remain up; not a problem - have newer #%lu" , st->st_serialno, c->name, newer_sa); } }; |
1131 | } else if (impair.revival) { |
1132 | log_state(RC_LOG, st, |
1133 | "IMPAIR: skipping revival of connection that is supposed to remain up"); |
1134 | } else { |
1135 | log_state(RC_LOG, st, |
1136 | "deleting IKE SA but connection is supposed to remain up; schedule EVENT_REVIVE_CONNS"); |
1137 | add_revival(c); |
1138 | } |
1139 | } |
1140 | |
1141 | /* |
1142 | * fake a state change here while we are still associated with a |
1143 | * connection. Without this the state logging (when enabled) cannot |
1144 | * work out what happened. |
1145 | */ |
1146 | binlog_fake_state(st, STATE_UNDEFINED)binlog_state((st), (STATE_UNDEFINED)); |
1147 | |
1148 | /* XXX: hack to avoid reference counting iface_port. */ |
1149 | if (st->st_interface != NULL((void*)0) && IS_IKE_SA(st)((st)->st_clonedfrom == 0) && |
1150 | st->st_serialno >= st->st_connection->newest_isakmp_sa) { |
1151 | /* |
1152 | * XXX: don't try to delete the iface port of an old |
1153 | * TCP IKE SA. It's replacement will have taken |
1154 | * ownership. However, do delete a TCP IKE SA when it |
1155 | * looks like it is getting ready for a replace. |
1156 | */ |
1157 | if (st->st_interface->protocol == &ip_protocol_tcp) { |
1158 | dbg("TCP: freeing interface; release instead?"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TCP: freeing interface; release instead?"); } }; |
1159 | struct iface_port **p = (void*)&st->st_interface; /* hack const */ |
1160 | /* |
1161 | * XXX: The state and the event loop are |
1162 | * sharing EVP. This deletes both. |
1163 | */ |
1164 | free_any_iface_port(p); |
1165 | } |
1166 | } |
1167 | st->st_interface = NULL((void*)0); |
1168 | |
1169 | /* |
1170 | * Unlink the connection which may in turn delete the |
1171 | * connection instance. Needs to be done before the state is |
1172 | * removed from the state DB as it can otherwise leak the |
1173 | * connection (or explode because it was removed from the |
1174 | * list). |
1175 | */ |
1176 | update_state_connection(st, NULL((void*)0)); |
1177 | |
1178 | /* |
1179 | * Effectively, this deletes any ISAKMP SA that this state |
1180 | * represents |
1181 | */ |
1182 | del_state_from_db(st); |
1183 | |
1184 | v2_msgid_free(st); |
1185 | |
1186 | change_state(st, STATE_UNDEFINED); |
1187 | |
1188 | release_any_whack(st, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 1188}, "deleting state"); |
1189 | |
1190 | /* from here on we are just freeing RAM */ |
1191 | |
1192 | ikev1_clear_msgid_list(st); |
1193 | unreference_key(&st->st_peer_pubkey); |
1194 | |
1195 | /* |
1196 | * Release stored IKE fragments. This is a union in st so only |
1197 | * call one! XXX: should be a union??? |
1198 | */ |
1199 | switch (st->st_ike_version) { |
1200 | case IKEv1: |
1201 | free_v1_message_queues(st); |
1202 | break; |
1203 | case IKEv2: |
1204 | free_v2_message_queues(st); |
1205 | break; |
1206 | default: |
1207 | bad_case(st->st_ike_version)libreswan_bad_case("st->st_ike_version", (st->st_ike_version ), (where_t) { .func = __func__, .basename = "state.c" , .line = 1207}); |
1208 | } |
1209 | |
1210 | /* |
1211 | * Free the accepted proposal first, it points into the |
1212 | * proposals. |
1213 | */ |
1214 | free_ikev2_proposal(&st->st_accepted_ike_proposal); |
1215 | free_ikev2_proposal(&st->st_accepted_esp_or_ah_proposal); |
1216 | |
1217 | /* |
1218 | * If this state 'owns' the DH secret, release it. If not |
1219 | * then it is presumably owned by a crypto-helper and that can |
1220 | * clean it up. |
1221 | */ |
1222 | if (st->st_dh_secret != NULL((void*)0)) { |
1223 | free_dh_secret(&st->st_dh_secret); |
1224 | } |
1225 | |
1226 | /* without st_connection, st isn't complete */ |
1227 | /* from here on logging is for the wrong state */ |
1228 | pop_cur_state(old_serialno)log_pop_state(old_serialno, (where_t) { .func = __func__, .basename = "state.c" , .line = 1228}); |
1229 | |
1230 | release_certs(&st->st_remote_certs.verified); |
1231 | free_public_keys(&st->st_remote_certs.pubkey_db); |
1232 | |
1233 | free_generalNames(st->st_requested_ca, TRUE1); |
1234 | |
1235 | free_chunk_content(&st->st_firstpacket_me); |
1236 | free_chunk_content(&st->st_firstpacket_peer); |
1237 | free_chunk_content(&st->st_v1_tpacket); |
1238 | free_chunk_content(&st->st_v1_rpacket); |
1239 | free_chunk_content(&st->st_p1isa); |
1240 | free_chunk_content(&st->st_gi); |
1241 | free_chunk_content(&st->st_gr); |
1242 | free_chunk_content(&st->st_ni); |
1243 | free_chunk_content(&st->st_nr); |
1244 | free_chunk_content(&st->st_dcookie); |
1245 | free_chunk_content(&st->st_v2_id_payload.data); |
1246 | |
1247 | # define free_any_nss_symkey(p) release_symkey(__func__, #p, &(p)) |
1248 | free_any_nss_symkey(st->st_shared_nss); |
1249 | free_any_nss_symkey(st->st_skeyid_nss); |
1250 | free_any_nss_symkey(st->st_skey_d_nss); /* aka st_skeyid_d_nss */ |
1251 | free_any_nss_symkey(st->st_skey_ai_nss); /* aka st_skeyid_a_nss */ |
1252 | free_any_nss_symkey(st->st_skey_ar_nss); |
1253 | free_any_nss_symkey(st->st_skey_ei_nss); /* aka st_skeyid_e_nss */ |
1254 | free_any_nss_symkey(st->st_skey_er_nss); |
1255 | free_any_nss_symkey(st->st_skey_pi_nss); |
1256 | free_any_nss_symkey(st->st_skey_pr_nss); |
1257 | free_any_nss_symkey(st->st_enc_key_nss); |
1258 | |
1259 | free_any_nss_symkey(st->st_sk_d_no_ppk); |
1260 | free_any_nss_symkey(st->st_sk_pi_no_ppk); |
1261 | free_any_nss_symkey(st->st_sk_pr_no_ppk); |
1262 | |
1263 | # undef free_any_nss_symkey |
1264 | |
1265 | free_chunk_content(&st->st_skey_initiator_salt); |
1266 | free_chunk_content(&st->st_skey_responder_salt); |
1267 | free_chunk_content(&st->st_skey_chunk_SK_pi); |
1268 | free_chunk_content(&st->st_skey_chunk_SK_pr); |
1269 | |
1270 | # define wipe_any(p, l) { \ |
1271 | if ((p) != NULL((void*)0)) { \ |
1272 | memset((p), 0x00, (l)); \ |
1273 | pfree(p); \ |
1274 | (p) = NULL((void*)0); \ |
1275 | } \ |
1276 | } |
1277 | wipe_any(st->st_ah.our_keymat, st->st_ah.keymat_len); |
1278 | wipe_any(st->st_ah.peer_keymat, st->st_ah.keymat_len); |
1279 | wipe_any(st->st_esp.our_keymat, st->st_esp.keymat_len); |
1280 | wipe_any(st->st_esp.peer_keymat, st->st_esp.keymat_len); |
1281 | |
1282 | wipe_any(st->st_xauth_password.ptr, st->st_xauth_password.len); |
1283 | # undef wipe_any |
1284 | |
1285 | /* st_xauth_username is an array on the state itself, not clone_str()'ed */ |
1286 | pfreeany(st->st_seen_cfg_dns){ typeof(st->st_seen_cfg_dns) *pp_ = &(st->st_seen_cfg_dns ); if (*pp_ != ((void*)0)) { pfree(*pp_); *pp_ = ((void*)0); } }; |
1287 | pfreeany(st->st_seen_cfg_domains){ typeof(st->st_seen_cfg_domains) *pp_ = &(st->st_seen_cfg_domains ); if (*pp_ != ((void*)0)) { pfree(*pp_); *pp_ = ((void*)0); } }; |
1288 | pfreeany(st->st_seen_cfg_banner){ typeof(st->st_seen_cfg_banner) *pp_ = &(st->st_seen_cfg_banner ); if (*pp_ != ((void*)0)) { pfree(*pp_); *pp_ = ((void*)0); } }; |
1289 | |
1290 | free_chunk_content(&st->st_no_ppk_auth); |
1291 | |
1292 | pfreeany(st->sec_ctx){ typeof(st->sec_ctx) *pp_ = &(st->sec_ctx); if (*pp_ != ((void*)0)) { pfree(*pp_); *pp_ = ((void*)0); } }; |
1293 | free_logger(&st->st_logger); |
1294 | messup(st)memset(((st)), 0xFB, (sizeof(*(st)))); |
1295 | pfree(st); |
1296 | } |
1297 | |
1298 | /* |
1299 | * Is a connection in use by some state? |
1300 | */ |
1301 | |
1302 | bool_Bool shared_phase1_connection(const struct connection *c) |
1303 | { |
1304 | so_serial_t serial_us = c->newest_isakmp_sa; |
1305 | |
1306 | if (serial_us == SOS_NOBODY0) |
1307 | return FALSE0; |
1308 | |
1309 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1310 | struct state *st = NULL((void*)0); |
1311 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
1312 | if (st->st_connection != c && st->st_clonedfrom == serial_us) |
1313 | return TRUE1; |
1314 | } |
1315 | |
1316 | return FALSE0; |
1317 | } |
1318 | |
1319 | bool_Bool v2_child_connection_probably_shared(struct child_sa *child) |
1320 | { |
1321 | struct connection *c = child->sa.st_connection; |
1322 | |
1323 | if (in_pending_use(c)) { |
1324 | dbg("#%lu connection is also pending; but what about pending for this state???",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu connection is also pending; but what about pending for this state???" , child->sa.st_serialno); } } |
1325 | child->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu connection is also pending; but what about pending for this state???" , child->sa.st_serialno); } }; |
1326 | return true1; |
1327 | } |
1328 | |
1329 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1330 | struct ike_sa *ike = ike_sa(&child->sa, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 1330}); |
1331 | struct state *st = NULL((void*)0); |
1332 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
1333 | if (st->st_connection != c) { |
1334 | continue; |
1335 | } |
1336 | if (st == &child->sa) { |
1337 | dbg("ignoring ourselves #%lu sharing connection %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring ourselves #%lu sharing connection %s" , st->st_serialno, c->name); } } |
1338 | st->st_serialno, c->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring ourselves #%lu sharing connection %s" , st->st_serialno, c->name); } }; |
1339 | continue; |
1340 | } |
1341 | if (st == &ike->sa) { |
1342 | dbg("ignoring IKE SA #%lu sharing connection %s with #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring IKE SA #%lu sharing connection %s with #%lu" , st->st_serialno, c->name, child->sa.st_serialno); } } |
1343 | st->st_serialno, c->name, child->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring IKE SA #%lu sharing connection %s with #%lu" , st->st_serialno, c->name, child->sa.st_serialno); } }; |
1344 | continue; |
1345 | } |
1346 | dbg("#%lu and #%lu share connection %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu and #%lu share connection %s", child-> sa.st_serialno, st->st_serialno, c->name); } } |
1347 | child->sa.st_serialno, st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu and #%lu share connection %s", child-> sa.st_serialno, st->st_serialno, c->name); } } |
1348 | c->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu and #%lu share connection %s", child-> sa.st_serialno, st->st_serialno, c->name); } }; |
1349 | return true1; |
1350 | } |
1351 | |
1352 | return false0; |
1353 | } |
1354 | |
1355 | /* |
1356 | * delete all states that were created for a given connection, |
1357 | * additionally delete any states for which func(st, c) |
1358 | * returns true. |
1359 | */ |
1360 | static void foreach_state_by_connection_func_delete(struct connection *c, |
1361 | bool_Bool (*comparefunc)( |
1362 | struct state *st, |
1363 | struct connection *c), |
1364 | struct fd *whackfd) |
1365 | { |
1366 | /* this kludge avoids an n^2 algorithm */ |
1367 | |
1368 | /* We take two passes so that we delete any ISAKMP SAs last. |
1369 | * This allows Delete Notifications to be sent. |
1370 | * ?? We could probably double the performance by caching any |
1371 | * ISAKMP SA states found in the first pass, avoiding a second. |
1372 | */ |
1373 | for (int pass = 0; pass != 2; pass++) { |
1374 | dbg("pass %d", pass){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("pass %d", pass); } }; |
1375 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1376 | struct state *this = NULL((void*)0); |
1377 | FOR_EACH_STATE_NEW2OLD(this)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (this = (typeof(this))entry_->data, entry_ = entry_->older ; this != ((void*)0); this = (typeof(this))entry_->data, entry_ = entry_->older) { |
1378 | dbg("state #%lu", this->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu", this->st_serialno); } }; |
1379 | |
1380 | /* on first pass, ignore established ISAKMP SA's */ |
1381 | if (pass == 0 && |
1382 | IS_ISAKMP_SA_ESTABLISHED(this->st_state)((((lset_t)1 << (this->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))) |
1383 | continue; |
1384 | |
1385 | /* call comparison function */ |
1386 | if ((*comparefunc)(this, c)) { |
1387 | /* |
1388 | * XXX: this simingly redundant |
1389 | * push/pop has the side effect |
1390 | * suppressing the message 'deleting |
1391 | * other state'. |
1392 | */ |
1393 | so_serial_t old_serialno = push_cur_state(this)log_push_state(this, (where_t) { .func = __func__, .basename = "state.c" , .line = 1393}); |
1394 | /* XXX: better way? */ |
1395 | close_any(&this->st_logger->global_whackfd)close_any_fd((&this->st_logger->global_whackfd), (where_t ) { .func = __func__, .basename = "state.c" , .line = 1395}); |
1396 | this->st_logger->global_whackfd = dup_any(whackfd)dup_any_fd((whackfd), (where_t) { .func = __func__, .basename = "state.c" , .line = 1396}); |
1397 | delete_state(this); |
1398 | pop_cur_state(old_serialno)log_pop_state(old_serialno, (where_t) { .func = __func__, .basename = "state.c" , .line = 1398}); |
1399 | } |
1400 | } |
1401 | } |
1402 | } |
1403 | |
1404 | /* |
1405 | * Delete all states that have somehow not ben deleted yet |
1406 | * but using interfaces that are going down |
1407 | */ |
1408 | |
1409 | void delete_states_dead_interfaces(struct fd *whackfd) |
1410 | { |
1411 | struct state *this = NULL((void*)0); |
1412 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1413 | FOR_EACH_STATE_NEW2OLD(this)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (this = (typeof(this))entry_->data, entry_ = entry_->older ; this != ((void*)0); this = (typeof(this))entry_->data, entry_ = entry_->older) { |
1414 | if (this->st_interface && |
1415 | this->st_interface->ip_dev->ifd_change == IFD_DELETE) { |
1416 | char *id_vname = NULL((void*)0); |
1417 | struct connection *c = this->st_connection; |
1418 | if (c->xfrmi != NULL((void*)0) && c->xfrmi->name != NULL((void*)0)) |
1419 | id_vname = c->xfrmi->name; |
1420 | else |
1421 | id_vname = this->st_interface->ip_dev->id_rname; |
1422 | log_global(RC_LOG, whackfd,{ struct logger log_ = (struct logger) { .where = (where_t) { .func = __func__, .basename = "state.c" , .line = 1424}, .global_whackfd = whackfd, .object = ((void*)0), .object_vec = &logger_global_vec , }; log_message(RC_LOG, &log_, "deleting lasting state #%lu on interface (%s) which is shutting down" , this->st_serialno, id_vname); } |
1423 | "deleting lasting state #%lu on interface (%s) which is shutting down",{ struct logger log_ = (struct logger) { .where = (where_t) { .func = __func__, .basename = "state.c" , .line = 1424}, .global_whackfd = whackfd, .object = ((void*)0), .object_vec = &logger_global_vec , }; log_message(RC_LOG, &log_, "deleting lasting state #%lu on interface (%s) which is shutting down" , this->st_serialno, id_vname); } |
1424 | this->st_serialno, id_vname){ struct logger log_ = (struct logger) { .where = (where_t) { .func = __func__, .basename = "state.c" , .line = 1424}, .global_whackfd = whackfd, .object = ((void*)0), .object_vec = &logger_global_vec , }; log_message(RC_LOG, &log_, "deleting lasting state #%lu on interface (%s) which is shutting down" , this->st_serialno, id_vname); }; |
1425 | /* XXX: better? */ |
1426 | close_any(&this->st_logger->global_whackfd)close_any_fd((&this->st_logger->global_whackfd), (where_t ) { .func = __func__, .basename = "state.c" , .line = 1426}); |
1427 | this->st_logger->global_whackfd = dup_any(whackfd)dup_any_fd((whackfd), (where_t) { .func = __func__, .basename = "state.c" , .line = 1427}); |
1428 | delete_state(this); |
1429 | /* note: no md->st to clear */ |
1430 | } |
1431 | } |
1432 | } |
1433 | |
1434 | /* |
1435 | * delete all states that were created for a given connection. |
1436 | * if relations == TRUE, then also delete states that share |
1437 | * the same phase 1 SA. |
1438 | */ |
1439 | |
1440 | static bool_Bool same_phase1_sa(struct state *this, |
1441 | struct connection *c) |
1442 | { |
1443 | return this->st_connection == c; |
1444 | } |
1445 | |
1446 | static bool_Bool same_phase1_sa_relations(struct state *this, |
1447 | struct connection *c) |
1448 | { |
1449 | so_serial_t parent_sa = c->newest_isakmp_sa; |
1450 | |
1451 | return this->st_connection == c || |
1452 | (parent_sa != SOS_NOBODY0 && |
1453 | this->st_clonedfrom == parent_sa); |
1454 | } |
1455 | |
1456 | void delete_states_by_connection(struct connection *c, bool_Bool relations, struct fd *whackfd) |
1457 | { |
1458 | enum connection_kind ck = c->kind; |
1459 | |
1460 | dbg("deleting states for connection - %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting states for connection - %s", relations ? "including all other IPsec SA's of this IKE SA" : "not including other IPsec SA's" ); } } |
1461 | relations ? "including all other IPsec SA's of this IKE SA" :{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting states for connection - %s", relations ? "including all other IPsec SA's of this IKE SA" : "not including other IPsec SA's" ); } } |
1462 | "not including other IPsec SA's"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting states for connection - %s", relations ? "including all other IPsec SA's of this IKE SA" : "not including other IPsec SA's" ); } }; |
1463 | |
1464 | /* |
1465 | * save this connection's isakmp SA, |
1466 | * since it will get set to later SOS_NOBODY |
1467 | */ |
1468 | if (ck == CK_INSTANCE) |
1469 | c->kind = CK_GOING_AWAY; |
1470 | |
1471 | foreach_state_by_connection_func_delete(c, |
1472 | relations ? same_phase1_sa_relations : same_phase1_sa, |
1473 | whackfd); |
1474 | |
1475 | const struct spd_route *sr; |
1476 | |
1477 | for (sr = &c->spd; sr != NULL((void*)0); sr = sr->spd_next) { |
1478 | passert(sr->eroute_owner == SOS_NOBODY){ _Bool assertion__ = sr->eroute_owner == 0; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 1478}, "%s", "sr->eroute_owner == SOS_NOBODY" ); } }; |
1479 | passert(sr->routing != RT_ROUTED_TUNNEL){ _Bool assertion__ = sr->routing != RT_ROUTED_TUNNEL; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "state.c" , .line = 1479}, "%s", "sr->routing != RT_ROUTED_TUNNEL" ); } }; |
1480 | } |
1481 | |
1482 | if (ck == CK_INSTANCE) { |
1483 | c->kind = ck; |
1484 | delete_connection(c, relations); |
1485 | } |
1486 | } |
1487 | |
1488 | /* |
1489 | * Walk through the state table, and delete each state whose phase 1 (IKE) |
1490 | * peer is among those given. |
1491 | * This function is only called for ipsec whack --crash peer |
1492 | */ |
1493 | void delete_states_by_peer(const struct fd *whackfd, const ip_address *peer) |
1494 | { |
1495 | address_buf peer_buf; |
1496 | const char *peerstr = ipstr(peer, &peer_buf); |
1497 | |
1498 | whack_log(RC_COMMENT, whackfd, "restarting peer %s", peerstr); |
1499 | |
1500 | /* first restart the phase1s */ |
1501 | for (int ph1 = 0; ph1 < 2; ph1++) { |
1502 | struct state *this; |
1503 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1504 | FOR_EACH_STATE_NEW2OLD(this)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (this = (typeof(this))entry_->data, entry_ = entry_->older ; this != ((void*)0); this = (typeof(this))entry_->data, entry_ = entry_->older) { |
1505 | const struct connection *c = this->st_connection; |
1506 | endpoint_buf b; |
1507 | dbg("comparing %s to %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("comparing %s to %s", str_endpoint(&this-> st_remote_endpoint, &b), peerstr); } } |
1508 | str_endpoint(&this->st_remote_endpoint, &b),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("comparing %s to %s", str_endpoint(&this-> st_remote_endpoint, &b), peerstr); } } |
1509 | peerstr){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("comparing %s to %s", str_endpoint(&this-> st_remote_endpoint, &b), peerstr); } }; |
1510 | |
1511 | if (sameaddr(&this->st_remote_endpoint, peer)) { |
1512 | if (ph1 == 0 && IS_IKE_SA(this)((this)->st_clonedfrom == 0)) { |
1513 | whack_log(RC_COMMENT, whackfd, |
1514 | "peer %s for connection %s crashed; replacing", |
1515 | peerstr, |
1516 | c->name); |
1517 | ipsecdoi_replace(this, 1); |
1518 | } else { |
1519 | event_force(EVENT_SA_REPLACE, this); |
1520 | } |
1521 | } |
1522 | } |
1523 | } |
1524 | } |
1525 | |
1526 | /* |
1527 | * IKEv1: Duplicate a Phase 1 state object, to create a Phase 2 object. |
1528 | * |
1529 | * IKEv2: Duplicate an IKE SA state object, to create either a CHILD |
1530 | * SA or IKE SA (rekeying parent) object. |
1531 | * |
1532 | * Caller must schedule an event for this object so that it doesn't leak. |
1533 | * Caller must insert_state(). |
1534 | */ |
1535 | static struct state *duplicate_state(struct state *st, |
1536 | enum sa_type sa_type, |
1537 | struct fd *whackfd) |
1538 | { |
1539 | struct state *nst; |
1540 | |
1541 | if (sa_type == IPSEC_SA) { |
1542 | /* record use of the Phase 1 / Parent state */ |
1543 | st->st_outbound_count++; |
1544 | st->st_outbound_time = mononow(); |
1545 | } |
1546 | |
1547 | nst = new_state(st->st_ike_version, |
1548 | st->st_ike_spis.initiator, |
1549 | st->st_ike_spis.responder, |
1550 | sa_type, whackfd); |
1551 | |
1552 | connection_buf cib; |
1553 | dbg("duplicating state object #%lu "PRI_CONNECTION" as #%lu for %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("duplicating state object #%lu ""\"%s\"%s"" as #%lu for %s" , st->st_serialno, (st->st_connection)->name, str_connection_instance (st->st_connection, &cib), nst->st_serialno, sa_type == IPSEC_SA ? "IPSEC SA" : "IKE SA"); } } |
1554 | st->st_serialno, pri_connection(st->st_connection, &cib),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("duplicating state object #%lu ""\"%s\"%s"" as #%lu for %s" , st->st_serialno, (st->st_connection)->name, str_connection_instance (st->st_connection, &cib), nst->st_serialno, sa_type == IPSEC_SA ? "IPSEC SA" : "IKE SA"); } } |
1555 | nst->st_serialno, sa_type == IPSEC_SA ? "IPSEC SA" : "IKE SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("duplicating state object #%lu ""\"%s\"%s"" as #%lu for %s" , st->st_serialno, (st->st_connection)->name, str_connection_instance (st->st_connection, &cib), nst->st_serialno, sa_type == IPSEC_SA ? "IPSEC SA" : "IKE SA"); } }; |
1556 | |
1557 | update_state_connection(nst, st->st_connection); |
1558 | |
1559 | if (sa_type == IPSEC_SA) { |
1560 | nst->st_oakley = st->st_oakley; |
1561 | } |
1562 | |
1563 | nst->quirks = st->quirks; |
1564 | nst->hidden_variables = st->hidden_variables; |
1565 | nst->st_remote_endpoint = st->st_remote_endpoint; |
1566 | pexpect_st_local_endpoint(st); |
1567 | endpoint_buf eb; |
1568 | dbg("#%lu setting local endpoint to %s from #%ld.st_localport "PRI_WHERE,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu setting local endpoint to %s from #%ld.st_localport " "(in %s() at %s:%lu)", nst->st_serialno, str_endpoint(& st->st_interface->local_endpoint, &eb), st->st_serialno ,((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).func, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).line); } } |
1569 | nst->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu setting local endpoint to %s from #%ld.st_localport " "(in %s() at %s:%lu)", nst->st_serialno, str_endpoint(& st->st_interface->local_endpoint, &eb), st->st_serialno ,((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).func, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).line); } } |
1570 | str_endpoint(&st->st_interface->local_endpoint, &eb),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu setting local endpoint to %s from #%ld.st_localport " "(in %s() at %s:%lu)", nst->st_serialno, str_endpoint(& st->st_interface->local_endpoint, &eb), st->st_serialno ,((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).func, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).line); } } |
1571 | st->st_serialno,pri_where(HERE)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu setting local endpoint to %s from #%ld.st_localport " "(in %s() at %s:%lu)", nst->st_serialno, str_endpoint(& st->st_interface->local_endpoint, &eb), st->st_serialno ,((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).func, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 1571}).line); } }; |
1572 | nst->st_interface = st->st_interface; |
1573 | pexpect_st_local_endpoint(nst); |
1574 | nst->st_clonedfrom = st->st_serialno; |
1575 | passert(nst->st_ike_version == st->st_ike_version){ _Bool assertion__ = nst->st_ike_version == st->st_ike_version ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "state.c" , .line = 1575}, "%s", "nst->st_ike_version == st->st_ike_version" ); } }; |
1576 | nst->st_ikev2_anon = st->st_ikev2_anon; |
1577 | nst->st_seen_fragmentation_supported = st->st_seen_fragmentation_supported; |
1578 | nst->st_seen_fragments = st->st_seen_fragments; |
1579 | nst->st_seen_ppk = st->st_seen_ppk; |
1580 | nst->st_seen_redirect_sup = st->st_seen_redirect_sup; |
1581 | nst->st_seen_use_ipcomp = st->st_seen_use_ipcomp; |
1582 | nst->st_sent_redirect = st->st_sent_redirect; |
1583 | nst->st_event = NULL((void*)0); |
1584 | |
1585 | /* these were set while we didn't have client state yet */ |
1586 | /* we should really split the NOTIFY loop in two cleaner ones */ |
1587 | nst->st_ipcomp.attrs = st->st_ipcomp.attrs; |
1588 | nst->st_ipcomp.present = st->st_ipcomp.present; |
1589 | nst->st_ipcomp.our_spi = st->st_ipcomp.our_spi; |
1590 | |
1591 | if (sa_type == IPSEC_SA) { |
1592 | # define clone_nss_symkey_field(field) nst->field = reference_symkey(__func__, #field, st->field) |
1593 | clone_nss_symkey_field(st_skeyid_nss); |
1594 | clone_nss_symkey_field(st_skey_d_nss); /* aka st_skeyid_d_nss */ |
1595 | clone_nss_symkey_field(st_skey_ai_nss); /* aka st_skeyid_a_nss */ |
1596 | clone_nss_symkey_field(st_skey_ar_nss); |
1597 | clone_nss_symkey_field(st_skey_ei_nss); /* aka st_skeyid_e_nss */ |
1598 | clone_nss_symkey_field(st_skey_er_nss); |
1599 | clone_nss_symkey_field(st_skey_pi_nss); |
1600 | clone_nss_symkey_field(st_skey_pr_nss); |
1601 | clone_nss_symkey_field(st_enc_key_nss); |
1602 | |
1603 | clone_nss_symkey_field(st_sk_d_no_ppk); |
1604 | clone_nss_symkey_field(st_sk_pi_no_ppk); |
1605 | clone_nss_symkey_field(st_sk_pr_no_ppk); |
1606 | # undef clone_nss_symkey_field |
1607 | |
1608 | /* v2 duplication of state */ |
1609 | # define state_clone_chunk(CHUNK) \ |
1610 | nst->CHUNK = clone_hunk(st->CHUNK, #CHUNK " in duplicate state")({ typeof(st->CHUNK) hunk_ = st->CHUNK; clone_bytes_as_chunk (hunk_.ptr, hunk_.len, #CHUNK " in duplicate state"); }) |
1611 | |
1612 | state_clone_chunk(st_ni); |
1613 | state_clone_chunk(st_nr); |
1614 | state_clone_chunk(st_skey_initiator_salt); |
1615 | state_clone_chunk(st_skey_responder_salt); |
1616 | |
1617 | # undef state_clone_chunk |
1618 | } |
1619 | |
1620 | /* |
1621 | * These are done because we need them in child st when |
1622 | * do_command() uses them to fill in our format string. |
1623 | * Maybe similarly to above for chunks, do this for all |
1624 | * strings on the state? |
1625 | */ |
1626 | jam_str(nst->st_xauth_username, sizeof(nst->st_xauth_username), st->st_xauth_username); |
1627 | |
1628 | nst->st_seen_cfg_dns = clone_str(st->st_seen_cfg_dns, "child st_seen_cfg_dns")((st->st_seen_cfg_dns) == ((void*)0) ? ((void*)0) : clone_bytes ((st->st_seen_cfg_dns), strlen((st->st_seen_cfg_dns)) + 1, ("child st_seen_cfg_dns"))); |
1629 | nst->st_seen_cfg_domains = clone_str(st->st_seen_cfg_domains, "child st_seen_cfg_domains")((st->st_seen_cfg_domains) == ((void*)0) ? ((void*)0) : clone_bytes ((st->st_seen_cfg_domains), strlen((st->st_seen_cfg_domains )) + 1, ("child st_seen_cfg_domains"))); |
1630 | nst->st_seen_cfg_banner = clone_str(st->st_seen_cfg_banner, "child st_seen_cfg_banner")((st->st_seen_cfg_banner) == ((void*)0) ? ((void*)0) : clone_bytes ((st->st_seen_cfg_banner), strlen((st->st_seen_cfg_banner )) + 1, ("child st_seen_cfg_banner"))); |
1631 | |
1632 | return nst; |
1633 | } |
1634 | |
1635 | struct state *ikev1_duplicate_state(struct state *st, |
1636 | struct fd *whackfd) |
1637 | { |
1638 | return duplicate_state(st, IPSEC_SA, whackfd); |
1639 | } |
1640 | |
1641 | struct child_sa *new_v2_child_state(struct ike_sa *ike, |
1642 | enum sa_type sa_type, |
1643 | enum sa_role role, |
1644 | enum state_kind kind, |
1645 | struct fd *whackfd) |
1646 | { |
1647 | struct state *cst = duplicate_state(&ike->sa, sa_type, whackfd); |
1648 | cst->st_sa_role = role; |
1649 | struct child_sa *child = pexpect_child_sa(cst); |
1650 | v2_msgid_init_child(ike, child); |
1651 | change_state(&child->sa, kind); |
1652 | const struct state_v2_microcode *transition = child->sa.st_state->v2_transitions; |
1653 | set_v2_transition(&child->sa, transition, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 1653}); |
1654 | return child; |
1655 | } |
1656 | |
1657 | void for_each_state(void (*f)(struct state *, void *data), void *data, |
1658 | const char *func) |
1659 | { |
1660 | dbg("FOR_EACH_STATE_... in %s (%s)", func, __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s (%s)", func, __func__ ); } }; |
1661 | struct state *st = NULL((void*)0); |
1662 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
1663 | /* |
1664 | * Since OLD_STATE might be deleted by f(); |
1665 | * save/restore using serialno. |
1666 | */ |
1667 | so_serial_t old_serialno = push_cur_state(st)log_push_state(st, (where_t) { .func = __func__, .basename = "state.c" , .line = 1667}); |
1668 | (*f)(st, data); |
1669 | pop_cur_state(old_serialno)log_pop_state(old_serialno, (where_t) { .func = __func__, .basename = "state.c" , .line = 1669}); |
1670 | } |
1671 | } |
1672 | |
1673 | /* |
1674 | * Find a state object for an IKEv1 state |
1675 | */ |
1676 | |
1677 | struct state *find_state_ikev1(const ike_spis_t *ike_spis, msgid_t msgid) |
1678 | { |
1679 | return state_by_ike_spis(IKEv1, |
1680 | NULL((void*)0)/*ignore-clonedfrom*/, |
1681 | &msgid/*check v1 msgid*/, |
1682 | NULL((void*)0)/*ignore-role*/, |
1683 | ike_spis, NULL((void*)0), NULL((void*)0), __func__); |
1684 | } |
1685 | |
1686 | struct state *find_state_ikev1_init(const ike_spi_t *ike_initiator_spi, |
1687 | msgid_t msgid) |
1688 | { |
1689 | return state_by_ike_initiator_spi(IKEv1, |
1690 | NULL((void*)0)/*ignore-clonedfrom*/, |
1691 | &msgid/*check v1 msgid*/, |
1692 | NULL((void*)0)/*ignore-role*/, |
1693 | ike_initiator_spi, __func__); |
1694 | } |
1695 | |
1696 | /* |
1697 | * Find the IKEv2 IKE SA with the specified SPIs. |
1698 | */ |
1699 | struct ike_sa *find_v2_ike_sa(const ike_spis_t *ike_spis, |
1700 | enum sa_role local_ike_role) |
1701 | { |
1702 | const so_serial_t sos_nobody = SOS_NOBODY0; |
1703 | struct state *st = state_by_ike_spis(IKEv2, |
1704 | &sos_nobody/*clonedfrom: IKE SA*/, |
1705 | NULL((void*)0)/*ignore v1 msgid*/, |
1706 | &local_ike_role, |
1707 | ike_spis, NULL((void*)0), NULL((void*)0), __func__); |
1708 | return pexpect_ike_sa(st); |
1709 | } |
1710 | |
1711 | /* |
1712 | * Find an IKEv2 IKE SA with a matching SPIi. |
1713 | * |
1714 | * This is used doring the IKE_SA_INIT exchange where SPIr is either |
1715 | * zero (message request) or not-yet-known (message response). |
1716 | */ |
1717 | struct ike_sa *find_v2_ike_sa_by_initiator_spi(const ike_spi_t *ike_initiator_spi, |
1718 | enum sa_role local_ike_role) |
1719 | { |
1720 | const so_serial_t sos_nobody = SOS_NOBODY0; |
1721 | struct state *st = state_by_ike_initiator_spi(IKEv2, |
1722 | &sos_nobody/*clonedfrom: IKE_SA*/, |
1723 | NULL((void*)0)/*ignore v1 msgid*/, |
1724 | &local_ike_role, |
1725 | ike_initiator_spi, __func__); |
1726 | return pexpect_ike_sa(st); |
1727 | } |
1728 | |
1729 | /* |
1730 | * Find an IKEv2 CHILD SA using the protocol and the (from our POV) |
1731 | * 'outbound' SPI. |
1732 | * |
1733 | * The remote end, when identifying a CHILD SA in a Delete or REKEY_SA |
1734 | * notification, sends its end's inbound SPI, which from our |
1735 | * point-of-view is the outbound SPI aka 'attrs.spi'. |
1736 | * |
1737 | * From 1.3.3. Rekeying Child SAs with the CREATE_CHILD_SA Exchange: |
1738 | * The SA being rekeyed is identified by the SPI field in the |
1739 | * [REKEY_SA] Notify payload; this is the SPI the exchange initiator |
1740 | * would expect in inbound ESP or AH packets. |
1741 | * |
1742 | * From 3.11. Delete Payload: [the delete payload will] contain the |
1743 | * IPsec protocol ID of that protocol (2 for AH, 3 for ESP), and the |
1744 | * SPI is the SPI the sending endpoint would expect in inbound ESP or |
1745 | * AH packets. |
1746 | */ |
1747 | |
1748 | struct v2_spi_filter { |
1749 | uint8_t protoid; |
1750 | ipsec_spi_t outbound_spi; |
1751 | }; |
1752 | |
1753 | static bool_Bool v2_spi_predicate(struct state *st, void *context) |
1754 | { |
1755 | struct v2_spi_filter *filter = context; |
1756 | |
1757 | struct ipsec_proto_info *pr; |
1758 | switch (filter->protoid) { |
1759 | case PROTO_IPSEC_AH2: |
1760 | pr = &st->st_ah; |
1761 | break; |
1762 | case PROTO_IPSEC_ESP3: |
1763 | pr = &st->st_esp; |
1764 | break; |
1765 | default: |
1766 | bad_case(filter->protoid)libreswan_bad_case("filter->protoid", (filter->protoid) , (where_t) { .func = __func__, .basename = "state.c" , .line = 1766}); |
1767 | } |
1768 | |
1769 | if (pr->present) { |
1770 | if (pr->attrs.spi == filter->outbound_spi) { |
1771 | dbg("v2 CHILD SA #%lu found using their inbound (our outbound) SPI, in %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("v2 CHILD SA #%lu found using their inbound (our outbound) SPI, in %s" , st->st_serialno, st->st_state->name); } } |
1772 | st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("v2 CHILD SA #%lu found using their inbound (our outbound) SPI, in %s" , st->st_serialno, st->st_state->name); } } |
1773 | st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("v2 CHILD SA #%lu found using their inbound (our outbound) SPI, in %s" , st->st_serialno, st->st_state->name); } }; |
1774 | return true1; |
1775 | } |
1776 | #if 0 |
1777 | /* see function description above */ |
1778 | if (pr->our_spi == filter->outbound_spi) { |
1779 | dbg("v2 CHILD SA #%lu found using our inbound (their outbound) !?! SPI, in %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("v2 CHILD SA #%lu found using our inbound (their outbound) !?! SPI, in %s" , st->st_serialno, st->st_state->name); } } |
1780 | st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("v2 CHILD SA #%lu found using our inbound (their outbound) !?! SPI, in %s" , st->st_serialno, st->st_state->name); } } |
1781 | st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("v2 CHILD SA #%lu found using our inbound (their outbound) !?! SPI, in %s" , st->st_serialno, st->st_state->name); } }; |
1782 | return true1; |
1783 | } |
1784 | #endif |
1785 | } |
1786 | return false0; |
1787 | } |
1788 | |
1789 | struct child_sa *find_v2_child_sa_by_outbound_spi(struct ike_sa *ike, |
1790 | uint8_t protoid, |
1791 | ipsec_spi_t outbound_spi) |
1792 | { |
1793 | struct v2_spi_filter filter = { |
1794 | .protoid = protoid, |
1795 | .outbound_spi = outbound_spi, |
1796 | }; |
1797 | struct state *st = state_by_ike_spis(IKEv2, |
1798 | &ike->sa.st_serialno, |
1799 | NULL((void*)0)/* ignore v1 msgid*/, |
1800 | NULL((void*)0)/*ignore-role*/, |
1801 | &ike->sa.st_ike_spis, |
1802 | v2_spi_predicate, &filter, __func__); |
1803 | return pexpect_child_sa(st); |
1804 | } |
1805 | |
1806 | /* |
1807 | * Find a state object. |
1808 | */ |
1809 | struct v1_msgid_filter { |
1810 | msgid_t msgid; |
1811 | }; |
1812 | |
1813 | static bool_Bool v1_msgid_predicate(struct state *st, void *context) |
1814 | { |
1815 | struct v1_msgid_filter *filter = context; |
1816 | dbg("peer and cookies match on #%lu; msgid=%08" PRIx32 " st_msgid=%08" PRIx32 " st_v1_msgid.phase15=%08" PRIx32,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("peer and cookies match on #%lu; msgid=%08" "x" " st_msgid=%08" "x" " st_v1_msgid.phase15=%08" "x", st->st_serialno , filter->msgid, st->st_v1_msgid.id, st->st_v1_msgid .phase15); } } |
1817 | st->st_serialno, filter->msgid,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("peer and cookies match on #%lu; msgid=%08" "x" " st_msgid=%08" "x" " st_v1_msgid.phase15=%08" "x", st->st_serialno , filter->msgid, st->st_v1_msgid.id, st->st_v1_msgid .phase15); } } |
1818 | st->st_v1_msgid.id, st->st_v1_msgid.phase15){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("peer and cookies match on #%lu; msgid=%08" "x" " st_msgid=%08" "x" " st_v1_msgid.phase15=%08" "x", st->st_serialno , filter->msgid, st->st_v1_msgid.id, st->st_v1_msgid .phase15); } }; |
1819 | if ((st->st_v1_msgid.phase15 != v1_MAINMODE_MSGID((msgid_t) 0) && |
1820 | filter->msgid == st->st_v1_msgid.phase15) || |
1821 | filter->msgid == st->st_v1_msgid.id) { |
1822 | dbg("p15 state object #%lu found, in %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("p15 state object #%lu found, in %s", st->st_serialno , st->st_state->name); } } |
1823 | st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("p15 state object #%lu found, in %s", st->st_serialno , st->st_state->name); } }; |
1824 | return true1; |
1825 | } |
1826 | return false0; |
1827 | } |
1828 | |
1829 | struct state *find_v1_info_state(const ike_spis_t *ike_spis, msgid_t msgid) |
1830 | { |
1831 | struct v1_msgid_filter filter = { |
1832 | .msgid = msgid, |
1833 | }; |
1834 | return state_by_ike_spis(IKEv1, |
1835 | NULL((void*)0)/*ignore-clonedfrom*/, |
1836 | NULL((void*)0)/*ignore v1 msgid; see predicate*/, |
1837 | NULL((void*)0)/*ignore-role*/, |
1838 | ike_spis, v1_msgid_predicate, |
1839 | &filter, __func__); |
1840 | } |
1841 | |
1842 | /* |
1843 | * find_phase2_state_to_delete: find an AH or ESP SA to delete |
1844 | * |
1845 | * We are supposed to be given the other side's SPI. |
1846 | * Certain CISCO implementations send our side's SPI instead. |
1847 | * We'll accept this, but mark it as bogus. |
1848 | */ |
1849 | struct state *find_phase2_state_to_delete(const struct state *p1st, |
1850 | uint8_t protoid, |
1851 | ipsec_spi_t spi, |
1852 | bool_Bool *bogus) |
1853 | { |
1854 | const struct connection *p1c = p1st->st_connection; |
1855 | struct state *bogusst = NULL((void*)0); |
1856 | |
1857 | *bogus = FALSE0; |
1858 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1859 | struct state *st; |
1860 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
1861 | const struct connection *c = st->st_connection; |
1862 | if (IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA)) && |
1863 | p1c->host_pair == c->host_pair && |
1864 | same_peer_ids(p1c, c, NULL((void*)0))) |
1865 | { |
1866 | struct ipsec_proto_info *pr = |
1867 | protoid == PROTO_IPSEC_AH2 ? |
1868 | &st->st_ah : &st->st_esp; |
1869 | |
1870 | if (pr->present) { |
1871 | if (pr->attrs.spi == spi) { |
1872 | *bogus = FALSE0; |
1873 | return st; |
1874 | } |
1875 | |
1876 | if (pr->our_spi == spi) { |
1877 | *bogus = TRUE1; |
1878 | bogusst = st; |
1879 | /* don't return! */ |
1880 | } |
1881 | } |
1882 | } |
1883 | } |
1884 | return bogusst; |
1885 | } |
1886 | |
1887 | bool_Bool find_pending_phase2(const so_serial_t psn, |
1888 | const struct connection *c, lset_t ok_states) |
1889 | { |
1890 | struct state *best = NULL((void*)0); |
1891 | int n = 0; |
1892 | |
1893 | passert(psn >= SOS_FIRST){ _Bool assertion__ = psn >= 1; if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "state.c" , .line = 1893}, "%s", "psn >= SOS_FIRST"); } }; |
1894 | |
1895 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1896 | struct state *st = NULL((void*)0); |
1897 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
1898 | if (LHAS(ok_states, st->st_state->kind)(((ok_states) & ((lset_t)1 << (st->st_state-> kind))) != ((lset_t)0)) && |
1899 | IS_CHILD_SA(st)((st)->st_clonedfrom != 0) && |
1900 | st->st_clonedfrom == psn && |
1901 | streq(st->st_connection->name, c->name)(strcmp((st->st_connection->name), (c->name)) == 0)) /* not instances */ |
1902 | { |
1903 | n++; |
1904 | if (best == NULL((void*)0) || best->st_serialno < st->st_serialno) |
1905 | best = st; |
1906 | } |
1907 | } |
1908 | |
1909 | if (n > 0) { |
1910 | dbg("connection %s has %d pending IPsec negotiations ike #%lu last child state #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("connection %s has %d pending IPsec negotiations ike #%lu last child state #%lu" , c->name, n, psn, best->st_serialno); } } |
1911 | c->name, n, psn, best->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("connection %s has %d pending IPsec negotiations ike #%lu last child state #%lu" , c->name, n, psn, best->st_serialno); } }; |
1912 | } |
1913 | |
1914 | return best != NULL((void*)0); |
1915 | } |
1916 | |
1917 | /* |
1918 | * to initiate a new IPsec SA or to rekey IPsec |
1919 | * the IKE SA must be around for while. If IKE rekeying itself no new IPsec SA. |
1920 | */ |
1921 | bool_Bool ikev2_viable_parent(const struct ike_sa *ike) |
1922 | { |
1923 | /* this check is defined only for an IKEv2 parent */ |
1924 | if (ike->sa.st_ike_version != IKEv2) |
1925 | return TRUE1; |
1926 | |
1927 | monotime_t now = mononow(); |
1928 | const struct pluto_event *ev = ike->sa.st_event; |
1929 | deltatime_t lifetime = monotimediff(ev->ev_time, now); |
1930 | |
1931 | if (deltatime_cmp(lifetime, >, PARENT_MIN_LIFE_DELAY)(deltatime_cmp_sign(lifetime, deltatime(1)) > 0) && |
1932 | /* in case st_margin == 0, insist minimum life */ |
1933 | deltatime_cmp(lifetime, >, ike->sa.st_replace_margin)(deltatime_cmp_sign(lifetime, ike->sa.st_replace_margin) > 0)) { |
1934 | return true1; |
1935 | } |
1936 | |
1937 | deltatime_buf lb, rb; |
1938 | log_state(RC_LOG_SERIOUS, &ike->sa, |
1939 | "no new CREATE_CHILD_SA exchange using #%lu. Parent lifetime %s < st_margin %s", |
1940 | ike->sa.st_serialno, |
1941 | str_deltatime(lifetime, &lb), |
1942 | str_deltatime(ike->sa.st_replace_margin, &rb)); |
1943 | |
1944 | return false0; |
1945 | } |
1946 | |
1947 | /* |
1948 | * Find newest Phase 1 negotiation state object for suitable for connection c |
1949 | */ |
1950 | struct state *find_phase1_state(const struct connection *c, lset_t ok_states) |
1951 | { |
1952 | struct state *best = NULL((void*)0); |
1953 | bool_Bool is_ikev2 = (c->policy & POLICY_IKEV1_ALLOW((lset_t)1 << (POLICY_IKEV1_ALLOW_IX))) == LEMPTY((lset_t)0); |
1954 | |
1955 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1956 | struct state *st; |
1957 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
1958 | if (LHAS(ok_states, st->st_state->kind)(((ok_states) & ((lset_t)1 << (st->st_state-> kind))) != ((lset_t)0)) && |
1959 | (st->st_ike_version == IKEv2) == is_ikev2 && |
1960 | c->host_pair == st->st_connection->host_pair && |
1961 | same_peer_ids(c, st->st_connection, NULL((void*)0)) && |
1962 | sameaddr(&st->st_remote_endpoint, &c->spd.that.host_addr) && |
1963 | IS_IKE_SA(st)((st)->st_clonedfrom == 0) && |
1964 | (best == NULL((void*)0) || best->st_serialno < st->st_serialno)) |
1965 | { |
1966 | best = st; |
1967 | } |
1968 | } |
1969 | |
1970 | return best; |
1971 | } |
1972 | |
1973 | void state_eroute_usage(const ip_subnet *ours, const ip_subnet *peers, |
1974 | unsigned long count, monotime_t nw) |
1975 | { |
1976 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
1977 | struct state *st = NULL((void*)0); |
1978 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
1979 | struct connection *c = st->st_connection; |
1980 | |
1981 | /* XXX spd-enum */ |
1982 | if (IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA)) && |
1983 | c->spd.eroute_owner == st->st_serialno && |
1984 | c->spd.routing == RT_ROUTED_TUNNEL && |
1985 | samesubnet(&c->spd.this.client, ours) && |
1986 | samesubnet(&c->spd.that.client, peers)) { |
1987 | if (st->st_outbound_count != count) { |
1988 | st->st_outbound_count = count; |
1989 | st->st_outbound_time = nw; |
1990 | } |
1991 | return; |
1992 | } |
1993 | } |
1994 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { |
1995 | selector_buf ourst; |
1996 | selector_buf hist; |
1997 | DBG_log("unknown tunnel eroute %s -> %s found in scan", |
1998 | str_selector(ours, &ourst), |
1999 | str_selector(peers, &hist)); |
2000 | } |
2001 | } |
2002 | |
2003 | /* note: this mutates *st by calling get_sa_info */ |
2004 | static void jam_state_traffic(struct jambuf *buf, struct state *st) |
2005 | { |
2006 | jam(buf, "#%lu: ", st->st_serialno); |
2007 | const struct connection *c = st->st_connection; |
2008 | jam_connection(buf, c); |
2009 | |
2010 | if (st->st_xauth_username[0] != '\0') { |
2011 | jam(buf, ", username=%s", st->st_xauth_username); |
2012 | } |
2013 | |
2014 | /* traffic */ |
2015 | jam(buf, ", type=%s, add_time=%"PRIu64"l" "u", |
2016 | (st->st_esp.present ? "ESP" : st->st_ah.present ? "AH" : st->st_ipcomp.present ? "IPCOMP" : "UNKNOWN"), |
2017 | st->st_esp.add_time); |
2018 | |
2019 | if (get_sa_info(st, TRUE1, NULL((void*)0))) { |
2020 | unsigned inb = (st->st_esp.present ? st->st_esp.our_bytes: |
2021 | st->st_ah.present ? st->st_ah.our_bytes : |
2022 | st->st_ipcomp.present ? st->st_ipcomp.our_bytes : 0); |
2023 | jam(buf, ", inBytes=%u", inb); |
2024 | } |
2025 | |
2026 | if (get_sa_info(st, FALSE0, NULL((void*)0))) { |
2027 | unsigned outb = (st->st_esp.present ? st->st_esp.peer_bytes : |
2028 | st->st_ah.present ? st->st_ah.peer_bytes : |
2029 | st->st_ipcomp.present ? st->st_ipcomp.peer_bytes : 0); |
2030 | jam(buf, ", outBytes=%u", outb); |
2031 | } |
2032 | |
2033 | if (st->st_xauth_username[0] == '\0') { |
2034 | jam(buf, ", id='"); |
2035 | jam_id(buf, &c->spd.that.id, jam_sanitized_bytes); |
2036 | jam(buf, "'"); |
2037 | } |
2038 | |
2039 | if (c->spd.that.has_lease) { |
2040 | /* |
2041 | * "this" gave "that" a lease from "this" address |
2042 | * pool. |
2043 | */ |
2044 | jam(buf, ", lease="); |
2045 | jam_subnet(buf, &c->spd.that.client); |
2046 | } else if (c->spd.this.has_internal_address) { |
2047 | /* |
2048 | * "this" received an internal address from "that"; |
2049 | * presumably from "that"'s address pool. |
2050 | */ |
2051 | jam(buf, ", lease="); |
2052 | jam_subnet(buf, &c->spd.this.client); |
2053 | } |
2054 | } |
2055 | |
2056 | static void show_state_traffic(struct show *s, |
2057 | enum rc_type rc, struct state *st) |
2058 | { |
2059 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) |
2060 | return; /* ignore non-IPsec states */ |
2061 | |
2062 | if (!IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA))) |
2063 | return; /* ignore non established states */ |
2064 | |
2065 | /* whack-log-global - no prefix */ |
2066 | SHOW_JAMBUF(rc, s, buf)for (struct jambuf *buf = show_jambuf(s); buf != ((void*)0); jambuf_to_show (buf, s, rc), buf = ((void*)0)) { |
2067 | /* note: this mutates *st by calling get_sa_info */ |
2068 | jam_state_traffic(buf, st); |
2069 | } |
2070 | } |
2071 | |
2072 | /* |
2073 | * odd fact: st cannot be const because we call get_sa_info on it |
2074 | */ |
2075 | void fmt_state(struct state *st, const monotime_t now, |
2076 | char *state_buf, const size_t state_buf_len, |
2077 | char *state_buf2, const size_t state_buf2_len) |
2078 | { |
2079 | /* what the heck is interesting about a state? */ |
2080 | const struct connection *c = st->st_connection; |
2081 | char inst[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)]; |
2082 | char dpdbuf[128]; |
2083 | char traffic_buf[512], *mbcp; |
2084 | const char *np1 = c->newest_isakmp_sa == st->st_serialno ? |
2085 | "; newest ISAKMP" : ""; |
2086 | const char *np2 = c->newest_ipsec_sa == st->st_serialno ? |
2087 | "; newest IPSEC" : ""; |
2088 | /* XXX spd-enum */ |
2089 | const char *eo = c->spd.eroute_owner == st->st_serialno ? |
2090 | "; eroute owner" : ""; |
2091 | |
2092 | fmt_conn_instance(c, inst); |
2093 | |
2094 | dpdbuf[0] = '\0'; /* default to empty string */ |
2095 | if (IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA))) { |
2096 | snprintf(dpdbuf, sizeof(dpdbuf), "; isakmp#%lu", |
2097 | st->st_clonedfrom); |
2098 | } else { |
2099 | if (st->hidden_variables.st_peer_supports_dpd) { |
2100 | /* ??? why is printing -1 better than 0? */ |
2101 | snprintf(dpdbuf, sizeof(dpdbuf), |
2102 | "; lastdpd=%jds(seq in:%u out:%u)", |
2103 | !is_monotime_epoch(st->st_last_dpd) ? |
2104 | deltasecs(monotimediff(mononow(), st->st_last_dpd)) : (intmax_t)-1, |
2105 | st->st_dpd_seqno, |
2106 | st->st_dpd_expectseqno); |
2107 | } else if (dpd_active_locally(st) && (st->st_ike_version == IKEv2)) { |
2108 | /* stats are on parent sa */ |
2109 | if (IS_CHILD_SA(st)((st)->st_clonedfrom != 0)) { |
2110 | struct state *pst = state_with_serialno(st->st_clonedfrom); |
2111 | |
2112 | if (pst != NULL((void*)0)) { |
2113 | snprintf(dpdbuf, sizeof(dpdbuf), |
2114 | "; lastlive=%jds", |
2115 | !is_monotime_epoch(pst->st_last_liveness) ? |
2116 | deltasecs(monotimediff(mononow(), pst->st_last_liveness)) : |
2117 | 0); |
2118 | } |
2119 | } |
2120 | } else { |
2121 | if (st->st_ike_version == IKEv1) |
2122 | snprintf(dpdbuf, sizeof(dpdbuf), "; nodpd"); |
2123 | } |
2124 | } |
2125 | |
2126 | /* |
2127 | * Hunt and peck for an event? Should it show the first? |
2128 | */ |
2129 | struct pluto_event *liveness_events[] = { |
2130 | st->st_event, |
2131 | st->st_retransmit_event, |
2132 | }; |
2133 | struct pluto_event *liveness = NULL((void*)0); |
2134 | for (unsigned e = 0; e < elemsof(liveness_events)(sizeof(liveness_events) / sizeof(*(liveness_events))); e++) { |
2135 | liveness = liveness_events[e]; |
2136 | if (liveness != NULL((void*)0)) { |
2137 | break; |
2138 | } |
2139 | } |
2140 | intmax_t delta = (liveness == NULL((void*)0) ? -1 : /* ??? sort of odd signifier */ |
2141 | deltasecs(monotimediff(liveness->ev_time, now))); |
2142 | |
2143 | snprintf(state_buf, state_buf_len, |
2144 | "#%lu: \"%s\"%s:%u%s %s (%s); %s in %jds%s%s%s%s; %s;", |
2145 | st->st_serialno, |
2146 | c->name, inst, |
2147 | endpoint_hport(&st->st_remote_endpoint), |
2148 | (st->st_interface->protocol == &ip_protocol_tcp) ? "(tcp)" : "", |
2149 | st->st_state->name, |
2150 | st->st_state->story, |
2151 | (liveness == NULL((void*)0) ? "none" : |
2152 | enum_name(&timer_event_names, liveness->ev_type)), |
2153 | delta, |
2154 | np1, np2, eo, dpdbuf, |
2155 | (st->st_offloaded_task != NULL((void*)0) && !st->st_v1_offloaded_task_in_background) |
2156 | ? "crypto_calculating" : |
2157 | st->st_suspended_md != NULL((void*)0) ? "crypto/dns-lookup" : |
2158 | "idle"); |
2159 | |
2160 | /* print out SPIs if SAs are established */ |
2161 | if (state_buf2_len != 0) |
2162 | state_buf2[0] = '\0'; /* default to empty */ |
2163 | if (IS_IPSEC_SA_ESTABLISHED(st)(((st)->st_clonedfrom != 0) && ((st->st_state-> kind) == STATE_QUICK_I2 || (st->st_state->kind) == STATE_QUICK_R1 || (st->st_state->kind) == STATE_QUICK_R2 || (st->st_state ->kind) == STATE_V2_ESTABLISHED_CHILD_SA))) { |
2164 | char lastused[40]; /* should be plenty long enough */ |
2165 | char saids_buf[(1 + SATOT_BUFsizeof(said_buf)) * 6]; |
2166 | struct jambuf buf = ARRAY_AS_JAMBUF(saids_buf)array_as_jambuf((saids_buf), sizeof(saids_buf)); |
2167 | |
2168 | # define add_said(ADST, ASPI, APROTO) \ |
2169 | { \ |
2170 | ip_said s = said3(ADST, ASPI, APROTO); \ |
2171 | jam(&buf, " "); \ |
2172 | jam_said(&buf, &s); \ |
2173 | } |
2174 | |
2175 | /* |
2176 | * XXX - mcr last used is really an attribute of |
2177 | * the connection |
2178 | */ |
2179 | lastused[0] = '\0'; |
2180 | if (c->spd.eroute_owner == st->st_serialno && |
2181 | st->st_outbound_count != 0) { |
2182 | snprintf(lastused, sizeof(lastused), |
2183 | " used %jds ago;", |
2184 | deltasecs(monotimediff(mononow(), |
2185 | st->st_outbound_time))); |
2186 | } |
2187 | |
2188 | mbcp = traffic_buf + |
2189 | snprintf(traffic_buf, sizeof(traffic_buf) - 1, |
2190 | "Traffic:"); |
2191 | |
2192 | if (st->st_ah.present) { |
2193 | add_said(&c->spd.that.host_addr, st->st_ah.attrs.spi, |
2194 | &ip_protocol_ah); |
2195 | if (get_sa_info(st, FALSE0, NULL((void*)0))) { |
2196 | mbcp = readable_humber(st->st_ah.peer_bytes, |
2197 | mbcp, |
2198 | traffic_buf + |
2199 | sizeof(traffic_buf), |
2200 | " AHout="); |
2201 | } |
2202 | add_said(&c->spd.this.host_addr, st->st_ah.our_spi, |
2203 | &ip_protocol_ah); |
2204 | if (get_sa_info(st, TRUE1, NULL((void*)0))) { |
2205 | mbcp = readable_humber(st->st_ah.our_bytes, |
2206 | mbcp, |
2207 | traffic_buf + |
2208 | sizeof(traffic_buf), |
2209 | " AHin="); |
2210 | } |
2211 | mbcp = readable_humber( |
2212 | (u_long)st->st_ah.attrs.life_kilobytes, |
2213 | mbcp, |
2214 | traffic_buf + |
2215 | sizeof(traffic_buf), |
2216 | "! AHmax="); |
2217 | } |
2218 | if (st->st_esp.present) { |
2219 | add_said(&c->spd.that.host_addr, st->st_esp.attrs.spi, |
2220 | &ip_protocol_esp); |
2221 | if (get_sa_info(st, TRUE1, NULL((void*)0))) { |
2222 | mbcp = readable_humber(st->st_esp.our_bytes, |
2223 | mbcp, |
2224 | traffic_buf + |
2225 | sizeof(traffic_buf), |
2226 | " ESPin="); |
2227 | } |
2228 | add_said(&c->spd.this.host_addr, st->st_esp.our_spi, |
2229 | &ip_protocol_esp); |
2230 | if (get_sa_info(st, FALSE0, NULL((void*)0))) { |
2231 | mbcp = readable_humber(st->st_esp.peer_bytes, |
2232 | mbcp, |
2233 | traffic_buf + |
2234 | sizeof(traffic_buf), |
2235 | " ESPout="); |
2236 | } |
2237 | |
2238 | mbcp = readable_humber( |
2239 | (u_long)st->st_esp.attrs.life_kilobytes, |
2240 | mbcp, |
2241 | traffic_buf + |
2242 | sizeof(traffic_buf), |
2243 | "! ESPmax="); |
2244 | } |
2245 | if (st->st_ipcomp.present) { |
2246 | add_said(&c->spd.that.host_addr, |
2247 | st->st_ipcomp.attrs.spi, &ip_protocol_comp); |
2248 | if (get_sa_info(st, FALSE0, NULL((void*)0))) { |
2249 | mbcp = readable_humber( |
2250 | st->st_ipcomp.peer_bytes, |
2251 | mbcp, |
2252 | traffic_buf + |
2253 | sizeof(traffic_buf), |
2254 | " IPCOMPout="); |
2255 | } |
2256 | add_said(&c->spd.this.host_addr, st->st_ipcomp.our_spi, |
2257 | &ip_protocol_comp); |
2258 | if (get_sa_info(st, TRUE1, NULL((void*)0))) { |
2259 | mbcp = readable_humber( |
2260 | st->st_ipcomp.our_bytes, |
2261 | mbcp, |
2262 | traffic_buf + |
2263 | sizeof(traffic_buf), |
2264 | " IPCOMPin="); |
2265 | } |
2266 | |
2267 | /* mbcp not subsequently used */ |
2268 | mbcp = readable_humber( |
Value stored to 'mbcp' is never read | |
2269 | (u_long)st->st_ipcomp.attrs.life_kilobytes, |
2270 | mbcp, |
2271 | traffic_buf + sizeof(traffic_buf), |
2272 | "! IPCOMPmax="); |
2273 | } |
2274 | |
2275 | #if defined(XFRM_SUPPORT1) |
2276 | if (st->st_ah.attrs.mode == |
2277 | ENCAPSULATION_MODE_TUNNEL1 || |
2278 | st->st_esp.attrs.mode == |
2279 | ENCAPSULATION_MODE_TUNNEL1 || |
2280 | st->st_ipcomp.attrs.mode == |
2281 | ENCAPSULATION_MODE_TUNNEL1) { |
2282 | add_said(&c->spd.that.host_addr, st->st_tunnel_out_spi, |
2283 | &ip_protocol_ipip); |
2284 | add_said(&c->spd.this.host_addr, st->st_tunnel_in_spi, |
2285 | &ip_protocol_ipip); |
2286 | } |
2287 | #endif |
2288 | |
2289 | snprintf(state_buf2, state_buf2_len, |
2290 | "#%lu: \"%s\"%s%s%s %s %s%s", |
2291 | st->st_serialno, |
2292 | c->name, inst, |
2293 | lastused, |
2294 | saids_buf, |
2295 | traffic_buf, |
2296 | st->st_xauth_username[0] != '\0' ? "username=" : "", |
2297 | st->st_xauth_username); |
2298 | |
2299 | # undef add_said |
2300 | } |
2301 | } |
2302 | |
2303 | /* |
2304 | * sorting logic is: |
2305 | * name |
2306 | * state serial no# |
2307 | */ |
2308 | |
2309 | static int state_compare_serial(const void *a, const void *b) |
2310 | { |
2311 | const struct state *sap = *(const struct state *const *)a; |
2312 | const struct state *sbp = *(const struct state *const *)b; |
2313 | const so_serial_t a_sn = sap->st_serialno; |
2314 | const so_serial_t b_sn = sbp->st_serialno; |
2315 | struct connection *ca = sap->st_connection; |
2316 | struct connection *cb = sbp->st_connection; |
2317 | int ret; |
2318 | |
2319 | ret = strcmp(ca->name, cb->name); |
2320 | if (ret != 0) |
2321 | return ret; |
2322 | |
2323 | return a_sn < b_sn ? -1 : a_sn > b_sn ? 1 : 0; |
2324 | } |
2325 | |
2326 | /* |
2327 | * sorting logic is: |
2328 | * |
2329 | * name |
2330 | * type |
2331 | * instance# |
2332 | * isakmp_sa (XXX probably wrong) |
2333 | * state_compare_serial above |
2334 | */ |
2335 | static int state_compare_connection(const void *a, const void *b) |
2336 | { |
2337 | const struct state *sap = *(const struct state *const *)a; |
2338 | struct connection *ca = sap->st_connection; |
2339 | const struct state *sbp = *(const struct state *const *)b; |
2340 | struct connection *cb = sbp->st_connection; |
2341 | |
2342 | /* DBG_log("comparing %s to %s", ca->name, cb->name); */ |
2343 | |
2344 | int order = connection_compare(ca, cb); |
2345 | if (order != 0) { |
2346 | return order; |
2347 | } |
2348 | |
2349 | return state_compare_serial(a, b); |
2350 | } |
2351 | |
2352 | /* |
2353 | * NULL terminated array of state pointers. |
2354 | * |
2355 | * Returns NULL (rather than an array containing one NULL) when there |
2356 | * are no states. |
2357 | * |
2358 | * Caller is responsible for freeing the structure. |
2359 | */ |
2360 | static struct state **sort_states(int (*sort_fn)(const void *, const void *), |
2361 | const char *func) |
2362 | { |
2363 | /* COUNT the number of states. */ |
2364 | int count = 0; |
2365 | { |
2366 | dbg("FOR_EACH_STATE_... in %s (%s)", func, __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s (%s)", func, __func__ ); } }; |
2367 | struct state *st; |
2368 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
2369 | count++; |
2370 | } |
2371 | } |
2372 | |
2373 | if (count == 0) { |
2374 | return NULL((void*)0); |
2375 | } |
2376 | |
2377 | /* |
2378 | * Create an array of COUNT+1 (NULL terminal) state pointers. |
2379 | */ |
2380 | struct state **array = alloc_things(struct state *, count + 1, "sorted state")((struct state **) alloc_bytes(sizeof(struct state *) * (count + 1), ("sorted state"))); |
2381 | { |
2382 | int p = 0; |
2383 | |
2384 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
2385 | struct state *st; |
2386 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
2387 | passert(st != NULL){ _Bool assertion__ = st != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "state.c" , .line = 2387}, "%s", "st != NULL"); } }; |
2388 | array[p++] = st; |
2389 | } |
2390 | passert(p == count){ _Bool assertion__ = p == count; if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "state.c" , .line = 2390}, "%s", "p == count"); } }; |
2391 | array[p] = NULL((void*)0); |
2392 | } |
2393 | |
2394 | /* sort it! */ |
2395 | qsort(array, count, sizeof(struct state *), sort_fn); |
2396 | |
2397 | return array; |
2398 | } |
2399 | |
2400 | static int show_newest_state_traffic(struct connection *c, |
2401 | struct fd *unused_whackfd UNUSED__attribute__ ((unused)), |
2402 | void *arg) |
2403 | { |
2404 | struct show *s = arg; |
2405 | struct state *st = state_by_serialno(c->newest_ipsec_sa); |
2406 | |
2407 | if (st == NULL((void*)0)) |
2408 | return 0; |
2409 | |
2410 | show_state_traffic(s, RC_INFORMATIONAL_TRAFFIC, st); |
2411 | return 1; |
2412 | } |
2413 | |
2414 | void show_traffic_status(struct show *s, const char *name) |
2415 | { |
2416 | if (name == NULL((void*)0)) { |
2417 | struct state **array = sort_states(state_compare_serial, |
2418 | __func__); |
2419 | |
2420 | /* now print sorted results */ |
2421 | if (array != NULL((void*)0)) { |
2422 | int i; |
2423 | for (i = 0; array[i] != NULL((void*)0); i++) { |
2424 | show_state_traffic(s, |
2425 | RC_INFORMATIONAL_TRAFFIC, |
2426 | array[i]); |
2427 | } |
2428 | pfree(array); |
2429 | } |
2430 | } else { |
2431 | struct connection *c = conn_by_name(name, true1/*strict*/); |
2432 | |
2433 | if (c != NULL((void*)0)) { |
2434 | /* cast away const sillyness */ |
2435 | show_newest_state_traffic(c, NULL((void*)0), s); |
2436 | } else { |
2437 | /* cast away const sillyness */ |
2438 | int count = foreach_connection_by_alias(name, NULL((void*)0), |
2439 | show_newest_state_traffic, |
2440 | s); |
2441 | if (count == 0) { |
2442 | /* |
2443 | * XXX: don't bother implementing |
2444 | * show_rc(...) - this is the only |
2445 | * place where it would be useful. |
2446 | */ |
2447 | SHOW_JAMBUF(RC_UNKNOWN_NAME, s, buf)for (struct jambuf *buf = show_jambuf(s); buf != ((void*)0); jambuf_to_show (buf, s, RC_UNKNOWN_NAME), buf = ((void*)0)) { |
2448 | jam(buf, "no such connection or aliased connection named \"%s\"", name); |
2449 | } |
2450 | } |
2451 | } |
2452 | } |
2453 | } |
2454 | |
2455 | void show_brief_status(struct show *s) |
2456 | { |
2457 | show_separator(s); |
2458 | show_comment(s, "State Information: DDoS cookies %s, %s new IKE connections", |
2459 | require_ddos_cookies() ? "REQUIRED" : "not required", |
2460 | drop_new_exchanges() ? "NOT ACCEPTING" : "Accepting"); |
2461 | |
2462 | show_comment(s, "IKE SAs: total("PRI_CAT"%ld""), half-open("PRI_CAT"%ld""), open("PRI_CAT"%ld""), authenticated("PRI_CAT"%ld""), anonymous("PRI_CAT"%ld"")", |
2463 | total_ike_sa(), |
2464 | cat_count[CAT_HALF_OPEN_IKE_SA], |
2465 | cat_count[CAT_OPEN_IKE_SA], |
2466 | cat_count_ike_sa[CAT_AUTHENTICATED0], |
2467 | cat_count_ike_sa[CAT_ANONYMOUS1]); |
2468 | show_comment(s, "IPsec SAs: total("PRI_CAT"%ld""), authenticated("PRI_CAT"%ld""), anonymous("PRI_CAT"%ld"")", |
2469 | cat_count[CAT_ESTABLISHED_CHILD_SA], |
2470 | cat_count_child_sa[CAT_AUTHENTICATED0], |
2471 | cat_count_child_sa[CAT_ANONYMOUS1]); |
2472 | } |
2473 | |
2474 | void show_states(struct show *s) |
2475 | { |
2476 | show_separator(s); |
2477 | struct state **array = sort_states(state_compare_connection, |
2478 | __func__); |
2479 | |
2480 | if (array != NULL((void*)0)) { |
2481 | monotime_t n = mononow(); |
2482 | /* now print sorted results */ |
2483 | int i; |
2484 | for (i = 0; array[i] != NULL((void*)0); i++) { |
2485 | struct state *st = array[i]; |
2486 | |
2487 | char state_buf[LOG_WIDTH((size_t)1024)]; |
2488 | char state_buf2[LOG_WIDTH((size_t)1024)]; |
2489 | fmt_state(st, n, state_buf, sizeof(state_buf), |
2490 | state_buf2, sizeof(state_buf2)); |
2491 | show_comment(s, "%s", state_buf); |
2492 | if (state_buf2[0] != '\0') |
2493 | show_comment(s, "%s", state_buf2); |
2494 | |
2495 | /* show any associated pending Phase 2s */ |
2496 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) |
2497 | show_pending_phase2(s, st->st_connection, |
2498 | pexpect_ike_sa(st)); |
2499 | } |
2500 | pfree(array); |
2501 | } |
2502 | } |
2503 | |
2504 | /* |
2505 | * Given that we've used up a range of unused CPI's, |
2506 | * search for a new range of currently unused ones. |
2507 | * Note: this is very expensive when not trivial! |
2508 | * If we can't find one easily, choose 0 (a bad SPI, |
2509 | * no matter what order) indicating failure. |
2510 | */ |
2511 | void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi) |
2512 | { |
2513 | int tries = 0; |
2514 | cpi_t base = *latest_cpi; |
2515 | cpi_t closest; |
2516 | |
2517 | startover: |
2518 | closest = ~0; /* not close at all */ |
2519 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
2520 | struct state *st; |
2521 | FOR_EACH_STATE_NEW2OLD(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->older ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->older) { |
2522 | if (st->st_ipcomp.present) { |
2523 | cpi_t c = ntohl(st->st_ipcomp.our_spi) - base; |
2524 | |
2525 | if (c < closest) { |
2526 | if (c == 0) { |
2527 | /* |
2528 | * oops: next spot is |
2529 | * occupied; start over |
2530 | */ |
2531 | if (++tries == 20) { |
2532 | /* FAILURE */ |
2533 | *latest_cpi = 0; |
2534 | *first_busy_cpi = 0; |
2535 | return; |
2536 | } |
2537 | base++; |
2538 | if (base > IPCOMP_LAST_NEGOTIATED61439) |
2539 | base = IPCOMP_FIRST_NEGOTIATED256; |
2540 | |
2541 | /* really a tail call */ |
2542 | goto startover; |
2543 | } |
2544 | closest = c; |
2545 | } |
2546 | } |
2547 | } |
2548 | *latest_cpi = base; /* base is first in next free range */ |
2549 | *first_busy_cpi = closest + base; /* and this is the roof */ |
2550 | } |
2551 | |
2552 | /* |
2553 | * Muck with high-order 16 bits of this SPI in order to make |
2554 | * the corresponding SAID unique. |
2555 | * Its low-order 16 bits hold a well-known IPCOMP CPI. |
2556 | * Oh, and remember that SPIs are stored in network order. |
2557 | * Kludge!!! So I name it with the non-English word "uniquify". |
2558 | * If we can't find one easily, return 0 (a bad SPI, |
2559 | * no matter what order) indicating failure. |
2560 | * |
2561 | * v1-only. |
2562 | * cpi is in network order. |
2563 | */ |
2564 | ipsec_spi_t uniquify_peer_cpi(ipsec_spi_t cpi, const struct state *st, int tries) |
2565 | { |
2566 | /* cpi is in network order so first two bytes are the high order ones */ |
2567 | get_rnd_bytes((u_char *)&cpi, 2); |
2568 | |
2569 | /* |
2570 | * Make sure that the result is unique. |
2571 | * Hard work. If there is no unique value, we'll loop forever! |
2572 | */ |
2573 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
2574 | struct state *s; |
2575 | FOR_EACH_STATE_NEW2OLD(s)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.older; entry_ != ((void*)0); entry_ = ((void*)0)) for (s = (typeof(s))entry_->data, entry_ = entry_->older; s != ((void*)0); s = (typeof(s))entry_->data, entry_ = entry_ ->older) { |
2576 | if (s->st_ipcomp.present && |
2577 | sameaddr(&s->st_connection->spd.that.host_addr, |
2578 | &st->st_connection->spd.that.host_addr) && |
2579 | cpi == s->st_ipcomp.attrs.spi) |
2580 | { |
2581 | if (++tries == 20) |
2582 | return 0; /* FAILURE */ |
2583 | return uniquify_peer_cpi(cpi, st, tries); |
2584 | } |
2585 | } |
2586 | return cpi; |
2587 | } |
2588 | |
2589 | void merge_quirks(struct state *st, const struct msg_digest *md) |
2590 | { |
2591 | struct isakmp_quirks *dq = &st->quirks; |
2592 | const struct isakmp_quirks *sq = &md->quirks; |
2593 | |
2594 | dq->xauth_ack_msgid |= sq->xauth_ack_msgid; |
2595 | dq->modecfg_pull_mode |= sq->modecfg_pull_mode; |
2596 | /* ??? st->quirks.qnat_traversal is never used */ |
2597 | if (dq->qnat_traversal_vid < sq->qnat_traversal_vid) |
2598 | dq->qnat_traversal_vid = sq->qnat_traversal_vid; |
2599 | dq->xauth_vid |= sq->xauth_vid; |
2600 | } |
2601 | |
2602 | /* |
2603 | * see https://tools.ietf.org/html/rfc7296#section-2.23 |
2604 | * |
2605 | * [...] SHOULD store this as the new address and port combination |
2606 | * for the SA (that is, they SHOULD dynamically update the address). |
2607 | * A host behind a NAT SHOULD NOT do this type of dynamic address |
2608 | * update if a validated packet has different port and/or address |
2609 | * values because it opens a possible DoS attack (such as allowing |
2610 | * an attacker to break the connection with a single packet). |
2611 | * |
2612 | * The probe bool is used to signify we are answering a MOBIKE |
2613 | * probe request (basically a informational without UPDATE_ADDRESS |
2614 | */ |
2615 | void update_ike_endpoints(struct ike_sa *ike, |
2616 | const struct msg_digest *md) |
2617 | { |
2618 | /* caller must ensure we are not behind NAT */ |
2619 | ike->sa.st_remote_endpoint = md->sender; |
2620 | endpoint_buf eb1, eb2; |
2621 | dbg("#%lu updating local interface from %s to %s using md->iface "PRI_WHERE,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu updating local interface from %s to %s using md->iface " "(in %s() at %s:%lu)", ike->sa.st_serialno, ike->sa.st_interface != ((void*)0) ? str_endpoint(&ike->sa.st_interface-> local_endpoint, &eb1) : "<none>", str_endpoint(& md->iface->local_endpoint, &eb2), ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).func, ((where_t ) { .func = __func__, .basename = "state.c" , .line = 2625}). basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).line); } } |
2622 | ike->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu updating local interface from %s to %s using md->iface " "(in %s() at %s:%lu)", ike->sa.st_serialno, ike->sa.st_interface != ((void*)0) ? str_endpoint(&ike->sa.st_interface-> local_endpoint, &eb1) : "<none>", str_endpoint(& md->iface->local_endpoint, &eb2), ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).func, ((where_t ) { .func = __func__, .basename = "state.c" , .line = 2625}). basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).line); } } |
2623 | ike->sa.st_interface != NULL ? str_endpoint(&ike->sa.st_interface->local_endpoint, &eb1) : "<none>",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu updating local interface from %s to %s using md->iface " "(in %s() at %s:%lu)", ike->sa.st_serialno, ike->sa.st_interface != ((void*)0) ? str_endpoint(&ike->sa.st_interface-> local_endpoint, &eb1) : "<none>", str_endpoint(& md->iface->local_endpoint, &eb2), ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).func, ((where_t ) { .func = __func__, .basename = "state.c" , .line = 2625}). basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).line); } } |
2624 | str_endpoint(&md->iface->local_endpoint, &eb2),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu updating local interface from %s to %s using md->iface " "(in %s() at %s:%lu)", ike->sa.st_serialno, ike->sa.st_interface != ((void*)0) ? str_endpoint(&ike->sa.st_interface-> local_endpoint, &eb1) : "<none>", str_endpoint(& md->iface->local_endpoint, &eb2), ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).func, ((where_t ) { .func = __func__, .basename = "state.c" , .line = 2625}). basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).line); } } |
2625 | pri_where(HERE)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu updating local interface from %s to %s using md->iface " "(in %s() at %s:%lu)", ike->sa.st_serialno, ike->sa.st_interface != ((void*)0) ? str_endpoint(&ike->sa.st_interface-> local_endpoint, &eb1) : "<none>", str_endpoint(& md->iface->local_endpoint, &eb2), ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).func, ((where_t ) { .func = __func__, .basename = "state.c" , .line = 2625}). basename, ((where_t) { .func = __func__, .basename = "state.c" , .line = 2625}).line); } }; |
2626 | ike->sa.st_interface = md->iface; |
2627 | pexpect_st_local_endpoint(&ike->sa); |
2628 | } |
2629 | |
2630 | /* |
2631 | * We have successfully decrypted this packet, so we can update |
2632 | * the remote IP / port |
2633 | */ |
2634 | bool_Bool update_mobike_endpoints(struct ike_sa *ike, const struct msg_digest *md) |
2635 | { |
2636 | struct connection *c = ike->sa.st_connection; |
2637 | const struct ip_info *afi = endpoint_type(&md->iface->local_endpoint); |
2638 | |
2639 | /* |
2640 | * AA_201705 is this the right way to find Child SA(s)? |
2641 | * would it work if there are multiple Child SAs on this parent?? |
2642 | * would it work if the Child SA connection is different from IKE SA? |
2643 | * for now just do this one connection, later on loop over all Child SAs |
2644 | */ |
2645 | struct child_sa *child = child_sa_by_serialno(c->newest_ipsec_sa); |
2646 | |
2647 | /* check for all conditions before updating IPsec SA's */ |
2648 | if (afi != address_type(&c->spd.that.host_addr)) { |
2649 | libreswan_log("MOBIKE: AF change switching between v4 and v6 not supported")loglog(RC_LOG, "MOBIKE: AF change switching between v4 and v6 not supported" ); |
2650 | return false0; |
2651 | } |
2652 | |
2653 | passert(child->sa.st_connection == ike->sa.st_connection){ _Bool assertion__ = child->sa.st_connection == ike->sa .st_connection; if (!assertion__) { lsw_passert_fail((where_t ) { .func = __func__, .basename = "state.c" , .line = 2653}, "%s" , "child->sa.st_connection == ike->sa.st_connection"); } }; |
2654 | |
2655 | ip_endpoint old_endpoint; |
2656 | ip_endpoint new_endpoint; |
2657 | |
2658 | enum message_role md_role = v2_msg_role(md); |
2659 | switch (md_role) { |
2660 | case MESSAGE_RESPONSE: |
2661 | /* MOBIKE inititor processing response */ |
2662 | pexpect_st_local_endpoint(&ike->sa); |
2663 | old_endpoint = ike->sa.st_interface->local_endpoint; |
2664 | |
2665 | child->sa.st_mobike_local_endpoint = ike->sa.st_mobike_local_endpoint; |
2666 | child->sa.st_mobike_host_nexthop = ike->sa.st_mobike_host_nexthop; |
2667 | |
2668 | new_endpoint = ike->sa.st_mobike_local_endpoint; |
2669 | break; |
2670 | case MESSAGE_REQUEST: |
2671 | /* MOBIKE responder processing request */ |
2672 | old_endpoint = ike->sa.st_remote_endpoint; |
2673 | |
2674 | child->sa.st_mobike_remote_endpoint = md->sender; |
2675 | ike->sa.st_mobike_remote_endpoint = md->sender; |
2676 | |
2677 | new_endpoint =md->sender; |
2678 | break; |
2679 | default: |
2680 | bad_case(md_role)libreswan_bad_case("md_role", (md_role), (where_t) { .func = __func__ , .basename = "state.c" , .line = 2680}); |
2681 | } |
2682 | |
2683 | char buf[256]; |
2684 | endpoint_buf old; |
2685 | endpoint_buf new; |
2686 | snprintf(buf, sizeof(buf), "MOBIKE update %s address %s -> %s", |
2687 | md_role == MESSAGE_RESPONSE ? "local" : "remote", |
2688 | str_sensitive_endpoint(&old_endpoint, &old), |
2689 | str_sensitive_endpoint(&new_endpoint, &new)); |
2690 | |
2691 | dbg("#%lu pst=#%lu %s", child->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu pst=#%lu %s", child->sa.st_serialno, ike ->sa.st_serialno, buf); } } |
2692 | ike->sa.st_serialno, buf){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu pst=#%lu %s", child->sa.st_serialno, ike ->sa.st_serialno, buf); } }; |
2693 | |
2694 | if (endpoint_eq(old_endpoint, new_endpoint)) { |
2695 | if (md_role == MESSAGE_REQUEST) { |
2696 | /* on responder NAT could hide end-to-end change */ |
2697 | endpoint_buf b; |
2698 | libreswan_log("MOBIKE success no change to kernel SA same IP address ad port %s",loglog(RC_LOG, "MOBIKE success no change to kernel SA same IP address ad port %s" , str_sensitive_endpoint(&old_endpoint, &b)) |
2699 | str_sensitive_endpoint(&old_endpoint, &b))loglog(RC_LOG, "MOBIKE success no change to kernel SA same IP address ad port %s" , str_sensitive_endpoint(&old_endpoint, &b)); |
2700 | |
2701 | return true1; |
2702 | } |
2703 | } |
2704 | |
2705 | if (!migrate_ipsec_sa(&child->sa)) { |
2706 | libreswan_log("%s FAILED", buf)loglog(RC_LOG, "%s FAILED", buf); |
2707 | return false0; |
2708 | } |
2709 | |
2710 | libreswan_log(" success %s", buf)loglog(RC_LOG, " success %s", buf); |
2711 | |
2712 | switch (md_role) { |
2713 | case MESSAGE_RESPONSE: |
2714 | /* MOBIKE initiator processing response */ |
2715 | c->spd.this.host_addr = endpoint_address(&child->sa.st_mobike_local_endpoint); |
2716 | c->spd.this.host_port = endpoint_hport(&child->sa.st_mobike_local_endpoint); |
2717 | c->spd.this.host_nexthop = child->sa.st_mobike_host_nexthop; |
2718 | |
2719 | ike->sa.st_interface = child->sa.st_interface = md->iface; |
2720 | break; |
2721 | case MESSAGE_REQUEST: |
2722 | /* MOBIKE responder processing request */ |
2723 | c->spd.that.host_addr = md->sender; |
2724 | c->spd.that.host_port = endpoint_hport(&md->sender); |
2725 | |
2726 | /* for the consistency, correct output in ipsec status */ |
2727 | child->sa.st_remote_endpoint = ike->sa.st_remote_endpoint = md->sender; |
2728 | child->sa.st_interface = ike->sa.st_interface = md->iface; |
2729 | break; |
2730 | default: |
2731 | bad_case(md_role)libreswan_bad_case("md_role", (md_role), (where_t) { .func = __func__ , .basename = "state.c" , .line = 2731}); |
2732 | } |
2733 | pexpect_st_local_endpoint(&ike->sa); |
2734 | pexpect_st_local_endpoint(&child->sa); |
2735 | |
2736 | /* reset liveness */ |
2737 | ike->sa.st_pend_liveness = FALSE0; |
2738 | ike->sa.st_last_liveness = monotime_epoch; |
2739 | |
2740 | delete_oriented_hp(c); /* hp list may have changed */ |
2741 | if (!orient(c)) { |
2742 | pexpect_fail(ike->sa.st_logger, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 2742}, |
2743 | "%s after mobike failed", "orient"); |
2744 | } |
2745 | /* assumption: orientation has not changed */ |
2746 | connect_to_host_pair(c); /* re-create hp listing */ |
2747 | |
2748 | if (md_role == MESSAGE_RESPONSE) { |
2749 | /* MOBIKE initiator processing response */ |
2750 | migration_up(child->sa.st_connection, &child->sa); |
2751 | ike->sa.st_deleted_local_addr = address_any(&ipv4_info); |
2752 | child->sa.st_deleted_local_addr = address_any(&ipv4_info); |
2753 | if (dpd_active_locally(&child->sa) && child->sa.st_liveness_event == NULL((void*)0)) { |
2754 | dbg("dpd re-enabled after mobike, scheduling ikev2 liveness checks"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("dpd re-enabled after mobike, scheduling ikev2 liveness checks" ); } }; |
2755 | deltatime_t delay = deltatime_max(child->sa.st_connection->dpd_delay, deltatime(MIN_LIVENESS1)); |
2756 | event_schedule(EVENT_v2_LIVENESS, delay, &child->sa); |
2757 | } |
2758 | } |
2759 | |
2760 | return true1; |
2761 | } |
2762 | |
2763 | /* seems to be a good spot for now */ |
2764 | bool_Bool dpd_active_locally(const struct state *st) |
2765 | { |
2766 | return deltasecs(st->st_connection->dpd_delay) != 0 && |
2767 | deltasecs(st->st_connection->dpd_timeout) != 0; |
2768 | } |
2769 | |
2770 | /* |
2771 | * Find all CHILD SAs belonging to FROM and migrate them to TO. |
2772 | */ |
2773 | |
2774 | struct v2_migrate_filter { |
2775 | struct ike_sa *from; |
2776 | struct child_sa *to; |
2777 | }; |
2778 | |
2779 | static bool_Bool v2_migrate_predicate(struct state *st, void *context) |
2780 | { |
2781 | struct v2_migrate_filter *filter = context; |
2782 | passert(st->st_serialno != filter->to->sa.st_serialno){ _Bool assertion__ = st->st_serialno != filter->to-> sa.st_serialno; if (!assertion__) { lsw_passert_fail((where_t ) { .func = __func__, .basename = "state.c" , .line = 2782}, "%s" , "st->st_serialno != filter->to->sa.st_serialno"); } }; |
2783 | /* |
2784 | * Migrate the CHILD SA. |
2785 | * |
2786 | * Just the IKE_SPIrehash the SPIs without moving entry. |
2787 | * |
2788 | * XXX: this should also wipe message counters but first need |
2789 | * evidence. |
2790 | */ |
2791 | dbg("#%lu migrated from IKE SA #%lu to IKE SA #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu migrated from IKE SA #%lu to IKE SA #%lu" , st->st_serialno, filter->from->sa.st_serialno, filter ->to->sa.st_serialno); } } |
2792 | st->st_serialno, filter->from->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu migrated from IKE SA #%lu to IKE SA #%lu" , st->st_serialno, filter->from->sa.st_serialno, filter ->to->sa.st_serialno); } } |
2793 | filter->to->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu migrated from IKE SA #%lu to IKE SA #%lu" , st->st_serialno, filter->from->sa.st_serialno, filter ->to->sa.st_serialno); } }; |
2794 | st->st_clonedfrom = filter->to->sa.st_serialno; |
2795 | st->st_ike_spis = filter->to->sa.st_ike_spis; |
2796 | /* |
2797 | * Delete the old IKE_SPI hash entries (both for I and I+R |
2798 | * and), and then inserts new ones using ST's current IKE SPI |
2799 | * values. The serialno tables are not touched. |
2800 | */ |
2801 | rehash_state_cookies_in_db(st); |
2802 | return false0; /* keep going */ |
2803 | } |
2804 | |
2805 | void v2_migrate_children(struct ike_sa *from, struct child_sa *to) |
2806 | { |
2807 | /* |
2808 | * TO is in the process of being emancipated. It's |
2809 | * .st_clonedfrom has been zapped and the new IKE_SPIs |
2810 | * installed (a true child would have FROM's IKE SPIs). |
2811 | * |
2812 | * While FROM and TO should have different IKE_SPIs there's |
2813 | * nothing to force them both being different - relying on |
2814 | * luck. |
2815 | */ |
2816 | passert(to->sa.st_clonedfrom == SOS_NOBODY){ _Bool assertion__ = to->sa.st_clonedfrom == 0; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "state.c" , .line = 2816}, "%s", "to->sa.st_clonedfrom == SOS_NOBODY" ); } }; |
2817 | /* passert(SPIs should be different) */ |
2818 | |
2819 | /* |
2820 | * Use ..._NEW2OLD() to iterate over the slot. Since this |
2821 | * macro maintains a "cursor" that is one ahead of ST it is |
2822 | * safe for rehash_state_cookies_in_db(st) to delete the old |
2823 | * hash entries. Similarly, since the table is walked |
2824 | * NEW2OLD, insert will happen at the front of the table |
2825 | * which, the cursor is past (this odds of this are very low). |
2826 | */ |
2827 | struct v2_migrate_filter filter = { |
2828 | .from = from, |
2829 | .to = to, |
2830 | }; |
2831 | state_by_ike_spis(IKEv2, |
2832 | &from->sa.st_serialno, |
2833 | NULL((void*)0)/*ignore v1 msgid*/, |
2834 | NULL((void*)0)/*ignore-sa-role*/, |
2835 | &from->sa.st_ike_spis, |
2836 | v2_migrate_predicate, &filter, __func__); |
2837 | } |
2838 | |
2839 | static bool_Bool delete_ike_family_child(struct state *st, void *unused_context UNUSED__attribute__ ((unused))) |
2840 | { |
2841 | struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "state.c" , .line = 2841}); |
2842 | /* pass down whack fd; better abstraction? */ |
2843 | if (ike != NULL((void*)0) && fd_p(ike->sa.st_logger->global_whackfd)) { |
2844 | close_any(&st->st_logger->global_whackfd)close_any_fd((&st->st_logger->global_whackfd), (where_t ) { .func = __func__, .basename = "state.c" , .line = 2844}); |
2845 | st->st_logger->global_whackfd = dup_any(ike->sa.st_logger->global_whackfd)dup_any_fd((ike->sa.st_logger->global_whackfd), (where_t ) { .func = __func__, .basename = "state.c" , .line = 2845}); |
2846 | } |
2847 | switch (st->st_ike_version) { |
2848 | case IKEv1: |
2849 | break; |
2850 | case IKEv2: |
2851 | st->st_dont_send_delete = true1; |
2852 | break; |
2853 | } |
2854 | delete_state(st); |
2855 | return false0; /* keep going */ |
2856 | } |
2857 | |
2858 | void delete_ike_family(struct ike_sa *ike, enum send_delete send_delete) |
2859 | { |
2860 | /* |
2861 | * We are a parent: delete our children and |
2862 | * then prepare to delete ourself. |
2863 | * Our children will be on the same hash chain |
2864 | * because we share IKE SPIs. |
2865 | */ |
2866 | state_by_ike_spis(ike->sa.st_ike_version, |
2867 | &ike->sa.st_serialno, |
2868 | NULL((void*)0)/*ignore v1 msgid*/, |
2869 | NULL((void*)0)/*ignore-sa-role*/, |
2870 | &ike->sa.st_ike_spis, |
2871 | delete_ike_family_child, NULL((void*)0), |
2872 | __func__); |
2873 | /* delete self */ |
2874 | switch (send_delete) { |
2875 | case DONT_SEND_DELETE: |
2876 | ike->sa.st_dont_send_delete = true1; |
2877 | break; |
2878 | case PROBABLY_SEND_DELETE: |
2879 | /* let delete_state()'s vodo make the decision */ |
2880 | break; |
2881 | } |
2882 | delete_state(&ike->sa); |
2883 | } |
2884 | |
2885 | /* |
2886 | * if the state is too busy to process a packet, say so |
2887 | * |
2888 | * Two things indicate this - st_suspended_md is non-NULL or there's |
2889 | * an offloaded task. |
2890 | */ |
2891 | |
2892 | struct msg_digest *unsuspend_md(struct state *st) |
2893 | { |
2894 | /* don't assume it is non-NULL */ |
2895 | struct msg_digest *md = st->st_suspended_md; |
2896 | st->st_suspended_md = NULL((void*)0); |
2897 | st->st_suspended_md_func = NULL((void*)0); |
2898 | st->st_suspended_md_line = 0; |
2899 | dbg("unsuspending #%lu MD %p", st->st_serialno, md){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("unsuspending #%lu MD %p", st->st_serialno, md); } }; |
2900 | return md; |
2901 | } |
2902 | |
2903 | bool_Bool state_is_busy(const struct state *st) |
2904 | { |
2905 | passert(st != NULL){ _Bool assertion__ = st != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "state.c" , .line = 2905}, "%s", "st != NULL"); } }; |
2906 | /* |
2907 | * Ignore a packet if the state has a suspended state |
2908 | * transition. Probably a duplicated packet but the original |
2909 | * packet is not yet recorded in st->st_v1_rpacket, so duplicate |
2910 | * checking won't catch. |
2911 | * |
2912 | * ??? Should the packet be recorded earlier to improve |
2913 | * diagnosis? |
2914 | * |
2915 | * See comments in state.h. |
2916 | * |
2917 | * ST_SUSPENDED_MD acts as a poor proxy for indicating a busy |
2918 | * state. For instance, the initial initiator (both IKEv1 and |
2919 | * IKEv2) doesn't have a suspended MD. To get around this a |
2920 | * 'fake_md' MD is created. |
2921 | * |
2922 | * XXX: what about xauth? It sets ST_SUSPENDED_MD. |
2923 | */ |
2924 | if (st->st_suspended_md != NULL((void*)0)) { |
2925 | dbg("#%lu is busy; has suspended MD %p",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is busy; has suspended MD %p", st->st_serialno , st->st_suspended_md); } } |
2926 | st->st_serialno, st->st_suspended_md){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is busy; has suspended MD %p", st->st_serialno , st->st_suspended_md); } }; |
2927 | return true1; |
2928 | } |
2929 | /* |
2930 | * If IKEv1 is doing something in the background then the |
2931 | * state isn't busy. |
2932 | */ |
2933 | if (st->st_v1_offloaded_task_in_background) { |
2934 | pexpect(st->st_offloaded_task != NULL)({ _Bool assertion__ = st->st_offloaded_task != ((void*)0) ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "state.c" , .line = 2934}, "%s", "st->st_offloaded_task != NULL" ); } assertion__; }); |
2935 | dbg("#%lu is idle; has background offloaded task",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is idle; has background offloaded task", st->st_serialno); } } |
2936 | st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is idle; has background offloaded task", st->st_serialno); } }; |
2937 | return false0; |
2938 | } |
2939 | /* |
2940 | * If this state is busy calculating. |
2941 | */ |
2942 | if (st->st_offloaded_task != NULL((void*)0)) { |
2943 | dbg("#%lu is busy; has an offloaded task",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is busy; has an offloaded task", st-> st_serialno); } } |
2944 | st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is busy; has an offloaded task", st-> st_serialno); } }; |
2945 | return true1; |
2946 | } |
2947 | dbg("#%lu is idle", st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu is idle", st->st_serialno); } }; |
2948 | return false0; |
2949 | } |
2950 | |
2951 | bool_Bool verbose_state_busy(const struct state *st) |
2952 | { |
2953 | if (st == NULL((void*)0)) { |
2954 | dbg("#null state always idle"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#null state always idle"); } }; |
2955 | return false0; |
2956 | } |
2957 | if (!state_is_busy(st)) { |
2958 | dbg("#%lu idle", st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu idle", st->st_serialno); } }; |
2959 | return false0; |
2960 | } |
2961 | if (st->st_suspended_md != NULL((void*)0)) { |
2962 | /* not whack */ |
2963 | /* XXX: why not whack? */ |
2964 | /* XXX: can this and below be merged; is there always an offloaded task? */ |
2965 | log_state(LOG_STREAM/*not-whack*/, st, |
2966 | "discarding packet received during asynchronous work (DNS or crypto) in %s", |
2967 | st->st_state->name); |
2968 | } else if (st->st_offloaded_task != NULL((void*)0)) { |
2969 | log_state(RC_LOG, st, "message received while calculating. Ignored."); |
2970 | } |
2971 | return true1; |
2972 | } |
2973 | |
2974 | bool_Bool require_ddos_cookies(void) |
2975 | { |
2976 | return pluto_ddos_mode == DDOS_FORCE_BUSY || |
2977 | (pluto_ddos_mode == DDOS_AUTO && |
2978 | cat_count[CAT_HALF_OPEN_IKE_SA] >= pluto_ddos_threshold); |
2979 | } |
2980 | |
2981 | bool_Bool drop_new_exchanges(void) |
2982 | { |
2983 | return cat_count[CAT_HALF_OPEN_IKE_SA] >= pluto_max_halfopen; |
2984 | } |
2985 | |
2986 | void show_globalstate_status(struct show *s) |
2987 | { |
2988 | unsigned shunts = shunt_count(); |
2989 | |
2990 | show_raw(s, "config.setup.ike.ddos_threshold=%u", pluto_ddos_threshold); |
2991 | show_raw(s, "config.setup.ike.max_halfopen=%u", pluto_max_halfopen); |
2992 | |
2993 | /* technically shunts are not a struct state's - but makes it easier to group */ |
2994 | show_raw(s, "current.states.all="PRI_CAT"%ld", shunts + total_sa()); |
2995 | show_raw(s, "current.states.ipsec="PRI_CAT"%ld", cat_count[CAT_ESTABLISHED_CHILD_SA]); |
2996 | show_raw(s, "current.states.ike="PRI_CAT"%ld", total_ike_sa()); |
2997 | show_raw(s, "current.states.shunts=%u", shunts); |
2998 | show_raw(s, "current.states.iketype.anonymous="PRI_CAT"%ld", cat_count_ike_sa[CAT_ANONYMOUS1]); |
2999 | show_raw(s, "current.states.iketype.authenticated="PRI_CAT"%ld", cat_count_ike_sa[CAT_AUTHENTICATED0]); |
3000 | show_raw(s, "current.states.iketype.halfopen="PRI_CAT"%ld", cat_count[CAT_HALF_OPEN_IKE_SA]); |
3001 | show_raw(s, "current.states.iketype.open="PRI_CAT"%ld", cat_count[CAT_OPEN_IKE_SA]); |
3002 | for (enum state_kind sk = STATE_IKEv1_FLOOR; sk < STATE_IKEv1_ROOF; sk++) { |
3003 | const struct finite_state *fs = finite_states[sk]; |
3004 | show_raw(s, "current.states.enumerate.%s="PRI_CAT"%ld", |
3005 | fs->name, state_count[sk]); |
3006 | } |
3007 | for (enum state_kind sk = STATE_IKEv2_FLOOR; sk < STATE_IKEv2_ROOF; sk++) { |
3008 | const struct finite_state *fs = finite_states[sk]; |
3009 | show_raw(s, "current.states.enumerate.%s="PRI_CAT"%ld", |
3010 | fs->name, state_count[sk]); |
3011 | } |
3012 | } |
3013 | |
3014 | static void log_newest_sa_change(const char *f, so_serial_t old_ipsec_sa, |
3015 | struct state *const st) |
3016 | { |
3017 | dbg("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu" , f, st->st_connection->name, st->st_connection-> instance_serial, enum_name(&ike_version_names, st->st_ike_version ), st->st_connection->newest_ipsec_sa, old_ipsec_sa, st ->st_connection->spd.eroute_owner, st->st_clonedfrom ); } } |
3018 | f, st->st_connection->name,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu" , f, st->st_connection->name, st->st_connection-> instance_serial, enum_name(&ike_version_names, st->st_ike_version ), st->st_connection->newest_ipsec_sa, old_ipsec_sa, st ->st_connection->spd.eroute_owner, st->st_clonedfrom ); } } |
3019 | st->st_connection->instance_serial,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu" , f, st->st_connection->name, st->st_connection-> instance_serial, enum_name(&ike_version_names, st->st_ike_version ), st->st_connection->newest_ipsec_sa, old_ipsec_sa, st ->st_connection->spd.eroute_owner, st->st_clonedfrom ); } } |
3020 | enum_name(&ike_version_names, st->st_ike_version),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu" , f, st->st_connection->name, st->st_connection-> instance_serial, enum_name(&ike_version_names, st->st_ike_version ), st->st_connection->newest_ipsec_sa, old_ipsec_sa, st ->st_connection->spd.eroute_owner, st->st_clonedfrom ); } } |
3021 | st->st_connection->newest_ipsec_sa, old_ipsec_sa,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu" , f, st->st_connection->name, st->st_connection-> instance_serial, enum_name(&ike_version_names, st->st_ike_version ), st->st_connection->newest_ipsec_sa, old_ipsec_sa, st ->st_connection->spd.eroute_owner, st->st_clonedfrom ); } } |
3022 | st->st_connection->spd.eroute_owner,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu" , f, st->st_connection->name, st->st_connection-> instance_serial, enum_name(&ike_version_names, st->st_ike_version ), st->st_connection->newest_ipsec_sa, old_ipsec_sa, st ->st_connection->spd.eroute_owner, st->st_clonedfrom ); } } |
3023 | st->st_clonedfrom){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: instance %s[%lu], setting %s newest_ipsec_sa to #%lu (was #%lu) (spd.eroute=#%lu) cloned from #%lu" , f, st->st_connection->name, st->st_connection-> instance_serial, enum_name(&ike_version_names, st->st_ike_version ), st->st_connection->newest_ipsec_sa, old_ipsec_sa, st ->st_connection->spd.eroute_owner, st->st_clonedfrom ); } }; |
3024 | } |
3025 | |
3026 | void set_newest_ipsec_sa(const char *m, struct state *const st) |
3027 | { |
3028 | so_serial_t old_ipsec_sa = st->st_connection->newest_ipsec_sa; |
3029 | |
3030 | st->st_connection->newest_ipsec_sa = st->st_serialno; |
3031 | log_newest_sa_change(m, old_ipsec_sa, st); |
3032 | } |
3033 | |
3034 | void record_newaddr(ip_address *ip, char *a_type) |
3035 | { |
3036 | address_buf ip_str; |
3037 | dbg("XFRM RTM_NEWADDR %s %s", str_address(ip, &ip_str), a_type){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XFRM RTM_NEWADDR %s %s", str_address(ip, & ip_str), a_type); } }; |
3038 | for_each_state(ikev2_record_newaddr, ip, __func__); |
3039 | } |
3040 | |
3041 | void record_deladdr(ip_address *ip, char *a_type) |
3042 | { |
3043 | address_buf ip_str; |
3044 | dbg("XFRM RTM_DELADDR %s %s", str_address(ip, &ip_str), a_type){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XFRM RTM_DELADDR %s %s", str_address(ip, & ip_str), a_type); } }; |
3045 | for_each_state(ikev2_record_deladdr, ip, __func__); |
3046 | } |
3047 | |
3048 | static void append_word(char **sentence, const char *word) |
3049 | { |
3050 | size_t sl = strlen(*sentence); |
3051 | size_t wl = strlen(word); |
3052 | char *ns = alloc_bytes(sl + 1 + wl + 1, "sentence"); |
3053 | |
3054 | memcpy(ns, *sentence, sl); |
3055 | ns[sl] = ' '; |
3056 | memcpy(&ns[sl + 1], word, wl+1); /* includes NUL */ |
3057 | pfree(*sentence); |
3058 | *sentence = ns; |
3059 | } |
3060 | |
3061 | /* |
3062 | * Moved from ikev1_xauth.c since IKEv2 code now also uses it |
3063 | * Converted to store ephemeral data in the state, not connection |
3064 | */ |
3065 | void append_st_cfg_dns(struct state *st, const char *dnsip) |
3066 | { |
3067 | if (st->st_seen_cfg_dns == NULL((void*)0)) { |
3068 | st->st_seen_cfg_dns = clone_str(dnsip, "fresh append_st_cfg_dns")((dnsip) == ((void*)0) ? ((void*)0) : clone_bytes((dnsip), strlen ((dnsip)) + 1, ("fresh append_st_cfg_dns"))); |
3069 | } else { |
3070 | append_word(&st->st_seen_cfg_dns, dnsip); |
3071 | } |
3072 | } |
3073 | |
3074 | void append_st_cfg_domain(struct state *st, char *domain) |
3075 | { |
3076 | /* note: we are responsible to ensure domain is freed */ |
3077 | if (st->st_seen_cfg_domains == NULL((void*)0)) { |
3078 | st->st_seen_cfg_domains = domain; |
3079 | } else { |
3080 | append_word(&st->st_seen_cfg_domains, domain); |
3081 | pfree(domain); |
3082 | } |
3083 | } |
3084 | |
3085 | static void suppress_delete_notify(const struct ike_sa *ike, |
3086 | const char *what, so_serial_t so) |
3087 | { |
3088 | struct state *st = state_by_serialno(so); |
3089 | if (st == NULL((void*)0)) { |
3090 | log_state(RC_LOG, &ike->sa, |
3091 | "did not find old %s state #%lu to mark for suppressing delete", |
3092 | what, so); |
3093 | return; |
3094 | } |
3095 | |
3096 | st->st_dont_send_delete = true1; |
3097 | dbg("marked %s state #%lu to suppress sending delete notify",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("marked %s state #%lu to suppress sending delete notify" , what, st->st_serialno); } } |
3098 | what, st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("marked %s state #%lu to suppress sending delete notify" , what, st->st_serialno); } }; |
3099 | } |
3100 | |
3101 | /* |
3102 | * an ISAKMP SA has been established. |
3103 | * Note the serial number, and release any connections with |
3104 | * the same peer ID but different peer IP address. |
3105 | * |
3106 | * Called by IKEv1 and IKEv2 when the IKE SA is established. |
3107 | * It checks if the freshly established connection needs is |
3108 | * replacing an established version of itself. |
3109 | * |
3110 | * The use of uniqueIDs is mostly historic and might be removed |
3111 | * in a future version. It is ignored for PSK based connections, |
3112 | * which only act based on being a "server using PSK". |
3113 | * |
3114 | * IKEv1 code does not send or process INITIAL_CONTACT |
3115 | * IKEv2 codes does so we take it into account. |
3116 | */ |
3117 | |
3118 | void IKE_SA_established(const struct ike_sa *ike) |
3119 | { |
3120 | struct connection *c = ike->sa.st_connection; |
3121 | bool_Bool authnull = (LIN(POLICY_AUTH_NULL, c->policy)(((((lset_t)1 << (POLICY_AUTH_NULL_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_AUTH_NULL_IX)))) || c->spd.that.authby == AUTHBY_NULL); |
3122 | |
3123 | if (c->spd.this.xauth_server && LIN(POLICY_PSK, c->policy)(((((lset_t)1 << (POLICY_PSK_IX))) & (c->policy) ) == (((lset_t)1 << (POLICY_PSK_IX))))) { |
3124 | /* |
3125 | * If we are a server and use PSK, all clients use the same group ID |
3126 | * Note that "xauth_server" also refers to IKEv2 CP |
3127 | */ |
3128 | dbg("We are a server using PSK and clients are using a group ID"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("We are a server using PSK and clients are using a group ID" ); } }; |
3129 | } else if (!uniqueIDs) { |
3130 | dbg("uniqueIDs disabled, not contemplating releasing older self"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("uniqueIDs disabled, not contemplating releasing older self" ); } }; |
3131 | } else { |
3132 | /* |
3133 | * for all existing connections: if the same Phase 1 IDs are used, |
3134 | * unorient the (old) connection (if different from current connection) |
3135 | * Only do this for connections with the same name (can be shared ike sa) |
3136 | */ |
3137 | dbg("FOR_EACH_CONNECTION_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_CONNECTION_... in %s", __func__); } }; |
3138 | for (struct connection *d = connections; d != NULL((void*)0); ) { |
3139 | /* might move underneath us */ |
3140 | struct connection *next = d->ac_next; |
3141 | |
3142 | /* if old IKE SA is same as new IKE sa and non-auth isn't overwrting auth */ |
3143 | if (c != d && c->kind == d->kind && streq(c->name, d->name)(strcmp((c->name), (d->name)) == 0) && |
3144 | same_id(&c->spd.this.id, &d->spd.this.id) && |
3145 | same_id(&c->spd.that.id, &d->spd.that.id)) |
3146 | { |
3147 | bool_Bool old_is_nullauth = (LIN(POLICY_AUTH_NULL, d->policy)(((((lset_t)1 << (POLICY_AUTH_NULL_IX))) & (d->policy )) == (((lset_t)1 << (POLICY_AUTH_NULL_IX)))) || d->spd.that.authby == AUTHBY_NULL); |
3148 | bool_Bool same_remote_ip = sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr); |
3149 | |
3150 | if (same_remote_ip && (!old_is_nullauth && authnull)) { |
3151 | log_state(RC_LOG, &ike->sa, "cannot replace old authenticated connection with authnull connection"); |
3152 | } else if (!same_remote_ip && old_is_nullauth && authnull) { |
3153 | log_state(RC_LOG, &ike->sa, "NULL auth ID for different IP's cannot replace each other"); |
3154 | } else { |
3155 | dbg("unorienting old connection with same IDs"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("unorienting old connection with same IDs"); } }; |
3156 | /* |
3157 | * When replacing an old |
3158 | * existing connection, |
3159 | * suppress sending delete |
3160 | * notify |
3161 | */ |
3162 | suppress_delete_notify(ike, "ISAKMP", d->newest_isakmp_sa); |
3163 | suppress_delete_notify(ike, "IKE", d->newest_ipsec_sa); |
3164 | /* |
3165 | * XXX: assume this call |
3166 | * doesn't want to log to |
3167 | * whack(?). While PST still |
3168 | * has an attached whack, the |
3169 | * global whack that this call |
3170 | * would have used detached |
3171 | * long ago. |
3172 | */ |
3173 | release_connection(d, false0, null_fd((struct fd *) ((void*)0))); /* this deletes the states */ |
3174 | } |
3175 | } |
3176 | d = next; |
3177 | } |
3178 | |
3179 | /* |
3180 | * This only affects IKEv2, since we don't store any |
3181 | * received INITIAL_CONTACT for IKEv1. |
3182 | * We don't do this on IKEv1, because it seems to |
3183 | * confuse various third parties (Windows, Cisco VPN 300, |
3184 | * and juniper |
3185 | * likely because this would be called before the IPsec SA |
3186 | * of QuickMode is installed, so the remote endpoints view |
3187 | * this IKE SA still as the active one? |
3188 | */ |
3189 | if (ike->sa.st_seen_initialc) { |
3190 | if (c->newest_isakmp_sa != SOS_NOBODY0 && |
3191 | c->newest_isakmp_sa != ike->sa.st_serialno) { |
3192 | struct state *old_p1 = state_by_serialno(c->newest_isakmp_sa); |
3193 | |
3194 | dbg("deleting replaced IKE state for %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting replaced IKE state for %s", old_p1-> st_connection->name); } } |
3195 | old_p1->st_connection->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting replaced IKE state for %s", old_p1-> st_connection->name); } }; |
3196 | old_p1->st_dont_send_delete = true1; |
3197 | event_force(EVENT_SA_EXPIRE, old_p1); |
3198 | } |
3199 | |
3200 | if (c->newest_ipsec_sa != SOS_NOBODY0) { |
3201 | struct state *old_p2 = state_by_serialno(c->newest_ipsec_sa); |
3202 | struct connection *d = old_p2 == NULL((void*)0) ? NULL((void*)0) : old_p2->st_connection; |
3203 | |
3204 | if (c == d && same_id(&c->spd.that.id, &d->spd.that.id)) { |
3205 | dbg("Initial Contact received, deleting old state #%lu from connection '%s'",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initial Contact received, deleting old state #%lu from connection '%s'" , c->newest_ipsec_sa, c->name); } } |
3206 | c->newest_ipsec_sa, c->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initial Contact received, deleting old state #%lu from connection '%s'" , c->newest_ipsec_sa, c->name); } }; |
3207 | old_p2->st_dont_send_delete = true1; |
3208 | event_force(EVENT_SA_EXPIRE, old_p2); |
3209 | } |
3210 | } |
3211 | } |
3212 | } |
3213 | |
3214 | c->newest_isakmp_sa = ike->sa.st_serialno; |
3215 | } |
3216 | |
3217 | static void list_state_event(struct show *s, struct state *st, |
3218 | struct pluto_event *pe, monotime_t now) |
3219 | { |
3220 | if (pe != NULL((void*)0)) { |
3221 | pexpect(st == pe->ev_state)({ _Bool assertion__ = st == pe->ev_state; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "state.c" , .line = 3221}, "%s", "st == pe->ev_state"); } assertion__ ; }); |
3222 | SHOW_JAMBUF(RC_COMMENT, s, buf)for (struct jambuf *buf = show_jambuf(s); buf != ((void*)0); jambuf_to_show (buf, s, RC_COMMENT), buf = ((void*)0)) { |
3223 | jam(buf, "event %s is ", pe->ev_name); |
3224 | if (pe->ev_type == EVENT_NULL) { |
3225 | jam(buf, "not timer based"); |
3226 | } else { |
3227 | jam(buf, "schd: %jd (in %jds)", |
3228 | monosecs(pe->ev_time), |
3229 | deltasecs(monotimediff(pe->ev_time, now))); |
3230 | } |
3231 | if (st->st_connection != NULL((void*)0)) { |
3232 | /* fmt_connection(buf, st->st_connection); */ |
3233 | char cib[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)]; |
3234 | jam(buf, " \"%s\"%s", |
3235 | st->st_connection->name, |
3236 | fmt_conn_instance(st->st_connection, cib)); |
3237 | } |
3238 | jam(buf, " #%lu", st->st_serialno); |
3239 | } |
3240 | } |
3241 | } |
3242 | |
3243 | void list_state_events(struct show *s, monotime_t now) |
3244 | { |
3245 | dbg("FOR_EACH_STATE_... in %s", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("FOR_EACH_STATE_... in %s", __func__); } }; |
3246 | struct state *st = NULL((void*)0); |
3247 | FOR_EACH_STATE_OLD2NEW(st)for (struct list_entry *entry_ = (&state_serialno_list_head )->head.newer; entry_ != ((void*)0); entry_ = ((void*)0)) for (st = (typeof(st))entry_->data, entry_ = entry_->newer ; st != ((void*)0); st = (typeof(st))entry_->data, entry_ = entry_->newer) { |
3248 | list_state_event(s, st, st->st_event, now); |
3249 | list_state_event(s, st, st->st_liveness_event, now); |
3250 | list_state_event(s, st, st->st_rel_whack_event, now); |
3251 | list_state_event(s, st, st->st_send_xauth_event, now); |
3252 | list_state_event(s, st, st->st_addr_change_event, now); |
3253 | list_state_event(s, st, st->st_dpd_event, now); |
3254 | } |
3255 | } |
3256 | |
3257 | void set_v1_transition(struct state *st, const struct state_v1_microcode *transition, |
3258 | where_t where) |
3259 | { |
3260 | 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)) { |
3261 | jam(buf, "#%lu.st_v1_transition ", st->st_serialno); |
3262 | jam_v1_transition(buf, st->st_v1_transition); |
3263 | jam(buf, " to "); |
3264 | jam_v1_transition(buf, transition); |
3265 | jam(buf, " "PRI_WHERE"(in %s() at %s:%lu)", pri_where(where)(where).func, (where).basename, (where).line); |
3266 | } |
3267 | st->st_v1_transition = transition; |
3268 | } |
3269 | |
3270 | void set_v2_transition(struct state *st, const struct state_v2_microcode *transition, |
3271 | where_t where) |
3272 | { |
3273 | 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)) { |
3274 | jam(buf, "#%lu.st_v2_transition ", st->st_serialno); |
3275 | jam_v2_transition(buf, st->st_v2_transition); |
3276 | jam(buf, " -> "); |
3277 | jam_v2_transition(buf, transition); |
3278 | jam(buf, " "PRI_WHERE"(in %s() at %s:%lu)", pri_where(where)(where).func, (where).basename, (where).line); |
3279 | } |
3280 | st->st_v2_transition = transition; |
3281 | } |
3282 | |
3283 | static void jam_st(struct jambuf *buf, struct state *st) |
3284 | { |
3285 | if (st == NULL((void*)0)) { |
3286 | jam(buf, "NULL"); |
3287 | } else { |
3288 | jam(buf, "%s #%lu %s", |
3289 | IS_CHILD_SA(st)((st)->st_clonedfrom != 0) ? "CHILD" : "IKE", |
3290 | st->st_serialno, st->st_state->short_name); |
3291 | } |
3292 | } |
3293 | |
3294 | void switch_md_st(struct msg_digest *md, struct state *st, where_t where) |
3295 | { |
3296 | 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)) { |
3297 | jam(buf, "switching IKEv%d MD.ST from ", st->st_ike_version); |
3298 | jam_st(buf, md->st); |
3299 | jam(buf, " to "); |
3300 | jam_st(buf, st); |
3301 | jam(buf, " "PRI_WHERE"(in %s() at %s:%lu)", pri_where(where)(where).func, (where).basename, (where).line); |
3302 | } |
3303 | md->st = st; |
3304 | } |