Bug Summary

File:src/sbin/isakmpd/sa.c
Warning:line 820, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sa.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/isakmpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sbin/isakmpd -I . -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/isakmpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/isakmpd/sa.c
1/* $OpenBSD: sa.c,v 1.124 2017/12/05 20:31:45 jca Exp $ */
2/* $EOM: sa.c,v 1.112 2000/12/12 00:22:52 niklas Exp $ */
3
4/*
5 * Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
6 * Copyright (c) 1999, 2001 Angelos D. Keromytis. All rights reserved.
7 * Copyright (c) 2003, 2004 Håkan Olsson. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * This code was written under funding by Ericsson Radio Systems.
32 */
33
34#include <sys/types.h>
35#include <sys/un.h>
36
37#include <stdlib.h>
38#include <string.h>
39#include <netdb.h>
40
41#include <regex.h>
42#include <keynote.h>
43
44#include "attribute.h"
45#include "conf.h"
46#include "connection.h"
47#include "cookie.h"
48#include "doi.h"
49#include "dpd.h"
50#include "exchange.h"
51#include "isakmp.h"
52#include "log.h"
53#include "message.h"
54#include "monitor.h"
55#include "sa.h"
56#include "timer.h"
57#include "transport.h"
58#include "util.h"
59#include "cert.h"
60#include "policy.h"
61#include "key.h"
62#include "ipsec.h"
63#include "ipsec_num.h"
64
65/* Initial number of bits from the cookies used as hash. */
66#define INITIAL_BUCKET_BITS6 6
67
68/*
69 * Don't try to use more bits than this as a hash.
70 * We only XOR 16 bits so going above that means changing the code below
71 * too.
72 */
73#define MAX_BUCKET_BITS16 16
74
75#if 0
76static void sa_resize(void);
77#endif
78static void sa_soft_expire(void *);
79static void sa_hard_expire(void *);
80
81static int _net_addrcmp(struct sockaddr *, struct sockaddr *);
82
83static LIST_HEAD(sa_list, sa)struct sa_list { struct sa *lh_first; } *sa_tab;
84
85/* Works both as a maximum index and a mask. */
86static int bucket_mask;
87
88void
89sa_init(void)
90{
91 int i;
92
93 bucket_mask = (1 << INITIAL_BUCKET_BITS6) - 1;
94 sa_tab = calloc(bucket_mask + 1, sizeof(struct sa_list));
95 if (!sa_tab)
96 log_fatal("sa_init: malloc (%lu) failed",
97 (bucket_mask + 1) * (unsigned long)sizeof(struct sa_list));
98 for (i = 0; i <= bucket_mask; i++)
99 LIST_INIT(&sa_tab[i])do { ((&sa_tab[i])->lh_first) = ((void *)0); } while (
0)
;
100}
101
102#if 0
103/* XXX We don't yet resize. */
104static void
105sa_resize(void)
106{
107 int new_mask = (bucket_mask + 1) * 2 - 1;
108 int i;
109 struct sa_list *new_tab;
110
111 new_tab = reallocarray(sa_tab, new_mask + 1, sizeof(struct sa_list));
112 if (!new_tab)
113 return;
114 sa_tab = new_tab;
115 for (i = bucket_mask + 1; i <= new_mask; i++)
116 LIST_INIT(&sa_tab[i])do { ((&sa_tab[i])->lh_first) = ((void *)0); } while (
0)
;
117 bucket_mask = new_mask;
118
119 /* XXX Rehash existing entries. */
120}
121#endif
122
123/* Lookup an SA with the help from a user-supplied checking function. */
124struct sa *
125sa_find(int (*check) (struct sa*, void *), void *arg)
126{
127 int i;
128 struct sa *sa;
129
130 for (i = 0; i <= bucket_mask; i++)
131 for (sa = LIST_FIRST(&sa_tab[i])((&sa_tab[i])->lh_first); sa; sa = LIST_NEXT(sa, link)((sa)->link.le_next))
132 if (check(sa, arg)) {
133 LOG_DBG((LOG_SA, 90, "sa_find: return SA %p",log_debug (LOG_SA, 90, "sa_find: return SA %p", sa)
134 sa))log_debug (LOG_SA, 90, "sa_find: return SA %p", sa);
135 return sa;
136 }
137 LOG_DBG((LOG_SA, 90, "sa_find: no SA matched query"))log_debug (LOG_SA, 90, "sa_find: no SA matched query");
138 return 0;
139}
140
141/* Check if SA is an ISAKMP SA with an initiator cookie equal to ICOOKIE. */
142static int
143sa_check_icookie(struct sa *sa, void *icookie)
144{
145 return sa->phase == 1 &&
146 memcmp(sa->cookies, icookie, ISAKMP_HDR_ICOOKIE_LEN8) == 0;
147}
148
149/* Lookup an ISAKMP SA out of just the initiator cookie. */
150struct sa *
151sa_lookup_from_icookie(u_int8_t *cookie)
152{
153 return sa_find(sa_check_icookie, cookie);
154}
155
156struct name_phase_arg {
157 char *name;
158 u_int8_t phase;
159};
160
161/* Check if SA has the name and phase given by V_ARG. */
162static int
163sa_check_name_phase(struct sa *sa, void *v_arg)
164{
165 struct name_phase_arg *arg = v_arg;
166
167 return sa->name && strcasecmp(sa->name, arg->name) == 0 &&
168 sa->phase == arg->phase && !(sa->flags & SA_FLAG_REPLACED0x08);
169}
170
171/* Lookup an SA by name, case-independent, and phase. */
172struct sa *
173sa_lookup_by_name(char *name, int phase)
174{
175 struct name_phase_arg arg;
176
177 arg.name = name;
178 arg.phase = phase;
179 return sa_find(sa_check_name_phase, &arg);
180}
181
182struct addr_arg {
183 struct sockaddr *addr;
184 socklen_t len;
185 int phase;
186 int flags;
187};
188
189/*
190 * This function has been removed from libc and put here as this
191 * file is the only user for it.
192 */
193static int
194_net_addrcmp(struct sockaddr *sa1, struct sockaddr *sa2)
195{
196
197 if (sa1->sa_len != sa2->sa_len)
198 return (sa1->sa_len < sa2->sa_len) ? -1 : 1;
199 if (sa1->sa_family != sa2->sa_family)
200 return (sa1->sa_family < sa2->sa_family) ? -1 : 1;
201
202 switch(sa1->sa_family) {
203 case AF_INET2:
204 return (memcmp(&((struct sockaddr_in *)sa1)->sin_addr,
205 &((struct sockaddr_in *)sa2)->sin_addr,
206 sizeof(struct in_addr)));
207 case AF_INET624:
208 if (((struct sockaddr_in6 *)sa1)->sin6_scope_id !=
209 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
210 return (((struct sockaddr_in6 *)sa1)->sin6_scope_id <
211 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
212 ? -1 : 1;
213 return memcmp(&((struct sockaddr_in6 *)sa1)->sin6_addr,
214 &((struct sockaddr_in6 *)sa2)->sin6_addr,
215 sizeof(struct in6_addr));
216 case AF_LOCAL1:
217 return (strcmp(((struct sockaddr_un *)sa1)->sun_path,
218 ((struct sockaddr_un *)sa2)->sun_path));
219 default:
220 return -1;
221 }
222}
223
224/*
225 * Check if SA is ready and has a peer with an address equal the one given
226 * by V_ADDR. Furthermore if we are searching for a specific phase, check
227 * that too.
228 */
229static int
230sa_check_peer(struct sa *sa, void *v_addr)
231{
232 struct addr_arg *addr = v_addr;
233 struct sockaddr *dst;
234
235 if (!sa->transport || (sa->flags & SA_FLAG_READY0x01) == 0 ||
236 (addr->phase && addr->phase != sa->phase))
237 return 0;
238
239 sa->transport->vtbl->get_dst(sa->transport, &dst);
240 if (_net_addrcmp(dst, addr->addr) != 0)
241 return 0;
242
243 /* same family, length and address, check port if inet/inet6 */
244 switch (dst->sa_family) {
245 case AF_INET2:
246 return ((struct sockaddr_in *)dst)->sin_port == ((struct sockaddr_in *)addr->addr)->sin_port;
247 case AF_INET624:
248 return ((struct sockaddr_in6 *)dst)->sin6_port == ((struct sockaddr_in6 *)addr->addr)->sin6_port;
249 }
250
251 return 1;
252}
253
254struct dst_isakmpspi_arg {
255 struct sockaddr *dst;
256 u_int8_t *spi; /* must be ISAKMP_SPI_SIZE octets */
257};
258
259/*
260 * Check if SA matches what we are asking for through V_ARG. It has to
261 * be a finished phase 1 (ISAKMP) SA.
262 */
263static int
264isakmp_sa_check(struct sa *sa, void *v_arg)
265{
266 struct dst_isakmpspi_arg *arg = v_arg;
267 struct sockaddr *dst, *src;
268
269 if (sa->phase != 1 || !(sa->flags & SA_FLAG_READY0x01))
270 return 0;
271
272 /* verify address is either src or dst for this sa */
273 sa->transport->vtbl->get_dst(sa->transport, &dst);
274 sa->transport->vtbl->get_src(sa->transport, &src);
275 if (memcmp(src, arg->dst, SA_LEN(src)((src)->sa_len)) &&
276 memcmp(dst, arg->dst, SA_LEN(dst)((dst)->sa_len)))
277 return 0;
278
279 /* match icookie+rcookie against spi */
280 if (memcmp(sa->cookies, arg->spi, ISAKMP_HDR_COOKIES_LEN(8 + 8)) == 0)
281 return 1;
282
283 return 0;
284}
285
286/*
287 * Find an ISAKMP SA with a "name" of DST & SPI.
288 */
289struct sa *
290sa_lookup_isakmp_sa(struct sockaddr *dst, u_int8_t *spi)
291{
292 struct dst_isakmpspi_arg arg;
293
294 arg.dst = dst;
295 arg.spi = spi;
296
297 return sa_find(isakmp_sa_check, &arg);
298}
299
300/* Lookup a ready SA by the peer's address. */
301struct sa *
302sa_lookup_by_peer(struct sockaddr *dst, socklen_t dstlen, int phase)
303{
304 struct addr_arg arg;
305
306 arg.addr = dst;
307 arg.len = dstlen;
308 arg.phase = phase;
309
310 return sa_find(sa_check_peer, &arg);
311}
312
313/* Lookup a ready ISAKMP SA given its peer address. */
314struct sa *
315sa_isakmp_lookup_by_peer(struct sockaddr *dst, socklen_t dstlen)
316{
317 struct addr_arg arg;
318
319 arg.addr = dst;
320 arg.len = dstlen;
321 arg.phase = 1;
322
323 return sa_find(sa_check_peer, &arg);
324}
325
326int
327sa_enter(struct sa *sa)
328{
329 u_int16_t bucket = 0;
330 int i;
331 u_int8_t *cp;
332
333 /* XXX We might resize if we are crossing a certain threshold */
334
335 for (i = 0; i < ISAKMP_HDR_COOKIES_LEN(8 + 8); i += 2) {
336 cp = sa->cookies + i;
337 /* Doing it this way avoids alignment problems. */
338 bucket ^= cp[0] | cp[1] << 8;
339 }
340 for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN4; i += 2) {
341 cp = sa->message_id + i;
342 /* Doing it this way avoids alignment problems. */
343 bucket ^= cp[0] | cp[1] << 8;
344 }
345 bucket &= bucket_mask;
346 LIST_INSERT_HEAD(&sa_tab[bucket], sa, link)do { if (((sa)->link.le_next = (&sa_tab[bucket])->lh_first
) != ((void *)0)) (&sa_tab[bucket])->lh_first->link
.le_prev = &(sa)->link.le_next; (&sa_tab[bucket])->
lh_first = (sa); (sa)->link.le_prev = &(&sa_tab[bucket
])->lh_first; } while (0)
;
347 sa_reference(sa);
348 LOG_DBG((LOG_SA, 70, "sa_enter: SA %p added to SA list", sa))log_debug (LOG_SA, 70, "sa_enter: SA %p added to SA list", sa
)
;
349 return 1;
350}
351
352/*
353 * Lookup the SA given by the header fields MSG. PHASE2 is false when
354 * looking for phase 1 SAa and true otherwise.
355 */
356struct sa *
357sa_lookup_by_header(u_int8_t *msg, int phase2)
358{
359 return sa_lookup(msg + ISAKMP_HDR_COOKIES_OFF0,
360 phase2 ? msg + ISAKMP_HDR_MESSAGE_ID_OFF20 : 0);
361}
362
363/*
364 * Lookup the SA given by the COOKIES and possibly the MESSAGE_ID unless
365 * a null pointer, meaning we are looking for phase 1 SAs.
366 */
367struct sa *
368sa_lookup(u_int8_t *cookies, u_int8_t *message_id)
369{
370 u_int16_t bucket = 0;
371 int i;
372 struct sa *sa;
373 u_int8_t *cp;
374
375 /*
376 * We use the cookies to get bits to use as an index into sa_tab, as at
377 * least one (our cookie) is a good hash, xoring all the bits, 16 at a
378 * time, and then masking, should do. Doing it this way means we can
379 * validate cookies very fast thus delimiting the effects of "Denial of
380 * service"-attacks using packet flooding.
381 */
382 for (i = 0; i < ISAKMP_HDR_COOKIES_LEN(8 + 8); i += 2) {
383 cp = cookies + i;
384 /* Doing it this way avoids alignment problems. */
385 bucket ^= cp[0] | cp[1] << 8;
386 }
387 if (message_id)
388 for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN4; i += 2) {
389 cp = message_id + i;
390 /* Doing it this way avoids alignment problems. */
391 bucket ^= cp[0] | cp[1] << 8;
392 }
393 bucket &= bucket_mask;
394 for (sa = LIST_FIRST(&sa_tab[bucket])((&sa_tab[bucket])->lh_first);
395 sa && (memcmp(cookies, sa->cookies, ISAKMP_HDR_COOKIES_LEN(8 + 8)) != 0 ||
396 (message_id && memcmp(message_id, sa->message_id,
397 ISAKMP_HDR_MESSAGE_ID_LEN4) != 0) ||
398 (!message_id && !zero_test(sa->message_id, ISAKMP_HDR_MESSAGE_ID_LEN4)));
399 sa = LIST_NEXT(sa, link)((sa)->link.le_next))
400 ;
401
402 return sa;
403}
404
405/* Create an SA. */
406int
407sa_create(struct exchange *exchange, struct transport *t)
408{
409 struct sa *sa;
410
411 /*
412 * We want the SA zeroed for sa_free to be able to find out what fields
413 * have been filled-in.
414 */
415 sa = calloc(1, sizeof *sa);
416 if (!sa) {
417 log_error("sa_create: calloc (1, %lu) failed",
418 (unsigned long)sizeof *sa);
419 return -1;
420 }
421 sa->transport = t;
422 if (t)
423 transport_reference(t);
424 sa->phase = exchange->phase;
425 memcpy(sa->cookies, exchange->cookies, ISAKMP_HDR_COOKIES_LEN(8 + 8));
426 memcpy(sa->message_id, exchange->message_id,
427 ISAKMP_HDR_MESSAGE_ID_LEN4);
428 sa->doi = exchange->doi;
429 sa->policy_id = -1;
430
431 if (sa->doi->sa_size) {
432 /*
433 * Allocate the DOI-specific structure and initialize it to
434 * zeroes.
435 */
436 sa->data = calloc(1, sa->doi->sa_size);
437 if (!sa->data) {
438 log_error("sa_create: calloc (1, %lu) failed",
439 (unsigned long)sa->doi->sa_size);
440 free(sa);
441 return -1;
442 }
443 }
444 TAILQ_INIT(&sa->protos)do { (&sa->protos)->tqh_first = ((void *)0); (&
sa->protos)->tqh_last = &(&sa->protos)->tqh_first
; } while (0)
;
445
446 sa_enter(sa);
447 TAILQ_INSERT_TAIL(&exchange->sa_list, sa, next)do { (sa)->next.tqe_next = ((void *)0); (sa)->next.tqe_prev
= (&exchange->sa_list)->tqh_last; *(&exchange->
sa_list)->tqh_last = (sa); (&exchange->sa_list)->
tqh_last = &(sa)->next.tqe_next; } while (0)
;
448 sa_reference(sa);
449
450 LOG_DBG((LOG_SA, 60,log_debug (LOG_SA, 60, "sa_create: sa %p phase %d added to exchange %p (%s)"
, sa, sa->phase, exchange, exchange->name ? exchange->
name : "<unnamed>")
451 "sa_create: sa %p phase %d added to exchange %p (%s)", sa,log_debug (LOG_SA, 60, "sa_create: sa %p phase %d added to exchange %p (%s)"
, sa, sa->phase, exchange, exchange->name ? exchange->
name : "<unnamed>")
452 sa->phase, exchange,log_debug (LOG_SA, 60, "sa_create: sa %p phase %d added to exchange %p (%s)"
, sa, sa->phase, exchange, exchange->name ? exchange->
name : "<unnamed>")
453 exchange->name ? exchange->name : "<unnamed>"))log_debug (LOG_SA, 60, "sa_create: sa %p phase %d added to exchange %p (%s)"
, sa, sa->phase, exchange, exchange->name ? exchange->
name : "<unnamed>")
;
454 return 0;
455}
456
457/*
458 * Dump the internal state of SA to the report channel, with HEADER
459 * prepended to each line.
460 */
461void
462sa_dump(int cls, int level, char *header, struct sa *sa)
463{
464 struct proto *proto;
465 char spi_header[80];
466 int i;
467
468 LOG_DBG((cls, level, "%s: %p %s phase %d doi %d flags 0x%x", header,log_debug (cls, level, "%s: %p %s phase %d doi %d flags 0x%x"
, header, sa, sa->name ? sa->name : "<unnamed>", sa
->phase, sa->doi->id, sa->flags)
469 sa, sa->name ? sa->name : "<unnamed>", sa->phase, sa->doi->id,log_debug (cls, level, "%s: %p %s phase %d doi %d flags 0x%x"
, header, sa, sa->name ? sa->name : "<unnamed>", sa
->phase, sa->doi->id, sa->flags)
470 sa->flags))log_debug (cls, level, "%s: %p %s phase %d doi %d flags 0x%x"
, header, sa, sa->name ? sa->name : "<unnamed>", sa
->phase, sa->doi->id, sa->flags)
;
471 LOG_DBG((cls, level, "%s: icookie %08x%08x rcookie %08x%08x", header,log_debug (cls, level, "%s: icookie %08x%08x rcookie %08x%08x"
, header, decode_32(sa->cookies), decode_32(sa->cookies
+ 4), decode_32(sa->cookies + 8), decode_32(sa->cookies
+ 12))
472 decode_32(sa->cookies), decode_32(sa->cookies + 4),log_debug (cls, level, "%s: icookie %08x%08x rcookie %08x%08x"
, header, decode_32(sa->cookies), decode_32(sa->cookies
+ 4), decode_32(sa->cookies + 8), decode_32(sa->cookies
+ 12))
473 decode_32(sa->cookies + 8), decode_32(sa->cookies + 12)))log_debug (cls, level, "%s: icookie %08x%08x rcookie %08x%08x"
, header, decode_32(sa->cookies), decode_32(sa->cookies
+ 4), decode_32(sa->cookies + 8), decode_32(sa->cookies
+ 12))
;
474 LOG_DBG((cls, level, "%s: msgid %08x refcnt %d", header,log_debug (cls, level, "%s: msgid %08x refcnt %d", header, decode_32
(sa->message_id), sa->refcnt)
475 decode_32(sa->message_id), sa->refcnt))log_debug (cls, level, "%s: msgid %08x refcnt %d", header, decode_32
(sa->message_id), sa->refcnt)
;
476 LOG_DBG((cls, level, "%s: life secs %llu kb %llu", header, sa->seconds,log_debug (cls, level, "%s: life secs %llu kb %llu", header, sa
->seconds, sa->kilobytes)
477 sa->kilobytes))log_debug (cls, level, "%s: life secs %llu kb %llu", header, sa
->seconds, sa->kilobytes)
;
478 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto;
479 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next)) {
480 LOG_DBG((cls, level, "%s: suite %d proto %d", header,log_debug (cls, level, "%s: suite %d proto %d", header, proto
->no, proto->proto)
481 proto->no, proto->proto))log_debug (cls, level, "%s: suite %d proto %d", header, proto
->no, proto->proto)
;
482 LOG_DBG((cls, level,log_debug (cls, level, "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p"
, header, proto->spi_sz[0], proto->spi[0], proto->spi_sz
[1], proto->spi[1])
483 "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p",log_debug (cls, level, "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p"
, header, proto->spi_sz[0], proto->spi[0], proto->spi_sz
[1], proto->spi[1])
484 header, proto->spi_sz[0], proto->spi[0], proto->spi_sz[1],log_debug (cls, level, "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p"
, header, proto->spi_sz[0], proto->spi[0], proto->spi_sz
[1], proto->spi[1])
485 proto->spi[1]))log_debug (cls, level, "%s: spi_sz[0] %d spi[0] %p spi_sz[1] %d spi[1] %p"
, header, proto->spi_sz[0], proto->spi[0], proto->spi_sz
[1], proto->spi[1])
;
486 LOG_DBG((cls, level, "%s: %s, %s", header,log_debug (cls, level, "%s: %s, %s", header, !sa->doi ? "<nodoi>"
: sa->doi->decode_ids("initiator id: %s, responder id: %s"
, sa->id_i, sa->id_i_len, sa->id_r, sa->id_r_len,
0), !sa->transport ? "<no transport>" : sa->transport
->vtbl->decode_ids(sa->transport))
487 !sa->doi ? "<nodoi>" :log_debug (cls, level, "%s: %s, %s", header, !sa->doi ? "<nodoi>"
: sa->doi->decode_ids("initiator id: %s, responder id: %s"
, sa->id_i, sa->id_i_len, sa->id_r, sa->id_r_len,
0), !sa->transport ? "<no transport>" : sa->transport
->vtbl->decode_ids(sa->transport))
488 sa->doi->decode_ids("initiator id: %s, responder id: %s",log_debug (cls, level, "%s: %s, %s", header, !sa->doi ? "<nodoi>"
: sa->doi->decode_ids("initiator id: %s, responder id: %s"
, sa->id_i, sa->id_i_len, sa->id_r, sa->id_r_len,
0), !sa->transport ? "<no transport>" : sa->transport
->vtbl->decode_ids(sa->transport))
489 sa->id_i, sa->id_i_len,log_debug (cls, level, "%s: %s, %s", header, !sa->doi ? "<nodoi>"
: sa->doi->decode_ids("initiator id: %s, responder id: %s"
, sa->id_i, sa->id_i_len, sa->id_r, sa->id_r_len,
0), !sa->transport ? "<no transport>" : sa->transport
->vtbl->decode_ids(sa->transport))
490 sa->id_r, sa->id_r_len, 0),log_debug (cls, level, "%s: %s, %s", header, !sa->doi ? "<nodoi>"
: sa->doi->decode_ids("initiator id: %s, responder id: %s"
, sa->id_i, sa->id_i_len, sa->id_r, sa->id_r_len,
0), !sa->transport ? "<no transport>" : sa->transport
->vtbl->decode_ids(sa->transport))
491 !sa->transport ? "<no transport>" :log_debug (cls, level, "%s: %s, %s", header, !sa->doi ? "<nodoi>"
: sa->doi->decode_ids("initiator id: %s, responder id: %s"
, sa->id_i, sa->id_i_len, sa->id_r, sa->id_r_len,
0), !sa->transport ? "<no transport>" : sa->transport
->vtbl->decode_ids(sa->transport))
492 sa->transport->vtbl->decode_ids(sa->transport)))log_debug (cls, level, "%s: %s, %s", header, !sa->doi ? "<nodoi>"
: sa->doi->decode_ids("initiator id: %s, responder id: %s"
, sa->id_i, sa->id_i_len, sa->id_r, sa->id_r_len,
0), !sa->transport ? "<no transport>" : sa->transport
->vtbl->decode_ids(sa->transport))
;
493 for (i = 0; i < 2; i++)
494 if (proto->spi[i]) {
495 snprintf(spi_header, sizeof spi_header,
496 "%s: spi[%d]", header, i);
497 LOG_DBG_BUF((cls, level, spi_header,log_debug_buf (cls, level, spi_header, proto->spi[i], proto
->spi_sz[i])
498 proto->spi[i], proto->spi_sz[i]))log_debug_buf (cls, level, spi_header, proto->spi[i], proto
->spi_sz[i])
;
499 }
500 }
501}
502
503/*
504 * Display the SA's two SPI values.
505 */
506static void
507report_spi(FILE *fd, const u_int8_t *buf, size_t sz, int spi)
508{
509#define SBUFSZ(2 * 32 + 9) (2 * 32 + 9)
510 char s[SBUFSZ(2 * 32 + 9)];
511 size_t i, j;
512
513 for (i = j = 0; i < sz;) {
514 snprintf(s + j, sizeof s - j, "%02x", buf[i++]);
515 j += strlen(s + j);
516 if (i % 4 == 0) {
517 if (i % 32 == 0) {
518 s[j] = '\0';
519 fprintf(fd, "%s", s);
520 j = 0;
521 } else
522 s[j++] = ' ';
523 }
524 }
525
526 if (j) {
527 s[j] = '\0';
528 fprintf(fd, "SPI %d: %s\n", spi, s);
529 }
530}
531
532/*
533 * Display the transform names to file.
534 * Structure is taken from pf_key_v2.c, pf_key_v2_set_spi.
535 * Transform names are taken from /usr/src/sys/crypto/xform.c.
536 */
537static void
538report_proto(FILE *fd, struct proto *proto)
539{
540 struct ipsec_proto *iproto;
541 int keylen, hashlen;
542
543 switch (proto->proto) {
544 case IPSEC_PROTO_IPSEC_ESP3:
545 keylen = ipsec_esp_enckeylength(proto);
546 hashlen = ipsec_esp_authkeylength(proto);
547 fprintf(fd, "Transform: IPsec ESP\n");
548 fprintf(fd, "Encryption key length: %d\n", keylen);
549 fprintf(fd, "Authentication key length: %d\n", hashlen);
550
551 fprintf(fd, "Encryption algorithm: ");
552 switch (proto->id) {
553 case IPSEC_ESP_3DES3:
554 fprintf(fd, "3DES\n");
555 break;
556
557 case IPSEC_ESP_AES12:
558 fprintf(fd, "AES (CBC)\n");
559 break;
560
561 case IPSEC_ESP_AES_CTR13:
562 fprintf(fd, "AES (CTR)\n");
563 break;
564
565 case IPSEC_ESP_AES_GCM_1620:
566 fprintf(fd, "AES (GCM)\n");
567 break;
568
569 case IPSEC_ESP_AES_GMAC23:
570 fprintf(fd, "AES (GMAC)\n");
571 break;
572
573 case IPSEC_ESP_CAST6:
574 fprintf(fd, "Cast-128\n");
575 break;
576
577 case IPSEC_ESP_BLOWFISH7:
578 fprintf(fd, "Blowfish\n");
579 break;
580
581 default:
582 fprintf(fd, "unknown (%d)\n", proto->id);
583 }
584
585 fprintf(fd, "Authentication algorithm: ");
586
587 if (!proto->data) {
588 fprintf(fd, "none\n");
589 break;
590 }
591 iproto = proto->data;
592
593 switch (iproto->auth) {
594 case IPSEC_AUTH_HMAC_MD51:
595 fprintf(fd, "HMAC-MD5\n");
596 break;
597
598 case IPSEC_AUTH_HMAC_SHA2:
599 fprintf(fd, "HMAC-SHA1\n");
600 break;
601
602 case IPSEC_AUTH_HMAC_RIPEMD8:
603 fprintf(fd, "HMAC-RIPEMD-160\n");
604 break;
605
606 case IPSEC_AUTH_HMAC_SHA2_2565:
607 fprintf(fd, "HMAC-SHA2-256\n");
608 break;
609
610 case IPSEC_AUTH_HMAC_SHA2_3846:
611 fprintf(fd, "HMAC-SHA2-384\n");
612 break;
613
614 case IPSEC_AUTH_HMAC_SHA2_5127:
615 fprintf(fd, "HMAC-SHA2-512\n");
616 break;
617
618 case IPSEC_AUTH_DES_MAC3:
619 case IPSEC_AUTH_KPDK4:
620 /* XXX We should be supporting KPDK */
621 fprintf(fd, "unknown (%d)", iproto->auth);
622 break;
623
624 default:
625 fprintf(fd, "none\n");
626 }
627 break;
628
629 case IPSEC_PROTO_IPSEC_AH2:
630 hashlen = ipsec_ah_keylength(proto);
631 fprintf(fd, "Transform: IPsec AH\n");
632 fprintf(fd, "Encryption not used.\n");
633 fprintf(fd, "Authentication key length: %d\n", hashlen);
634
635 fprintf(fd, "Authentication algorithm: ");
636 switch (proto->id) {
637 case IPSEC_AH_MD52:
638 fprintf(fd, "HMAC-MD5\n");
639 break;
640
641 case IPSEC_AH_SHA3:
642 fprintf(fd, "HMAC-SHA1\n");
643 break;
644
645 case IPSEC_AH_RIPEMD8:
646 fprintf(fd, "HMAC-RIPEMD-160\n");
647 break;
648
649 case IPSEC_AH_SHA2_2565:
650 fprintf(fd, "HMAC-SHA2-256\n");
651 break;
652
653 case IPSEC_AH_SHA2_3846:
654 fprintf(fd, "HMAC-SHA2-384\n");
655 break;
656
657 case IPSEC_AH_SHA2_5127:
658 fprintf(fd, "HMAC-SHA2-512\n");
659 break;
660
661 default:
662 fprintf(fd, "unknown (%d)", proto->id);
663 }
664 break;
665
666 default:
667 fprintf(fd, "report_proto: invalid proto %d\n", proto->proto);
668 }
669}
670
671/*
672 * Display SA lifetimes.
673 */
674static void
675report_lifetimes(FILE *fd, struct sa *sa)
676{
677 long timeout;
678
679 if (sa->seconds)
680 fprintf(fd, "Lifetime: %llu seconds\n", sa->seconds);
681
682 if (sa->soft_death) {
683 timeout = get_timeout(&sa->soft_death->expiration);
684 if (timeout < 0)
685 fprintf(fd, "<no soft timeout>\n");
686 else
687 fprintf(fd, "Soft timeout in %ld seconds\n", timeout);
688 }
689
690 if (sa->death) {
691 timeout = get_timeout(&sa->death->expiration);
692 if (timeout < 0)
693 fprintf(fd, "No hard timeout>\n");
694 else
695 fprintf(fd, "Hard timeout in %ld seconds\n", timeout);
696 }
697
698 if (sa->kilobytes)
699 fprintf(fd, "Lifetime: %llu kilobytes\n", sa->kilobytes);
700}
701
702/*
703 * Print phase 1 specific information.
704 */
705static void
706report_phase1(FILE *fd, struct sa *sa)
707{
708 /* Cookies. */
709 fprintf(fd, "icookie %08x%08x rcookie %08x%08x\n",
710 decode_32(sa->cookies), decode_32(sa->cookies + 4),
711 decode_32(sa->cookies + 8), decode_32(sa->cookies + 12));
712}
713
714/*
715 * Print phase 2 specific information.
716 */
717static void
718report_phase2(FILE *fd, struct sa *sa)
719{
720 struct proto *proto;
721 int i;
722
723 /* Transform information. */
724 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto;
725 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next)) {
726
727 /* SPI values. */
728 for (i = 0; i < 2; i++)
729 if (proto->spi[i])
730 report_spi(fd, proto->spi[i],
731 proto->spi_sz[i], i);
732 else
733 fprintf(fd, "SPI %d not defined.\n", i);
734
735 /* Proto values. */
736 report_proto(fd, proto);
737 }
738}
739
740/* Report all the SAs to the report channel. */
741void
742sa_report(void)
743{
744 struct sa *sa;
745 int i;
746
747 for (i = 0; i <= bucket_mask; i++)
748 for (sa = LIST_FIRST(&sa_tab[i])((&sa_tab[i])->lh_first); sa; sa = LIST_NEXT(sa, link)((sa)->link.le_next))
749 sa_dump(LOG_REPORT-2, 0, "sa_report", sa);
750}
751
752/*
753 * Print an SA's connection details to file SA_FILE.
754 */
755static void
756sa_dump_all(FILE *fd, struct sa *sa)
757{
758 /* SA name and phase. */
759 fprintf(fd, "SA name: %s", sa->name ? sa->name : "<unnamed>");
760 fprintf(fd, " (Phase %d%s)\n", sa->phase, sa->phase == 1 ?
761 (sa->initiator ? "/Initiator" : "/Responder") : "");
762
763 /* Source and destination IPs. */
764 fprintf(fd, "%s", sa->transport == NULL((void *)0) ? "<no transport>" :
765 sa->transport->vtbl->decode_ids(sa->transport));
766 fprintf(fd, "\n");
767
768 /* Lifetimes */
769 report_lifetimes(fd, sa);
770
771 fprintf(fd, "Flags 0x%08x\n", sa->flags);
772
773 if (sa->phase == 1)
774 report_phase1(fd, sa);
775 else if (sa->phase == 2)
776 report_phase2(fd, sa);
777 else {
778 /* Should not happen, but... */
779 fprintf(fd, "<unknown phase>\n");
780 }
781
782 /* SA separator. */
783 fprintf(fd, "\n");
784}
785
786/* Report info of all SAs to file 'fd'. */
787void
788sa_report_all(FILE *fd)
789{
790 struct sa *sa;
791 int i;
792
793 for (i = 0; i <= bucket_mask; i++)
794 for (sa = LIST_FIRST(&sa_tab[i])((&sa_tab[i])->lh_first); sa; sa = LIST_NEXT(sa, link)((sa)->link.le_next))
795 sa_dump_all(fd, sa);
796}
797
798/* Free the protocol structure pointed to by PROTO. */
799void
800proto_free(struct proto *proto)
801{
802 struct proto_attr *pa;
803 struct sa *sa = proto->sa;
804 int i;
805
806 for (i = 0; i < 2; i++)
1
Loop condition is true. Entering loop body
4
Loop condition is true. Entering loop body
7
Loop condition is false. Execution continues on line 812
807 if (proto->spi[i]) {
2
Assuming the condition is false
3
Taking false branch
5
Assuming the condition is false
6
Taking false branch
808 if (sa->doi->delete_spi)
809 sa->doi->delete_spi(sa, proto, i);
810 free(proto->spi[i]);
811 }
812 TAILQ_REMOVE(&sa->protos, proto, link)do { if (((proto)->link.tqe_next) != ((void *)0)) (proto)->
link.tqe_next->link.tqe_prev = (proto)->link.tqe_prev; else
(&sa->protos)->tqh_last = (proto)->link.tqe_prev
; *(proto)->link.tqe_prev = (proto)->link.tqe_next; ; ;
} while (0)
;
8
Assuming field 'tqe_next' is equal to null
9
Taking false branch
10
Loop condition is false. Exiting loop
813 if (proto->data) {
11
Assuming field 'data' is null
12
Taking false branch
814 if (sa->doi && sa->doi->free_proto_data)
815 sa->doi->free_proto_data(proto->data);
816 free(proto->data);
817 }
818 if (proto->xf_cnt)
13
Assuming field 'xf_cnt' is not equal to 0
14
Taking true branch
819 while ((pa = TAILQ_FIRST(&proto->xfs)((&proto->xfs)->tqh_first)) != NULL((void *)0)) {
15
Assuming the condition is true
16
Loop condition is true. Entering loop body
21
Loop condition is true. Entering loop body
820 free(pa->attrs);
22
Use of memory after it is freed
821 TAILQ_REMOVE(&proto->xfs, pa, next)do { if (((pa)->next.tqe_next) != ((void *)0)) (pa)->next
.tqe_next->next.tqe_prev = (pa)->next.tqe_prev; else (&
proto->xfs)->tqh_last = (pa)->next.tqe_prev; *(pa)->
next.tqe_prev = (pa)->next.tqe_next; ; ; } while (0)
;
17
Assuming field 'tqe_next' is equal to null
18
Taking false branch
19
Loop condition is false. Exiting loop
822 free(pa);
20
Memory is released
823 }
824
825 LOG_DBG((LOG_SA, 90, "proto_free: freeing %p", proto))log_debug (LOG_SA, 90, "proto_free: freeing %p", proto);
826 free(proto);
827}
828
829/* Release all resources this SA is using. */
830void
831sa_free(struct sa *sa)
832{
833 if (sa->death) {
834 timer_remove_event(sa->death);
835 sa->death = 0;
836 sa->refcnt--;
837 }
838 if (sa->soft_death) {
839 timer_remove_event(sa->soft_death);
840 sa->soft_death = 0;
841 sa->refcnt--;
842 }
843 if (sa->dpd_event) {
844 timer_remove_event(sa->dpd_event);
845 sa->dpd_event = 0;
846 }
847 sa_remove(sa);
848}
849
850/* Remove the SA from the hash table of live SAs. */
851void
852sa_remove(struct sa *sa)
853{
854 LIST_REMOVE(sa, link)do { if ((sa)->link.le_next != ((void *)0)) (sa)->link.
le_next->link.le_prev = (sa)->link.le_prev; *(sa)->link
.le_prev = (sa)->link.le_next; ; ; } while (0)
;
855 LOG_DBG((LOG_SA, 70, "sa_remove: SA %p removed from SA list", sa))log_debug (LOG_SA, 70, "sa_remove: SA %p removed from SA list"
, sa)
;
856 sa_release(sa);
857}
858
859/* Raise the reference count of SA. */
860void
861sa_reference(struct sa *sa)
862{
863 sa->refcnt++;
864 LOG_DBG((LOG_SA, 80, "sa_reference: SA %p now has %d references",log_debug (LOG_SA, 80, "sa_reference: SA %p now has %d references"
, sa, sa->refcnt)
865 sa, sa->refcnt))log_debug (LOG_SA, 80, "sa_reference: SA %p now has %d references"
, sa, sa->refcnt)
;
866}
867
868/* Release a reference to SA. */
869void
870sa_release(struct sa *sa)
871{
872 struct cert_handler *handler;
873 struct proto *proto;
874
875 LOG_DBG((LOG_SA, 80, "sa_release: SA %p had %d references",log_debug (LOG_SA, 80, "sa_release: SA %p had %d references",
sa, sa->refcnt)
876 sa, sa->refcnt))log_debug (LOG_SA, 80, "sa_release: SA %p had %d references",
sa, sa->refcnt)
;
877
878 if (--sa->refcnt)
879 return;
880
881 LOG_DBG((LOG_SA, 60, "sa_release: freeing SA %p", sa))log_debug (LOG_SA, 60, "sa_release: freeing SA %p", sa);
882
883 while ((proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first)) != 0)
884 proto_free(proto);
885 if (sa->data) {
886 if (sa->doi && sa->doi->free_sa_data)
887 sa->doi->free_sa_data(sa->data);
888 free(sa->data);
889 }
890 free(sa->id_i);
891 free(sa->id_r);
892 if (sa->recv_cert) {
893 handler = cert_get(sa->recv_certtype);
894 if (handler)
895 handler->cert_free(sa->recv_cert);
896 }
897 if (sa->sent_cert) {
898 handler = cert_get(sa->sent_certtype);
899 if (handler)
900 handler->cert_free(sa->sent_cert);
901 }
902 if (sa->recv_key)
903 key_free(sa->recv_keytype, ISAKMP_KEYTYPE_PUBLIC0,
904 sa->recv_key);
905 free(sa->keynote_key); /* This is just a string */
906 if (sa->policy_id != -1)
907 kn_close(sa->policy_id);
908 free(sa->name);
909 free(sa->keystate);
910 if (sa->nat_t_keepalive)
911 timer_remove_event(sa->nat_t_keepalive);
912 if (sa->dpd_event)
913 timer_remove_event(sa->dpd_event);
914 if (sa->transport)
915 transport_release(sa->transport);
916 free(sa->tag);
917 free(sa);
918}
919
920/*
921 * Rehash the ISAKMP SA this MSG is negotiating with the responder cookie
922 * filled in.
923 */
924void
925sa_isakmp_upgrade(struct message *msg)
926{
927 struct sa *sa = TAILQ_FIRST(&msg->exchange->sa_list)((&msg->exchange->sa_list)->tqh_first);
928
929 sa_remove(sa);
930 GET_ISAKMP_HDR_RCOOKIE(msg->iov[0].iov_base,field_get_raw (isakmp_hdr_fld + 1, msg->iov[0].iov_base, sa
->cookies + 8)
931 sa->cookies + ISAKMP_HDR_ICOOKIE_LEN)field_get_raw (isakmp_hdr_fld + 1, msg->iov[0].iov_base, sa
->cookies + 8)
;
932
933 /*
934 * We don't install a transport in the initiator case as we don't know
935 * what local address will be chosen. Do it now instead.
936 */
937 sa->transport = msg->transport;
938 transport_reference(sa->transport);
939 sa_enter(sa);
940}
941
942#define ATTRS_SIZE(17 + 1) (IKE_ATTR_BLOCK_SIZE17 + 1) /* XXX Should be dynamic. */
943
944struct attr_validation_state {
945 u_int8_t *attrp[ATTRS_SIZE(17 + 1)];
946 u_int8_t checked[ATTRS_SIZE(17 + 1)];
947 u_int16_t len[ATTRS_SIZE(17 + 1)];
948 int phase; /* IKE (1) or IPSEC (2) attrs? */
949 int mode; /* 0 = 'load', 1 = check */
950};
951
952/* Validate an attribute. Return 0 on match. */
953static int
954sa_validate_xf_attrs(u_int16_t type, u_int8_t *value, u_int16_t len,
955 void *arg)
956{
957 int val0, val1;
958
959 struct attr_validation_state *avs =
960 (struct attr_validation_state *)arg;
961
962 LOG_DBG((LOG_SA, 95, "sa_validate_xf_attrs: phase %d mode %d type %d "log_debug (LOG_SA, 95, "sa_validate_xf_attrs: phase %d mode %d type %d "
"len %d", avs->phase, avs->mode, type, len)
963 "len %d", avs->phase, avs->mode, type, len))log_debug (LOG_SA, 95, "sa_validate_xf_attrs: phase %d mode %d type %d "
"len %d", avs->phase, avs->mode, type, len)
;
964
965 /* Make sure the phase and type are valid. */
966 if (avs->phase == 1) {
967 if (type < IKE_ATTR_ENCRYPTION_ALGORITHM1 ||
968 type > IKE_ATTR_BLOCK_SIZE17)
969 return 1;
970 } else if (avs->phase == 2) {
971 if (type < IPSEC_ATTR_SA_LIFE_TYPE1 ||
972 type > IPSEC_ATTR_ECN_TUNNEL10)
973 return 1;
974 } else
975 return 1;
976
977 if (avs->mode == 0) { /* Load attrs. */
978 avs->attrp[type] = value;
979 avs->len[type] = len;
980 return 0;
981 }
982 /* Checking for a missing attribute is an immediate failure. */
983 if (!avs->attrp[type])
984 return 1;
985
986 /* Match the loaded attribute against this one, mark it as checked. */
987 avs->checked[type]++;
988 switch (len) {
989 case 2:
990 val0 = (int)decode_16(value);
991 break;
992 case 4:
993 val0 = (int)decode_32(value);
994 break;
995 default:
996 return 1;
997 }
998 switch (avs->len[type]) {
999 case 2:
1000 val1 = (int)decode_16(avs->attrp[type]);
1001 break;
1002 case 4:
1003 val1 = (int)decode_32(avs->attrp[type]);
1004 break;
1005 default:
1006 return 1;
1007 }
1008 /* Return 0 when the values are equal. */
1009 return (val0 != val1);
1010}
1011
1012/*
1013 * This function is used to validate the returned proposal (protection suite)
1014 * we get from the responder against a proposal we sent. Only run as initiator.
1015 * We return 0 if a match is found (in any transform of this proposal), 1
1016 * otherwise. Also see note in sa_add_transform() below.
1017 */
1018static int
1019sa_validate_proto_xf(struct proto *match, struct payload *xf, int phase)
1020{
1021 struct attr_validation_state *avs;
1022 struct proto_attr *pa;
1023 int found = 0;
1024 size_t i;
1025 u_int8_t xf_id;
1026
1027 if (!match->xf_cnt)
1028 return 0;
1029
1030 if (match->proto != GET_ISAKMP_PROP_PROTO(xf->context->p)field_get_num (isakmp_prop_fld + 1, xf->context->p)) {
1031 LOG_DBG((LOG_SA, 70, "sa_validate_proto_xf: proto %p (#%d) "log_debug (LOG_SA, 70, "sa_validate_proto_xf: proto %p (#%d) "
"protocol mismatch", match, match->no)
1032 "protocol mismatch", match, match->no))log_debug (LOG_SA, 70, "sa_validate_proto_xf: proto %p (#%d) "
"protocol mismatch", match, match->no)
;
1033 return 1;
1034 }
1035 avs = calloc(1, sizeof *avs);
1036 if (!avs) {
1037 log_error("sa_validate_proto_xf: calloc (1, %lu)",
1038 (unsigned long)sizeof *avs);
1039 return 1;
1040 }
1041 avs->phase = phase;
1042
1043 /* Load the "proposal candidate" attribute set. */
1044 (void)attribute_map(xf->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
1045 GET_ISAKMP_GEN_LENGTH(xf->p)field_get_num (isakmp_gen_fld + 2, xf->p) - ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
1046 sa_validate_xf_attrs, avs);
1047 xf_id = GET_ISAKMP_TRANSFORM_ID(xf->p)field_get_num (isakmp_transform_fld + 1, xf->p);
1048
1049 /* Check against the transforms we suggested. */
1050 avs->mode++;
1051 for (pa = TAILQ_FIRST(&match->xfs)((&match->xfs)->tqh_first); pa && !found;
1052 pa = TAILQ_NEXT(pa, next)((pa)->next.tqe_next)) {
1053 if (xf_id != GET_ISAKMP_TRANSFORM_ID(pa->attrs)field_get_num (isakmp_transform_fld + 1, pa->attrs))
1054 continue;
1055
1056 bzero(avs->checked, sizeof avs->checked);
1057 if (attribute_map(pa->attrs + ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
1058 pa->len - ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
1059 sa_validate_xf_attrs, avs) == 0)
1060 found++;
1061
1062 LOG_DBG((LOG_SA, 80, "sa_validate_proto_xf: attr_map "log_debug (LOG_SA, 80, "sa_validate_proto_xf: attr_map " "xf %p proto %p pa %p found %d"
, xf, match, pa, found)
1063 "xf %p proto %p pa %p found %d", xf, match, pa, found))log_debug (LOG_SA, 80, "sa_validate_proto_xf: attr_map " "xf %p proto %p pa %p found %d"
, xf, match, pa, found)
;
1064
1065 if (!found)
1066 continue;
1067
1068 /*
1069 * Require all attributes present and checked. XXX perhaps
1070 * not?
1071 */
1072 for (i = 0; i < sizeof avs->checked; i++)
1073 if (avs->attrp[i] && !avs->checked[i])
1074 found = 0;
1075
1076 LOG_DBG((LOG_SA, 80, "sa_validate_proto_xf: req_attr "log_debug (LOG_SA, 80, "sa_validate_proto_xf: req_attr " "xf %p proto %p pa %p found %d"
, xf, match, pa, found)
1077 "xf %p proto %p pa %p found %d", xf, match, pa, found))log_debug (LOG_SA, 80, "sa_validate_proto_xf: req_attr " "xf %p proto %p pa %p found %d"
, xf, match, pa, found)
;
1078 }
1079 free(avs);
1080 return found ? 0 : 1;
1081}
1082
1083/*
1084 * Register the chosen transform XF into SA. As a side effect set PROTOP
1085 * to point at the corresponding proto structure. INITIATOR is true if we
1086 * are the initiator.
1087 */
1088int
1089sa_add_transform(struct sa *sa, struct payload *xf, int initiator,
1090 struct proto **protop)
1091{
1092 struct proto *proto;
1093 struct payload *prop = xf->context;
1094
1095 *protop = 0;
1096 if (!initiator) {
1097 proto = calloc(1, sizeof *proto);
1098 if (!proto)
1099 log_error("sa_add_transform: calloc (1, %lu) failed",
1100 (unsigned long)sizeof *proto);
1101 } else {
1102 /*
1103 * RFC 2408, section 4.2 states the responder SHOULD use the
1104 * proposal number from the initiator (i.e us), in it's
1105 * selected proposal to make this lookup easier. Most vendors
1106 * follow this. One noted exception is the CiscoPIX (and
1107 * perhaps other Cisco products).
1108 *
1109 * We start by matching on the proposal number, as before.
1110 */
1111 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first);
1112 proto && proto->no != GET_ISAKMP_PROP_NO(prop->p)field_get_num (isakmp_prop_fld + 0, prop->p);
1113 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next))
1114 ;
1115 /*
1116 * If we did not find a match, search through all proposals
1117 * and xforms.
1118 */
1119 if (!proto || sa_validate_proto_xf(proto, xf, sa->phase) != 0)
1120 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first);
1121 proto && sa_validate_proto_xf(proto, xf, sa->phase) != 0;
1122 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next))
1123 ;
1124 }
1125 if (!proto)
1126 return -1;
1127 *protop = proto;
1128
1129 /* Allocate DOI-specific part. */
1130 if (!initiator) {
1131 proto->data = calloc(1, sa->doi->proto_size);
1132 if (!proto->data) {
1133 log_error("sa_add_transform: calloc (1, %lu) failed",
1134 (unsigned long)sa->doi->proto_size);
1135 goto cleanup;
1136 }
1137 }
1138 proto->no = GET_ISAKMP_PROP_NO(prop->p)field_get_num (isakmp_prop_fld + 0, prop->p);
1139 proto->proto = GET_ISAKMP_PROP_PROTO(prop->p)field_get_num (isakmp_prop_fld + 1, prop->p);
1140 proto->spi_sz[0] = GET_ISAKMP_PROP_SPI_SZ(prop->p)field_get_num (isakmp_prop_fld + 2, prop->p);
1141 if (proto->spi_sz[0]) {
1142 proto->spi[0] = malloc(proto->spi_sz[0]);
1143 if (!proto->spi[0])
1144 goto cleanup;
1145 memcpy(proto->spi[0], prop->p + ISAKMP_PROP_SPI_OFF8,
1146 proto->spi_sz[0]);
1147 }
1148 proto->chosen = xf;
1149 proto->sa = sa;
1150 proto->id = GET_ISAKMP_TRANSFORM_ID(xf->p)field_get_num (isakmp_transform_fld + 1, xf->p);
1151 if (!initiator)
1152 TAILQ_INSERT_TAIL(&sa->protos, proto, link)do { (proto)->link.tqe_next = ((void *)0); (proto)->link
.tqe_prev = (&sa->protos)->tqh_last; *(&sa->
protos)->tqh_last = (proto); (&sa->protos)->tqh_last
= &(proto)->link.tqe_next; } while (0)
;
1153
1154 /* Let the DOI get at proto for initializing its own data. */
1155 if (sa->doi->proto_init)
1156 sa->doi->proto_init(proto, 0);
1157
1158 LOG_DBG((LOG_SA, 80,log_debug (LOG_SA, 80, "sa_add_transform: " "proto %p no %d proto %d chosen %p sa %p id %d"
, proto, proto->no, proto->proto, proto->chosen, proto
->sa, proto->id)
1159 "sa_add_transform: "log_debug (LOG_SA, 80, "sa_add_transform: " "proto %p no %d proto %d chosen %p sa %p id %d"
, proto, proto->no, proto->proto, proto->chosen, proto
->sa, proto->id)
1160 "proto %p no %d proto %d chosen %p sa %p id %d",log_debug (LOG_SA, 80, "sa_add_transform: " "proto %p no %d proto %d chosen %p sa %p id %d"
, proto, proto->no, proto->proto, proto->chosen, proto
->sa, proto->id)
1161 proto, proto->no, proto->proto, proto->chosen, proto->sa,log_debug (LOG_SA, 80, "sa_add_transform: " "proto %p no %d proto %d chosen %p sa %p id %d"
, proto, proto->no, proto->proto, proto->chosen, proto
->sa, proto->id)
1162 proto->id))log_debug (LOG_SA, 80, "sa_add_transform: " "proto %p no %d proto %d chosen %p sa %p id %d"
, proto, proto->no, proto->proto, proto->chosen, proto
->sa, proto->id)
;
1163
1164 return 0;
1165
1166cleanup:
1167 if (!initiator) {
1168 free(proto->data);
1169 free(proto);
1170 }
1171 *protop = 0;
1172 return -1;
1173}
1174
1175/* Delete an SA. Tell the peer if NOTIFY is set. */
1176void
1177sa_delete(struct sa *sa, int notify)
1178{
1179 if (notify)
1180 message_send_delete(sa);
1181 sa_free(sa);
1182}
1183
1184
1185/* Teardown all SAs. */
1186void
1187sa_teardown_all(void)
1188{
1189 int i;
1190 struct sa *sa, *next = 0;
1191
1192 LOG_DBG((LOG_SA, 70, "sa_teardown_all:"))log_debug (LOG_SA, 70, "sa_teardown_all:");
1193 /* Get Phase 2 SAs. */
1194 for (i = 0; i <= bucket_mask; i++)
1195 for (sa = LIST_FIRST(&sa_tab[i])((&sa_tab[i])->lh_first); sa; sa = next) {
1196 next = LIST_NEXT(sa, link)((sa)->link.le_next);
1197 if (sa->phase == 2) {
1198 /*
1199 * Teardown the phase 2 SAs by name, similar
1200 * to ui_teardown.
1201 */
1202 LOG_DBG((LOG_SA, 70,log_debug (LOG_SA, 70, "sa_teardown_all: tearing down SA %s",
sa->name ? sa->name : "<unnamed>")
1203 "sa_teardown_all: tearing down SA %s",log_debug (LOG_SA, 70, "sa_teardown_all: tearing down SA %s",
sa->name ? sa->name : "<unnamed>")
1204 sa->name ? sa->name : "<unnamed>"))log_debug (LOG_SA, 70, "sa_teardown_all: tearing down SA %s",
sa->name ? sa->name : "<unnamed>")
;
1205 if (sa->name)
1206 connection_teardown(sa->name);
1207 sa_delete(sa, 1);
1208 }
1209 }
1210}
1211
1212/*
1213 * This function will get called when we are closing in on the death time of SA
1214 */
1215static void
1216sa_soft_expire(void *v_sa)
1217{
1218 struct sa *sa = v_sa;
1219
1220 sa->soft_death = 0;
1221 sa_release(sa);
1222
1223 if ((sa->flags & (SA_FLAG_STAYALIVE0x02 | SA_FLAG_REPLACED0x08)) ==
1224 SA_FLAG_STAYALIVE0x02)
1225 exchange_establish(sa->name, 0, 0, 1);
1226 else
1227 /*
1228 * Start to watch the use of this SA, so a renegotiation can
1229 * happen as soon as it is shown to be alive.
1230 */
1231 sa->flags |= SA_FLAG_FADING0x10;
1232}
1233
1234/* SA has passed its best before date. */
1235static void
1236sa_hard_expire(void *v_sa)
1237{
1238 struct sa *sa = v_sa;
1239
1240 sa->death = 0;
1241 sa_release(sa);
1242
1243 if ((sa->flags & (SA_FLAG_STAYALIVE0x02 | SA_FLAG_REPLACED0x08)) ==
1244 SA_FLAG_STAYALIVE0x02)
1245 exchange_establish(sa->name, 0, 0, 1);
1246
1247 sa_delete(sa, 1);
1248}
1249
1250void
1251sa_reinit(void)
1252{
1253 struct sa *sa;
1254 char *tag;
1255 int i;
1256
1257 /* For now; only do this if we have the proper tag configured. */
1258 tag = conf_get_str("General", "Renegotiate-on-HUP");
1259 if (!tag)
1260 return;
1261
1262 LOG_DBG((LOG_SA, 30, "sa_reinit: renegotiating active connections"))log_debug (LOG_SA, 30, "sa_reinit: renegotiating active connections"
)
;
1263
1264 /*
1265 * Get phase 2 SAs. Soft expire those without active exchanges. Do
1266 * not touch a phase 2 SA where the soft expiration is not set, ie.
1267 * the SA is not yet established.
1268 */
1269 for (i = 0; i <= bucket_mask; i++)
1270 for (sa = LIST_FIRST(&sa_tab[i])((&sa_tab[i])->lh_first); sa; sa = LIST_NEXT(sa, link)((sa)->link.le_next))
1271 if (sa->phase == 2)
1272 if (exchange_lookup_by_name(sa->name,
1273 sa->phase) == 0 && sa->soft_death) {
1274 timer_remove_event(sa->soft_death);
1275 sa_soft_expire(sa);
1276 }
1277}
1278
1279/*
1280 * Get an SA attribute's flag value out of textual description.
1281 */
1282int
1283sa_flag(char *attr)
1284{
1285 static struct sa_flag_map {
1286 char *name;
1287 int flag;
1288 } sa_flag_map[] = {
1289 {
1290 "active-only", SA_FLAG_ACTIVE_ONLY0x20
1291 },
1292
1293 /*
1294 * Below this point are flags that are internal to the
1295 * implementation.
1296 */
1297 {
1298 "__ondemand", SA_FLAG_ONDEMAND0x04
1299 },
1300 {
1301 "ikecfg", SA_FLAG_IKECFG0x40
1302 },
1303 };
1304 size_t i;
1305
1306 for (i = 0; i < sizeof sa_flag_map / sizeof sa_flag_map[0]; i++)
1307 if (strcasecmp(attr, sa_flag_map[i].name) == 0)
1308 return sa_flag_map[i].flag;
1309 log_print("sa_flag: attribute \"%s\" unknown", attr);
1310 return 0;
1311}
1312
1313/* Mark SA as replaced. */
1314void
1315sa_mark_replaced(struct sa *sa)
1316{
1317 LOG_DBG((LOG_SA, 60, "sa_mark_replaced: SA %p (%s) marked as replaced",log_debug (LOG_SA, 60, "sa_mark_replaced: SA %p (%s) marked as replaced"
, sa, sa->name ? sa->name : "unnamed")
1318 sa, sa->name ? sa->name : "unnamed"))log_debug (LOG_SA, 60, "sa_mark_replaced: SA %p (%s) marked as replaced"
, sa, sa->name ? sa->name : "unnamed")
;
1319 if (sa->dpd_event) {
1320 timer_remove_event(sa->dpd_event);
1321 sa->dpd_event = 0;
1322 }
1323 sa->flags |= SA_FLAG_REPLACED0x08;
1324}
1325
1326/* Replace SA */
1327void
1328sa_replace(struct sa *sa, struct sa *new_sa)
1329{
1330 LOG_DBG((LOG_SA, 60, "sa_replace: SA %p (%s) is replaced by SA %p (%s)",log_debug (LOG_SA, 60, "sa_replace: SA %p (%s) is replaced by SA %p (%s)"
, sa, sa->name ? sa->name : "unnamed", new_sa, new_sa->
name ? new_sa->name : "unnamed")
1331 sa, sa->name ? sa->name : "unnamed",log_debug (LOG_SA, 60, "sa_replace: SA %p (%s) is replaced by SA %p (%s)"
, sa, sa->name ? sa->name : "unnamed", new_sa, new_sa->
name ? new_sa->name : "unnamed")
1332 new_sa, new_sa->name ? new_sa->name : "unnamed"))log_debug (LOG_SA, 60, "sa_replace: SA %p (%s) is replaced by SA %p (%s)"
, sa, sa->name ? sa->name : "unnamed", new_sa, new_sa->
name ? new_sa->name : "unnamed")
;
1333 sa_mark_replaced(sa);
1334 if (new_sa->flags & SA_FLAG_REPLACED0x08) {
1335 /* enable the dpd */
1336 if ((new_sa->flags & SA_FLAG_DPD0x80) == SA_FLAG_DPD0x80)
1337 dpd_start(new_sa);
1338 new_sa->flags &= ~SA_FLAG_REPLACED0x08;
1339 }
1340}
1341
1342/*
1343 * Setup expiration timers for SA. This is used for ISAKMP SAs, but also
1344 * possible to use for application SAs if the application does not deal
1345 * with expirations itself. An example is the Linux FreeS/WAN KLIPS IPsec
1346 * stack.
1347 */
1348int
1349sa_setup_expirations(struct sa *sa)
1350{
1351 struct timespec expiration;
1352 u_int64_t seconds = sa->seconds;
1353
1354 /*
1355 * Set the soft timeout to a random percentage between 85 & 95 of
1356 * the negotiated lifetime to break strictly synchronized
1357 * renegotiations. This works better when the randomization is on the
1358 * order of processing plus network-roundtrip times, or larger.
1359 * I.e. it depends on configuration and negotiated lifetimes.
1360 * It is not good to do the decrease on the hard timeout, because then
1361 * we may drop our SA before our peer.
1362 * XXX Better scheme to come?
1363 */
1364 if (!sa->soft_death) {
1365 clock_gettime(CLOCK_MONOTONIC3, &expiration);
1366 /*
1367 * XXX This should probably be configuration controlled
1368 * somehow.
1369 */
1370 seconds = sa->seconds * (850 + arc4random_uniform(100)) / 1000;
1371 LOG_DBG((LOG_TIMER, 95,log_debug (LOG_TIMER, 95, "sa_setup_expirations: SA %p soft timeout in %llu seconds"
, sa, seconds)
1372 "sa_setup_expirations: SA %p soft timeout in %llu seconds",log_debug (LOG_TIMER, 95, "sa_setup_expirations: SA %p soft timeout in %llu seconds"
, sa, seconds)
1373 sa, seconds))log_debug (LOG_TIMER, 95, "sa_setup_expirations: SA %p soft timeout in %llu seconds"
, sa, seconds)
;
1374 expiration.tv_sec += seconds;
1375 sa->soft_death = timer_add_event("sa_soft_expire",
1376 sa_soft_expire, sa, &expiration);
1377 if (!sa->soft_death) {
1378 /* If we don't give up we might start leaking... */
1379 sa_delete(sa, 1);
1380 return -1;
1381 }
1382 sa_reference(sa);
1383 }
1384 if (!sa->death) {
1385 clock_gettime(CLOCK_MONOTONIC3, &expiration);
1386 LOG_DBG((LOG_TIMER, 95,log_debug (LOG_TIMER, 95, "sa_setup_expirations: SA %p hard timeout in %llu seconds"
, sa, sa->seconds)
1387 "sa_setup_expirations: SA %p hard timeout in %llu seconds",log_debug (LOG_TIMER, 95, "sa_setup_expirations: SA %p hard timeout in %llu seconds"
, sa, sa->seconds)
1388 sa, sa->seconds))log_debug (LOG_TIMER, 95, "sa_setup_expirations: SA %p hard timeout in %llu seconds"
, sa, sa->seconds)
;
1389 expiration.tv_sec += sa->seconds;
1390 sa->death = timer_add_event("sa_hard_expire", sa_hard_expire,
1391 sa, &expiration);
1392 if (!sa->death) {
1393 /* If we don't give up we might start leaking... */
1394 sa_delete(sa, 1);
1395 return -1;
1396 }
1397 sa_reference(sa);
1398 }
1399 return 0;
1400}