]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/isakmp.c
ipsec-332.100.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp.c
CommitLineData
d1e348cf
A
1/* $NetBSD: isakmp.c,v 1.20.6.7 2007/08/01 11:52:20 vanhu Exp $ */
2
3/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
52b7d2ce
A
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * 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 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
52b7d2ce 33#define __APPLE_API_PRIVATE
52b7d2ce
A
34
35#include "config.h"
36
37#include <sys/types.h>
38#include <sys/param.h>
39#include <sys/socket.h>
e8d9021d 40#include <sys/ioctl.h>
52b7d2ce
A
41#include <sys/queue.h>
42
43#include <netinet/in.h>
e8d9021d
A
44#include <net/if_var.h>
45#include <netinet6/in6_var.h>
52b7d2ce
A
46#include <arpa/inet.h>
47
48#ifndef HAVE_NETINET6_IPSEC
49#include <netinet/ipsec.h>
50#else
51#include <netinet6/ipsec.h>
52#endif
53
54#include <stdlib.h>
55#include <stdio.h>
56#include <string.h>
57#include <errno.h>
58#if TIME_WITH_SYS_TIME
59# include <sys/time.h>
60# include <time.h>
61#else
62# if HAVE_SYS_TIME_H
63# include <sys/time.h>
64# else
65# include <time.h>
66# endif
67#endif
68#include <netdb.h>
69#ifdef HAVE_UNISTD_H
70#include <unistd.h>
71#endif
72#include <ctype.h>
52b7d2ce
A
73
74#include "var.h"
75#include "misc.h"
76#include "vmbuf.h"
77#include "plog.h"
78#include "sockmisc.h"
79#include "schedule.h"
80#include "debug.h"
65c25746
A
81#include "session.h"
82#include "fsm.h"
52b7d2ce
A
83
84#include "remoteconf.h"
85#include "localconf.h"
86#include "grabmyaddr.h"
52b7d2ce
A
87#include "isakmp_var.h"
88#include "isakmp.h"
89#include "oakley.h"
52b7d2ce
A
90#include "handler.h"
91#include "proposal.h"
92#include "ipsec_doi.h"
93#include "pfkey.h"
94#include "crypto_openssl.h"
95#include "policy.h"
96#include "isakmp_ident.h"
97#include "isakmp_agg.h"
52b7d2ce
A
98#include "isakmp_quick.h"
99#include "isakmp_inf.h"
52b7d2ce
A
100#include "vpn_control.h"
101#include "vpn_control_var.h"
102#ifdef ENABLE_HYBRID
d1e348cf 103#include "vendorid.h"
52b7d2ce 104#include "isakmp_xauth.h"
d1e348cf 105#include "isakmp_unity.h"
52b7d2ce
A
106#include "isakmp_cfg.h"
107#endif
108#ifdef ENABLE_FRAG
109#include "isakmp_frag.h"
110#endif
111#include "strnames.h"
112
d1e348cf
A
113#include <fcntl.h>
114
52b7d2ce
A
115#ifdef ENABLE_NATT
116# include "nattraversal.h"
d1e348cf
A
117#endif
118#include "ike_session.h"
52b7d2ce
A
119# include <netinet/in.h>
120# include <netinet/udp.h>
d1e348cf
A
121# include <netinet/in_systm.h>
122# include <netinet/ip.h>
52b7d2ce 123# define SOL_UDP IPPROTO_UDP
e8d9021d 124#include "power_mgmt.h"
52b7d2ce 125
65c25746
A
126extern caddr_t val2str (const char *, size_t);
127u_char i_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the i_ck. */
128u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */
129
130
131static void isakmp_main (vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *);
132static void ikev1_received_packet(vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *);
133static int ikev1_ph1begin_r (ike_session_t *session, vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *, u_int8_t);
134static int ikev1_ph2begin_i (phase1_handle_t *, phase2_handle_t *);
135static int ikev1_ph2begin_r (phase1_handle_t *, vchar_t *);
136
137
52b7d2ce 138#ifdef ENABLE_FRAG
65c25746 139static void frag_handler (phase1_handle_t *, vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *);
52b7d2ce
A
140#endif
141
142/*
143 * isakmp packet handler
144 */
65c25746
A
145void
146isakmp_handler(int so_isakmp)
52b7d2ce
A
147{
148 struct isakmp isakmp;
149 union {
85f41bec 150 u_int64_t force_align; // Wcast-align fix - force alignment
52b7d2ce
A
151 char buf[sizeof (isakmp) + 4];
152 u_int32_t non_esp[2];
d1e348cf 153 char lbuf[sizeof(struct udphdr) +
d1e348cf 154 sizeof(struct ip) +
d1e348cf 155 sizeof(isakmp) + 4];
52b7d2ce
A
156 } x;
157 struct sockaddr_storage remote;
158 struct sockaddr_storage local;
159 unsigned int remote_len = sizeof(remote);
160 unsigned int local_len = sizeof(local);
85f41bec
A
161 ssize_t len = 0;
162 int extralen = 0;
52b7d2ce
A
163 u_short port;
164 vchar_t *buf = NULL, *tmpbuf = NULL;
165 int error = -1;
166
e8d9021d 167 if (slept_at || woke_at) {
7ebaebe2 168 plog(ASL_LEVEL_DEBUG, /* this log is high volume */
e8d9021d 169 "ignoring isakmp port until power-mgmt event is handled.\n");
65c25746 170 return;
e8d9021d
A
171 }
172
52b7d2ce
A
173 /* read message by MSG_PEEK */
174 while ((len = recvfromto(so_isakmp, x.buf, sizeof(x),
85f41bec 175 MSG_PEEK, &remote, &remote_len, &local, &local_len)) < 0) {
52b7d2ce
A
176 if (errno == EINTR)
177 continue;
65c25746 178 plog(ASL_LEVEL_ERR,
52b7d2ce
A
179 "failed to receive isakmp packet: %s\n",
180 strerror (errno));
181 goto end;
182 }
183
184 /* keep-alive packet - ignore */
185 if (len == 1 && (x.buf[0]&0xff) == 0xff) {
186 /* Pull the keep-alive packet */
187 if ((len = recvfrom(so_isakmp, (char *)x.buf, 1,
188 0, (struct sockaddr *)&remote, &remote_len)) != 1) {
65c25746 189 plog(ASL_LEVEL_ERR,
52b7d2ce
A
190 "failed to receive keep alive packet: %s\n",
191 strerror (errno));
d1e348cf 192 }
52b7d2ce
A
193 goto end;
194 }
195
d1e348cf 196
52b7d2ce
A
197 /* we don't know about portchange yet,
198 look for non-esp marker instead */
199 if (x.non_esp[0] == 0 && x.non_esp[1] != 0)
200 extralen = NON_ESP_MARKER_LEN;
52b7d2ce
A
201
202 /* now we know if there is an extra non-esp
203 marker at the beginning or not */
204 memcpy ((char *)&isakmp, x.buf + extralen, sizeof (isakmp));
205
206 /* check isakmp header length, as well as sanity of header length */
207 if (len < sizeof(isakmp) || ntohl(isakmp.len) < sizeof(isakmp)) {
65c25746
A
208 plog(ASL_LEVEL_ERR,
209 "packet shorter than isakmp header size (size: %zu, minimum expected: %zu)\n", len, sizeof(isakmp));
52b7d2ce
A
210 /* dummy receive */
211 if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
212 0, (struct sockaddr *)&remote, &remote_len)) < 0) {
65c25746 213 plog(ASL_LEVEL_ERR,
52b7d2ce
A
214 "failed to receive isakmp packet: %s\n",
215 strerror (errno));
216 }
217 goto end;
218 }
219
220 /* reject it if the size is tooooo big. */
221 if (ntohl(isakmp.len) > 0xffff) {
65c25746 222 plog(ASL_LEVEL_ERR,
52b7d2ce
A
223 "the length in the isakmp header is too big.\n");
224 if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
225 0, (struct sockaddr *)&remote, &remote_len)) < 0) {
65c25746 226 plog(ASL_LEVEL_ERR,
52b7d2ce
A
227 "failed to receive isakmp packet: %s\n",
228 strerror (errno));
229 }
230 goto end;
231 }
232
233 /* read real message */
234 if ((tmpbuf = vmalloc(ntohl(isakmp.len) + extralen)) == NULL) {
65c25746 235 plog(ASL_LEVEL_ERR,
52b7d2ce
A
236 "failed to allocate reading buffer (%u Bytes)\n",
237 ntohl(isakmp.len) + extralen);
238 /* dummy receive */
239 if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
240 0, (struct sockaddr *)&remote, &remote_len)) < 0) {
65c25746 241 plog(ASL_LEVEL_ERR,
52b7d2ce
A
242 "failed to receive isakmp packet: %s\n",
243 strerror (errno));
52b7d2ce 244 error = -2; /* serious problem with socket */
52b7d2ce
A
245 }
246 goto end;
247 }
248
249 while ((len = recvfromto(so_isakmp, (char *)tmpbuf->v, tmpbuf->l,
85f41bec 250 0, &remote, &remote_len, &local, &local_len)) < 0) {
52b7d2ce
A
251 if (errno == EINTR)
252 continue;
65c25746 253 plog(ASL_LEVEL_ERR,
52b7d2ce
A
254 "failed to receive isakmp packet: %s\n",
255 strerror (errno));
256 goto end;
257 }
258
e8d9021d 259 if (len < extralen) {
65c25746
A
260 plog(ASL_LEVEL_ERR,
261 "invalid len (%zd Bytes) & extralen (%d Bytes)\n",
e8d9021d
A
262 len, extralen);
263 goto end;
264 }
265
52b7d2ce 266 if ((buf = vmalloc(len - extralen)) == NULL) {
65c25746
A
267 plog(ASL_LEVEL_ERR,
268 "failed to allocate reading buffer (%lu Bytes)\n",
52b7d2ce
A
269 (len - extralen));
270 goto end;
271 }
272
273 memcpy (buf->v, tmpbuf->v + extralen, buf->l);
274
52b7d2ce
A
275 len -= extralen;
276
277 if (len != buf->l) {
65c25746 278 plog(ASL_LEVEL_ERR, "received invalid length (%zd != %zu), why ?\n",
52b7d2ce
A
279 len, buf->l);
280 goto end;
281 }
282
65c25746
A
283 plog(ASL_LEVEL_DEBUG, "%zd bytes message received %s\n",
284 len, saddr2str_fromto("from %s to %s",
285 (struct sockaddr *)&remote,
286 (struct sockaddr *)&local));
52b7d2ce
A
287
288 /* avoid packets with malicious port/address */
289 switch (remote.ss_family) {
290 case AF_INET:
291 port = ((struct sockaddr_in *)&remote)->sin_port;
292 break;
293#ifdef INET6
294 case AF_INET6:
295 port = ((struct sockaddr_in6 *)&remote)->sin6_port;
296 break;
297#endif
298 default:
65c25746 299 plog(ASL_LEVEL_ERR,
52b7d2ce
A
300 "invalid family: %d\n", remote.ss_family);
301 goto end;
302 }
303 if (port == 0) {
65c25746 304 plog(ASL_LEVEL_ERR,
52b7d2ce
A
305 "src port == 0 (valid as UDP but not with IKE)\n");
306 goto end;
307 }
308
309 /* XXX: check sender whether to be allowed or not to accept */
310
311 /* XXX: I don't know how to check isakmp half connection attack. */
312
313 /* simply reply if the packet was processed. */
65c25746
A
314
315 if (ike_session_check_recvdpkt(&remote, &local, buf)) {
e8d9021d
A
316 IPSECLOGASLMSG("Received retransmitted packet from %s.\n",
317 saddr2str((struct sockaddr *)&remote));
318
65c25746 319 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
320 "the packet is retransmitted by %s.\n",
321 saddr2str((struct sockaddr *)&remote));
322 error = 0;
323 goto end;
324 }
325
326 /* isakmp main routine */
65c25746 327 isakmp_main(buf, &remote, &local);
52b7d2ce
A
328
329end:
d1e348cf
A
330 if (tmpbuf != NULL)
331 vfree(tmpbuf);
52b7d2ce
A
332 if (buf != NULL)
333 vfree(buf);
334
65c25746 335 return;
52b7d2ce
A
336}
337
338/*
339 * main processing to handle isakmp payload
340 */
65c25746
A
341static void
342isakmp_main(vchar_t *msg, struct sockaddr_storage *remote, struct sockaddr_storage *local)
52b7d2ce
A
343{
344 struct isakmp *isakmp = (struct isakmp *)msg->v;
65c25746 345 u_int8_t isakmp_version = isakmp->v;
52b7d2ce
A
346
347#ifdef HAVE_PRINT_ISAKMP_C
348 isakmp_printpacket(msg, remote, local, 0);
349#endif
350
351 /* the initiator's cookie must not be zero */
352 if (memcmp(&isakmp->i_ck, r_ck0, sizeof(cookie_t)) == 0) {
65c25746 353 plog(ASL_LEVEL_ERR,
52b7d2ce 354 "malformed cookie received.\n");
65c25746 355 return;
52b7d2ce
A
356 }
357
358 /* Check the Major and Minor Version fields. */
359 /*
360 * XXX Is is right to check version here ?
361 * I think it may no be here because the version depends
362 * on exchange status.
363 */
d9c572c0 364 if (ISAKMP_GETMAJORV(isakmp_version) != ISAKMP_MAJOR_VERSION_IKEV1) {
65c25746
A
365 plog(ASL_LEVEL_ERR, "invalid major version %d.\n", isakmp_version);
366 return;
367 }
368
369#if 0
370#if ISAKMP_MINOR_VERSION > 0 //%%%%%%%% fix this
371 if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) { //%%%%%%%%%%%%%%% ??????
372 plog(ASL_LEVEL_ERR,
52b7d2ce
A
373 "invalid minor version %d.\n",
374 ISAKMP_GETMINORV(isakmp->v));
65c25746 375 return;
52b7d2ce
A
376 }
377#endif
65c25746 378#endif
52b7d2ce 379
65c25746
A
380 if (isakmp_version == ISAKMP_VERSION_NUMBER_IKEV1) {
381 /* check the Flags field. */
382 /* XXX How is the exclusive check, E and A ? */
d9c572c0 383 if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) {
65c25746
A
384 plog(ASL_LEVEL_ERR, "invalid flag 0x%02x.\n", isakmp->flags);
385 return;
386 }
52b7d2ce 387
65c25746
A
388 /* ignore commit bit. */
389 if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) {
d9c572c0 390 if (isakmp->msgid == 0) {
65c25746
A
391 isakmp_info_send_nx(isakmp, remote, local,
392 ISAKMP_NTYPE_INVALID_FLAGS, NULL);
393 plog(ASL_LEVEL_ERR, "Commit bit on Phase 1 forbidden.\n");
394 return;
395 }
52b7d2ce 396 }
65c25746
A
397
398 ikev1_received_packet(msg, local, remote);
52b7d2ce 399 }
65c25746
A
400 return;
401}
52b7d2ce 402
65c25746
A
403/*
404 * ikev1_received_packet
405 * Handler for received IKEv1 Packets
406 */
407static void
408ikev1_received_packet(vchar_t *msg, struct sockaddr_storage *local, struct sockaddr_storage *remote)
409{
410 ike_session_t *session;
411 phase1_handle_t *iph1;
412
413 struct isakmp *isakmp = (struct isakmp *)msg->v;
414 isakmp_index *index = (isakmp_index *)isakmp;
415
1760d65d
A
416 session = ike_session_get_session(local, remote, 0, index);
417 if (!session) {
418 session = ike_session_get_session(local, remote, 1, NULL);
419 }
65c25746 420 if (!session) {
7ebaebe2 421 plog (ASL_LEVEL_NOTICE, "failed to allocate or find ike session.\n");
65c25746
A
422 fatal_error(-1);
423 }
424
425 iph1 = ike_session_getph1byindex(session, index);
52b7d2ce
A
426 if (iph1 != NULL) {
427 /* validity check */
428 if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 &&
429 iph1->side == INITIATOR) {
7ebaebe2 430 plog(ASL_LEVEL_NOTICE,
65c25746 431 "Malformed cookie received or "
52b7d2ce 432 "the initiator's cookies collide.\n");
65c25746 433 return;
52b7d2ce 434 }
65c25746
A
435
436
52b7d2ce
A
437 /* Floating ports for NAT-T */
438 if (NATT_AVAILABLE(iph1) &&
439 ! (iph1->natt_flags & NAT_PORTS_CHANGED) &&
440 ((cmpsaddrstrict(iph1->remote, remote) != 0) ||
441 (cmpsaddrstrict(iph1->local, local) != 0)))
d9c572c0 442 {
52b7d2ce
A
443 /* prevent memory leak */
444 racoon_free(iph1->remote);
445 racoon_free(iph1->local);
d1e348cf
A
446 iph1->remote = NULL;
447 iph1->local = NULL;
52b7d2ce
A
448
449 /* copy-in new addresses */
65c25746 450 iph1->remote = dupsaddr(remote);
d1e348cf 451 if (iph1->remote == NULL) {
65c25746
A
452 plog(ASL_LEVEL_ERR,
453 "Phase 1 failed: dupsaddr failed.\n");
454 fatal_error(-1);
d1e348cf 455 }
65c25746 456 iph1->local = dupsaddr(local);
d1e348cf 457 if (iph1->local == NULL) {
65c25746
A
458 plog(ASL_LEVEL_ERR,
459 "Phase 1 failed: dupsaddr failed.\n");
460 fatal_error(-1);
461 }
52b7d2ce
A
462
463 /* set the flag to prevent further port floating
464 (FIXME: should we allow it? E.g. when the NAT gw
465 is rebooted?) */
466 iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
467
468 /* print some neat info */
7ebaebe2 469 plog (ASL_LEVEL_NOTICE,
52b7d2ce 470 "NAT-T: ports changed to: %s\n",
85f41bec 471 saddr2str_fromto("%s<->%s", (struct sockaddr *)iph1->remote, (struct sockaddr *)iph1->local));
52b7d2ce 472 }
65c25746 473
52b7d2ce
A
474 /* must be same addresses in one stream of a phase at least. */
475 if (cmpsaddrstrict(iph1->remote, remote) != 0) {
476 char *saddr_db, *saddr_act;
477
85f41bec
A
478 saddr_db = racoon_strdup(saddr2str((struct sockaddr *)iph1->remote));
479 saddr_act = racoon_strdup(saddr2str((struct sockaddr *)remote));
d1e348cf
A
480 STRDUP_FATAL(saddr_db);
481 STRDUP_FATAL(saddr_act);
52b7d2ce 482
65c25746
A
483 plog(ASL_LEVEL_WARNING,
484 "Remote address mismatched. db=%s, act=%s\n",
52b7d2ce
A
485 saddr_db, saddr_act);
486
487 racoon_free(saddr_db);
488 racoon_free(saddr_act);
489 }
490
491 /*
65c25746
A
492 * don't check of exchange type here because other type will have
493 * the same index, for example, informational exchange.
52b7d2ce
A
494 */
495
d1e348cf 496 // received ike packets: update dpd checks
65c25746 497 isakmp_reschedule_info_monitor_if_pending(iph1, "IKE packet received from peer");
52b7d2ce 498
52b7d2ce 499 }
65c25746
A
500
501 //
502 // Check exchange type and process accordingly
503 //
504 switch (isakmp->etype) {
52b7d2ce 505
65c25746
A
506 case ISAKMP_ETYPE_IDENT:
507 case ISAKMP_ETYPE_AGG:
508 {
509 /* phase 1 validity check */
510 if (isakmp->msgid != 0) {
511 plog(ASL_LEVEL_ERR, "Message id should be zero in Phase 1.\n");
512 return;
513 }
514
515 /* search for isakmp status record of phase 1 */
516 if (iph1 == NULL) {
517 /*
518 * the packet must be the 1st message from a initiator
519 * or the 2nd message from the responder.
520 */
521
522 /* search for phase1 handle by index without r_ck */
523 iph1 = ike_session_getph1byindex0(session, index);
524 if (iph1 == NULL) {
525 /*it must be the 1st message from a initiator.*/
526 if (memcmp(&isakmp->r_ck, r_ck0,
527 sizeof(cookie_t)) != 0) {
528
7ebaebe2 529 plog(ASL_LEVEL_NOTICE, "Malformed cookie received "
65c25746
A
530 "or the spi expired.\n");
531 return;
532 }
533
534 /* Initiation of new exchange */
535 ikev1_ph1begin_r(session, msg, remote, local, isakmp->etype);
536 return;
537 }
538 }
539
540 /*
541 * Don't delete phase 1 handler for mismatch
542 * because of no authentication has been completed.
543 */
544 if (iph1->etype != isakmp->etype) {
65c25746
A
545 plog(ASL_LEVEL_ERR,
546 "Exchange type is mismatched: "
547 "db=%s packet=%s, ignore it.\n",
548 s_isakmp_etype(iph1->etype),
549 s_isakmp_etype(isakmp->etype));
550 return;
551 }
552
553 if (isakmp->np == ISAKMP_NPTYPE_FRAG) {
554 frag_handler(iph1, msg, remote, local);
555 return;
556 }
557 fsm_ikev1_phase1_process_payloads(iph1, msg);
558 }
559 break;
560
561 case ISAKMP_ETYPE_INFO:
562 case ISAKMP_ETYPE_ACKINFO:
563 {
564 /*
565 * iph1 must be present for Information message.
566 * if iph1 is null then trying to get the phase1 status
567 * as the packet from responder againt initiator's 1st
568 * exchange in phase 1.
569 * NOTE: We think such informational exchange should be ignored.
570 */
571 if (iph1 == NULL) {
572 iph1 = ike_session_getph1byindex0(session, index);
573 if (iph1 == NULL) {
574 plog(ASL_LEVEL_ERR, "Unknown Informational exchange received.\n");
575 return;
576 }
577 if (cmpsaddrstrict(iph1->remote, remote) != 0) {
578 plog(ASL_LEVEL_WARNING,
579 "Remote address mismatched. "
580 "db=%s\n",
581 saddr2str((struct sockaddr *)iph1->remote));
582 }
583 }
584 if (isakmp->np == ISAKMP_NPTYPE_FRAG)
585 return frag_handler(iph1, msg, remote, local);
586
587 if (isakmp_info_recv(iph1, msg) < 0)
588 return;
589 }
590 break;
591
592 case ISAKMP_ETYPE_QUICK:
593 {
594 u_int32_t msgid = isakmp->msgid;
595 phase2_handle_t *iph2;
596
597 if (iph1 == NULL) {
598 isakmp_info_send_nx(isakmp, remote, local,
599 ISAKMP_NTYPE_INVALID_COOKIE, NULL);
600 plog(ASL_LEVEL_ERR, "Can't start the quick mode, "
601 "there is no ISAKMP-SA, %s\n", isakmp_pindex((isakmp_index *)&isakmp->i_ck,
602 isakmp->msgid));
603 return;
604 }
605 #ifdef ENABLE_HYBRID
606 /* Reinit the IVM if it's still there */
607 if (iph1->mode_cfg && iph1->mode_cfg->ivm) {
608 oakley_delivm(iph1->mode_cfg->ivm);
609 iph1->mode_cfg->ivm = NULL;
610 }
611 #endif
612 if (isakmp->np == ISAKMP_NPTYPE_FRAG) {
613 frag_handler(iph1, msg, remote, local);
614 return;
615 }
616
617 /* check status of phase 1 whether negotiated or not. */
618 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
65c25746
A
619 plog(ASL_LEVEL_ERR, "can't start the quick mode, "
620 "there is no valid ISAKMP-SA, %s\n", isakmp_pindex(&iph1->index, iph1->msgid));
621 return;
622 }
623
624 /* search isakmp phase 2 stauts record. */
625 iph2 = ike_session_getph2bymsgid(iph1, msgid);
626 if (iph2 == NULL) {
627 /* it must be new negotiation as responder */
628 ikev1_ph2begin_r(iph1, msg);
629 return;
630 }
631
632 /* commit bit. */
633 /* XXX
634 * we keep to set commit bit during negotiation.
635 * When SA is configured, bit will be reset.
636 * XXX
637 * don't initiate commit bit. should be fixed in the future.
638 */
639 if (ISSET(isakmp->flags, ISAKMP_FLAG_C))
640 iph2->flags |= ISAKMP_FLAG_C;
641
642 if (ISSET(isakmp->flags, ISAKMP_FLAG_E) &&
643 (iph2->ph1 == NULL || iph2->ph1->approval == NULL)) {
65c25746
A
644 plog(ASL_LEVEL_ERR, "can't start the quick mode, "
645 "invalid linked ISAKMP-SA\n");
646 return;
647 }
648 fsm_ikev1_phase2_process_payloads(iph2, msg);
649 }
650 break;
651
652 case ISAKMP_ETYPE_CFG:
653 {
654 if (iph1 == NULL) {
655 plog(ASL_LEVEL_ERR,
656 "mode config %d from %s, "
657 "but we have no ISAKMP-SA.\n",
658 isakmp->etype, saddr2str((struct sockaddr *)remote));
659 return;
660 }
661 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
662 plog(ASL_LEVEL_ERR,
663 "mode config %d from %s, "
664 "but ISAKMP-SA %s isn't established.\n",
665 isakmp->etype, saddr2str((struct sockaddr *)remote),
666 isakmp_pindex(&iph1->index, iph1->msgid));
667 return;
668 }
669 if (isakmp->np == ISAKMP_NPTYPE_FRAG)
670 return frag_handler(iph1, msg, remote, local);
671 isakmp_cfg_r(iph1, msg);
672 }
673 break;
674
675 case ISAKMP_ETYPE_NEWGRP:
676 case ISAKMP_ETYPE_AUTH:
677 case ISAKMP_ETYPE_NONE:
678 default:
679 plog(ASL_LEVEL_ERR,
680 "Invalid exchange type %d from %s.\n",
681 isakmp->etype, saddr2str((struct sockaddr *)remote));
682 break;
52b7d2ce 683 }
52b7d2ce
A
684}
685
686/* new negotiation of phase 1 for initiator */
687int
65c25746 688ikev1_ph1begin_i(ike_session_t *session, struct remoteconf *rmconf, struct sockaddr_storage *remote,
d06a7ccb 689 struct sockaddr_storage *local, int started_by_api, nw_nat64_prefix_t *nat64_prefix)
52b7d2ce 690{
65c25746
A
691
692 phase1_handle_t *iph1;
52b7d2ce
A
693#ifdef ENABLE_STATS
694 struct timeval start, end;
695#endif
696
65c25746 697 if (session == NULL) {
1760d65d 698 session = ike_session_get_session(local, remote, 1, NULL);
65c25746 699 if (!session) {
7ebaebe2 700 plog (ASL_LEVEL_NOTICE, "failed to allocate or find ike session.\n");
65c25746
A
701 fatal_error(-1);
702 }
703 }
704
52b7d2ce 705 /* get new entry to isakmp status table. */
65c25746 706 iph1 = ike_session_newph1(ISAKMP_VERSION_NUMBER_IKEV1);
52b7d2ce
A
707 if (iph1 == NULL)
708 return -1;
709
52b7d2ce 710 iph1->rmconf = rmconf;
65c25746 711 retain_rmconf(iph1->rmconf);
52b7d2ce 712 iph1->side = INITIATOR;
d1e348cf 713 iph1->started_by_api = started_by_api;
d06a7ccb
A
714 if (nat64_prefix != NULL) {
715 memcpy(&iph1->nat64_prefix, nat64_prefix, sizeof(*nat64_prefix));
716 }
65c25746 717 iph1->version = ISAKMP_VERSION_NUMBER_IKEV1;
52b7d2ce
A
718 iph1->msgid = 0;
719 iph1->flags = 0;
720 iph1->ph2cnt = 0;
65c25746 721
52b7d2ce 722#ifdef ENABLE_HYBRID
d1e348cf
A
723 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
724 /* don't call remph1(iph1) until after insph1(iph1) is called */
65c25746 725 ike_session_delph1(iph1);
52b7d2ce 726 return -1;
d1e348cf 727 }
52b7d2ce 728#endif
d1e348cf
A
729
730 if(rmconf->ike_frag == ISAKMP_FRAG_FORCE)
731 iph1->frag = 1;
732 else
733 iph1->frag = 0;
52b7d2ce 734 iph1->frag_chain = NULL;
52b7d2ce
A
735 iph1->approval = NULL;
736
737 /* XXX copy remote address */
d1e348cf
A
738 if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
739 /* don't call remph1(iph1) until after insph1(iph1) is called */
47612122 740 iph1 = NULL; /* deleted in copy_ph1addresses */
52b7d2ce 741 return -1;
d1e348cf 742 }
52b7d2ce 743
65c25746 744 if (ike_session_link_phase1(session, iph1) != 0) {
7ebaebe2 745 plog(ASL_LEVEL_NOTICE, "Failed to link ph1 to session\n");
65c25746 746 ike_session_delph1(iph1);
d1e348cf
A
747 return -1;
748 }
e8d9021d
A
749 // HACK!!! to track rekeys across SIGHUPs
750 if (started_by_api == VPN_RESTARTED_BY_API &&
751 !iph1->is_rekey) {
752 iph1->parent_session->established = 1;
753 iph1->parent_session->ikev1_state.ph2cnt++;
754 iph1->is_rekey = 1;
755 }
d1e348cf 756
52b7d2ce
A
757 /* start phase 1 exchange */
758 iph1->etype = rmconf->etypes->type;
65c25746
A
759 if (iph1->etype == ISAKMP_ETYPE_IDENT)
760 fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_START);
761 else if (iph1->etype == ISAKMP_ETYPE_AGG)
762 fsm_set_state(&iph1->status, IKEV1_STATE_AGG_I_START);
763 else
764 return -1;
765
766 plog(ASL_LEVEL_DEBUG, "===\n");
52b7d2ce
A
767 {
768 char *a;
769
85f41bec 770 a = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
d1e348cf
A
771 STRDUP_FATAL(a);
772
7ebaebe2 773 plog(ASL_LEVEL_NOTICE,
52b7d2ce 774 "initiate new phase 1 negotiation: %s<=>%s\n",
85f41bec 775 a, saddr2str((struct sockaddr *)iph1->remote));
52b7d2ce
A
776 racoon_free(a);
777 }
7ebaebe2 778 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
779 "begin %s mode.\n",
780 s_isakmp_etype(iph1->etype));
781
782#ifdef ENABLE_STATS
783 gettimeofday(&iph1->start, NULL);
784 gettimeofday(&start, NULL);
785#endif
e8d9021d 786
65c25746 787 IPSECLOGASLMSG("IPSec Phase 1 started (Initiated by me).\n");
52b7d2ce 788
65c25746
A
789 if (fsm_ikev1_phase1_send_response(iph1, NULL)) {
790 ike_session_unlink_phase1(iph1);
52b7d2ce
A
791 return -1;
792 }
793
794#ifdef ENABLE_STATS
795 gettimeofday(&end, NULL);
796 syslog(LOG_NOTICE, "%s(%s): %8.6f",
65c25746 797 "Phase 1",
52b7d2ce
A
798 s_isakmp_state(iph1->etype, iph1->side, iph1->status),
799 timedelta(&start, &end));
800#endif
801
802#ifdef ENABLE_VPNCONTROL_PORT
803 vpncontrol_notify_phase_change(1, FROM_LOCAL, iph1, NULL);
804#endif
52b7d2ce
A
805
806 return 0;
807}
808
809/* new negotiation of phase 1 for responder */
810static int
65c25746
A
811ikev1_ph1begin_r(ike_session_t *session, vchar_t *msg, struct sockaddr_storage *remote,
812 struct sockaddr_storage *local, u_int8_t etype)
52b7d2ce 813{
65c25746
A
814
815 struct isakmp *isakmp = (struct isakmp *)msg->v;
52b7d2ce 816 struct remoteconf *rmconf;
65c25746 817 phase1_handle_t *iph1;
52b7d2ce
A
818 struct etypes *etypeok;
819#ifdef ENABLE_STATS
820 struct timeval start, end;
821#endif
822
823 /* look for my configuration */
824 rmconf = getrmconf(remote);
825 if (rmconf == NULL) {
65c25746 826 plog(ASL_LEVEL_ERR,
52b7d2ce
A
827 "couldn't find "
828 "configuration.\n");
829 return -1;
830 }
831
832 /* check to be acceptable exchange type */
833 etypeok = check_etypeok(rmconf, etype);
834 if (etypeok == NULL) {
65c25746 835 plog(ASL_LEVEL_ERR,
52b7d2ce
A
836 "not acceptable %s mode\n", s_isakmp_etype(etype));
837 return -1;
838 }
65c25746 839
52b7d2ce 840 /* get new entry to isakmp status table. */
65c25746 841 iph1 = ike_session_newph1(ISAKMP_VERSION_NUMBER_IKEV1);
52b7d2ce
A
842 if (iph1 == NULL)
843 return -1;
844
845 memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck));
65c25746
A
846 iph1->rmconf = rmconf;
847 retain_rmconf(iph1->rmconf);
52b7d2ce
A
848 iph1->flags = 0;
849 iph1->side = RESPONDER;
d1e348cf 850 iph1->started_by_api = 0;
52b7d2ce
A
851 iph1->etype = etypeok->type;
852 iph1->version = isakmp->v;
853 iph1->msgid = 0;
65c25746 854
7ebaebe2 855 if (iph1->etype == ISAKMP_ETYPE_IDENT) {
65c25746 856 fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_R_START);
7ebaebe2 857 } else if (iph1->etype == ISAKMP_ETYPE_AGG) {
65c25746 858 fsm_set_state(&iph1->status, IKEV1_STATE_AGG_R_START);
7ebaebe2
A
859 } else {
860 ike_session_delph1(iph1);
65c25746 861 return -1;
7ebaebe2 862 }
65c25746
A
863
864
52b7d2ce 865#ifdef ENABLE_HYBRID
d1e348cf
A
866 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
867 /* don't call remph1(iph1) until after insph1(iph1) is called */
65c25746 868 ike_session_delph1(iph1);
52b7d2ce 869 return -1;
d1e348cf 870 }
52b7d2ce 871#endif
65c25746 872
52b7d2ce
A
873 iph1->frag = 0;
874 iph1->frag_chain = NULL;
52b7d2ce
A
875 iph1->approval = NULL;
876
52b7d2ce
A
877 /* RFC3947 says that we MUST accept new phases1 on NAT-T floated port.
878 * We have to setup this flag now to correctly generate the first reply.
879 * Don't know if a better check could be done for that ?
880 */
881 if(extract_port(local) == lcconf->port_isakmp_natt)
882 iph1->natt_flags |= (NAT_PORTS_CHANGED);
52b7d2ce
A
883
884 /* copy remote address */
d1e348cf
A
885 if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
886 /* don't call remph1(iph1) until after insph1(iph1) is called */
47612122 887 iph1 = NULL; /* deleted in copy_ph1addresses */
52b7d2ce 888 return -1;
d1e348cf 889 }
52b7d2ce 890
65c25746
A
891 if (ike_session_link_phase1(session, iph1) != 0) {
892 ike_session_delph1(iph1);
d1e348cf
A
893 return -1;
894 }
895
65c25746 896 plog(ASL_LEVEL_DEBUG, "===\n");
52b7d2ce
A
897 {
898 char *a;
899
85f41bec 900 a = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
d1e348cf
A
901 STRDUP_FATAL(a);
902
7ebaebe2 903 plog(ASL_LEVEL_NOTICE,
52b7d2ce 904 "respond new phase 1 negotiation: %s<=>%s\n",
85f41bec 905 a, saddr2str((struct sockaddr *)iph1->remote));
52b7d2ce
A
906 racoon_free(a);
907 }
7ebaebe2 908 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
909 "begin %s mode.\n", s_isakmp_etype(etype));
910
911#ifdef ENABLE_STATS
912 gettimeofday(&iph1->start, NULL);
913 gettimeofday(&start, NULL);
914#endif
d1e348cf 915
65c25746 916 IPSECLOGASLMSG("IPSec Phase 1 started (Initiated by peer).\n");
d1e348cf
A
917
918 /* now that we have a phase1 handle, feed back into our
919 * main receive function to catch fragmented packets
920 */
65c25746
A
921 isakmp_main(msg, remote, local);
922 return 0;
52b7d2ce
A
923}
924
925/* new negotiation of phase 2 for initiator */
926static int
65c25746 927ikev1_ph2begin_i(phase1_handle_t *iph1, phase2_handle_t *iph2)
52b7d2ce 928{
65c25746 929
52b7d2ce
A
930#ifdef ENABLE_HYBRID
931 if (xauth_check(iph1) != 0) {
65c25746 932 plog(ASL_LEVEL_ERR,
52b7d2ce
A
933 "Attempt to start phase 2 whereas Xauth failed\n");
934 return -1;
935 }
936#endif
937
938 /* found ISAKMP-SA. */
65c25746
A
939 plog(ASL_LEVEL_DEBUG, "===\n");
940 plog(ASL_LEVEL_DEBUG, "begin QUICK mode.\n");
52b7d2ce
A
941 {
942 char *a;
85f41bec 943 a = racoon_strdup(saddr2str((struct sockaddr *)iph2->src));
d1e348cf
A
944 STRDUP_FATAL(a);
945
7ebaebe2 946 plog(ASL_LEVEL_NOTICE,
52b7d2ce 947 "initiate new phase 2 negotiation: %s<=>%s\n",
85f41bec 948 a, saddr2str((struct sockaddr *)iph2->dst));
52b7d2ce
A
949 racoon_free(a);
950 }
951
952#ifdef ENABLE_STATS
953 gettimeofday(&iph2->start, NULL);
954#endif
52b7d2ce 955
65c25746 956 iph2->is_dying = 0;
d06a7ccb 957 memcpy(&iph2->nat64_prefix, &iph1->nat64_prefix, sizeof(iph2->nat64_prefix));
65c25746 958 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_START);
e8d9021d 959
65c25746
A
960 IPSECLOGASLMSG("IPSec Phase 2 started (Initiated by me).\n");
961 if (quick_iprep(iph2, NULL))
52b7d2ce 962 return -1;
52b7d2ce
A
963
964#ifdef ENABLE_VPNCONTROL_PORT
965 vpncontrol_notify_phase_change(1, FROM_LOCAL, NULL, iph2);
966#endif
967
968 return 0;
969}
970
971/* new negotiation of phase 2 for responder */
972static int
65c25746 973ikev1_ph2begin_r(phase1_handle_t *iph1, vchar_t *msg)
52b7d2ce
A
974{
975 struct isakmp *isakmp = (struct isakmp *)msg->v;
65c25746 976 phase2_handle_t *iph2 = 0;
52b7d2ce
A
977 int error;
978#ifdef ENABLE_STATS
979 struct timeval start, end;
980#endif
981#ifdef ENABLE_HYBRID
982 if (xauth_check(iph1) != 0) {
65c25746
A
983 plog(ASL_LEVEL_ERR,
984 "Attempt to start Phase 2 whereas Xauth failed\n");
52b7d2ce
A
985 return -1;
986 }
987#endif
988
65c25746 989 iph2 = ike_session_newph2(ISAKMP_VERSION_NUMBER_IKEV1, PHASE2_TYPE_SA);
52b7d2ce 990 if (iph2 == NULL) {
65c25746
A
991 plog(ASL_LEVEL_ERR,
992 "failed to allocate Phase 2 entry.\n");
52b7d2ce
A
993 return -1;
994 }
995
52b7d2ce 996 iph2->side = RESPONDER;
65c25746
A
997 iph2->version = ISAKMP_VERSION_NUMBER_IKEV1;
998 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_START);
52b7d2ce
A
999 iph2->flags = isakmp->flags;
1000 iph2->msgid = isakmp->msgid;
1001 iph2->seq = pk_getseq();
1002 iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
1003 if (iph2->ivm == NULL) {
65c25746 1004 ike_session_delph2(iph2);
52b7d2ce
A
1005 return -1;
1006 }
65c25746 1007 iph2->dst = dupsaddr(iph1->remote); /* XXX should be considered */
52b7d2ce 1008 if (iph2->dst == NULL) {
65c25746 1009 ike_session_delph2(iph2);
52b7d2ce
A
1010 return -1;
1011 }
85f41bec 1012 switch (iph2->dst->ss_family) {
52b7d2ce
A
1013 case AF_INET:
1014#ifndef ENABLE_NATT
1015 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1016#endif
1017 break;
1018#ifdef INET6
1019 case AF_INET6:
1020#ifndef ENABLE_NATT
1021 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1022#endif
1023 break;
1024#endif
1025 default:
65c25746 1026 plog(ASL_LEVEL_ERR,
85f41bec 1027 "invalid family: %d\n", iph2->dst->ss_family);
65c25746 1028 ike_session_delph2(iph2);
52b7d2ce
A
1029 return -1;
1030 }
1031
65c25746 1032 iph2->src = dupsaddr(iph1->local); /* XXX should be considered */
52b7d2ce 1033 if (iph2->src == NULL) {
65c25746 1034 ike_session_delph2(iph2);
52b7d2ce
A
1035 return -1;
1036 }
85f41bec 1037 switch (iph2->src->ss_family) {
52b7d2ce
A
1038 case AF_INET:
1039#ifndef ENABLE_NATT
1040 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1041#endif
1042 break;
1043#ifdef INET6
1044 case AF_INET6:
1045#ifndef ENABLE_NATT
1046 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
1047#endif
1048 break;
1049#endif
1050 default:
65c25746 1051 plog(ASL_LEVEL_ERR,
85f41bec 1052 "invalid family: %d\n", iph2->src->ss_family);
65c25746 1053 ike_session_delph2(iph2);
d1e348cf
A
1054 return -1;
1055 }
1056
65c25746
A
1057 if (ike_session_link_ph2_to_ph1(iph1, iph2))
1058 return -1;
1059 iph2->is_dying = 0;
d06a7ccb 1060 memcpy(&iph2->nat64_prefix, &iph1->nat64_prefix, sizeof(iph2->nat64_prefix));
65c25746
A
1061
1062 plog(ASL_LEVEL_DEBUG, "===\n");
52b7d2ce
A
1063 {
1064 char *a;
1065
85f41bec 1066 a = racoon_strdup(saddr2str((struct sockaddr *)iph2->src));
d1e348cf
A
1067 STRDUP_FATAL(a);
1068
7ebaebe2 1069 plog(ASL_LEVEL_NOTICE,
52b7d2ce 1070 "respond new phase 2 negotiation: %s<=>%s\n",
85f41bec 1071 a, saddr2str((struct sockaddr *)iph2->dst));
52b7d2ce
A
1072 racoon_free(a);
1073 }
1074
1075#ifdef ENABLE_STATS
1076 gettimeofday(&start, NULL);
1077#endif
1078
65c25746 1079 IPSECLOGASLMSG("IPSec Phase 2 started (Initiated by peer).\n");
52b7d2ce 1080
65c25746
A
1081 error = fsm_ikev1_phase2_process_payloads(iph2, msg);
1082 if (error)
1083 return error;
52b7d2ce
A
1084
1085#ifdef ENABLE_VPNCONTROL_PORT
1086 vpncontrol_notify_phase_change(1, FROM_REMOTE, NULL, iph2);
1087#endif
1088
52b7d2ce
A
1089 return 0;
1090}
1091
65c25746
A
1092int
1093ikev1_phase1_established(phase1_handle_t *iph1)
1094{
1095 int spi_cmp;
1096 u_int rekey_lifetime;
1097 int ini_contact = iph1->rmconf->ini_contact;
1098
1099#ifdef ENABLE_STATS
1100 gettimeofday(&iph1->end, NULL);
1101 syslog(LOG_NOTICE, "%s(%s): %8.6f",
1102 "Phase 1", s_isakmp_etype(iph1->etype),
1103 timedelta(&iph1->start, &iph1->end));
1104#endif
1105
1106#ifdef ENABLE_VPNCONTROL_PORT
1107
1108 if (iph1->side == RESPONDER &&
1109 iph1->local->ss_family == AF_INET) {
1110
1111 struct redirect *addr;
1112
1113 LIST_FOREACH(addr, &lcconf->redirect_addresses, chain) {
1114 if (((struct sockaddr_in *)iph1->local)->sin_addr.s_addr == addr->cluster_address) {
1115 vchar_t *raddr = vmalloc(sizeof(u_int32_t));
1116
1117 if (raddr == NULL) {
1118 plog(ASL_LEVEL_ERR,
1119 "failed to send redirect message - memory error.\n");
1120 } else {
1121 memcpy(raddr->v, &addr->redirect_address, sizeof(u_int32_t));
1122 (void)isakmp_info_send_n1(iph1, ISAKMP_NTYPE_LOAD_BALANCE, raddr);
7ebaebe2 1123 plog(ASL_LEVEL_NOTICE, "sent redirect notification - address = %x.\n", ntohl(addr->redirect_address));
65c25746
A
1124 vfree(raddr);
1125 if (addr->force) {
1126 (void)ike_session_update_ph1_ph2tree(iph1);
1127 isakmp_ph1expire(iph1);
1128 }
1129 }
1130 }
1131 return 0;
1132 }
1133 }
1134#endif
1135 /* save created date. */
1136 (void)time(&iph1->created);
1137
1138 /* add to the schedule to expire, and save back pointer. */
1139 iph1->sce = sched_new(iph1->approval->lifetime,
1140 isakmp_ph1expire_stub, iph1);
1141
1142 if (iph1->rmconf->initiate_ph1rekey) {
1143 if (iph1->side == INITIATOR) {
1144 spi_cmp = memcmp(&iph1->index.i_ck, &iph1->index.r_ck, sizeof(iph1->index.i_ck));
1145 if (spi_cmp == 0)
1146 spi_cmp = 1;
1147 } else {
1148 spi_cmp = memcmp(&iph1->index.r_ck, &iph1->index.i_ck, sizeof(iph1->index.r_ck));
1149 if (spi_cmp == 0)
1150 spi_cmp = -1;
1151 }
1152 rekey_lifetime = ike_session_get_rekey_lifetime((spi_cmp > 0),
1153 iph1->approval->lifetime);
1154 if (rekey_lifetime) {
1155 iph1->sce_rekey = sched_new(rekey_lifetime,
1156 isakmp_ph1rekeyexpire_stub,
1157 iph1);
1158 } else {
1159 /* iph1->approval->lifetime is too small (e.g. 1) so why bother?
1160 * LOG ERROR
1161 */
1162 plog(ASL_LEVEL_ERR,
1163 "failed to get rekey timer - lifetime is too small... probably.\n");
1164 }
1165 }
1166
1167#ifdef ENABLE_HYBRID
1168 /* ignore xauth if it is a rekey */
1169 if (!iph1->is_rekey &&
1170 iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
1171 switch(AUTHMETHOD(iph1)) {
1172 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1173 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1174 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1175 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1176 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1177 xauth_sendreq(iph1);
1178 /* XXX Don't process INITIAL_CONTACT */
1179 ini_contact = 0;
1180 break;
1181 default:
1182 break;
1183 }
1184 }
1185#endif
1186#ifdef ENABLE_DPD
1187 /* Schedule the r_u_there.... */
1188 if(iph1->dpd_support && iph1->rmconf->dpd_interval)
1189 isakmp_sched_r_u(iph1, 0);
1190#endif
1191
1192 /* INITIAL-CONTACT processing */
1193 /* ignore initial-contact if it is a rekey */
1194 /* don't send anything if local test mode. */
1195 if (!iph1->is_rekey && !f_local && ini_contact && !ike_session_getcontacted(iph1->remote)) {
1196 /* send INITIAL-CONTACT */
1197 isakmp_info_send_n1(iph1,
1198 ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
1199 /* insert a node into contacted list. */
1200 if (ike_session_inscontacted(iph1->remote) == -1) {
1201 plog(ASL_LEVEL_ERR,
1202 "failed to add contacted list.\n");
1203 /* ignore */
1204 }
1205 }
1206
1207 log_ph1established(iph1);
1208 plog(ASL_LEVEL_DEBUG, "===\n");
1209
1210 ike_session_cleanup_other_established_ph1s(iph1->parent_session, iph1);
1211
1212#ifdef ENABLE_VPNCONTROL_PORT
1213 vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
1214 vpncontrol_notify_peer_resp_ph1(1, iph1);
1215#endif
1216
1217 return 0;
1218}
1219
52b7d2ce
A
1220/*
1221 * parse ISAKMP payloads, without ISAKMP base header.
1222 */
1223vchar_t *
1224isakmp_parsewoh(np0, gen, len)
1225 int np0;
1226 struct isakmp_gen *gen;
1227 int len;
1228{
1229 u_char np = np0 & 0xff;
1230 int tlen, plen;
1231 vchar_t *result;
1232 struct isakmp_parse_t *p, *ep;
1233
65c25746 1234 plog(ASL_LEVEL_DEBUG, "begin.\n");
52b7d2ce
A
1235
1236 /*
1237 * 5 is a magic number, but any value larger than 2 should be fine
1238 * as we do vrealloc() in the following loop.
1239 */
1240 result = vmalloc(sizeof(struct isakmp_parse_t) * 5);
1241 if (result == NULL) {
65c25746 1242 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1243 "failed to get buffer.\n");
1244 return NULL;
85f41bec
A
1245 }
1246 // Wcast-align fix (void*) - result = aligned buffer of struct isakmp_parse_t
1247 p = ALIGNED_CAST(struct isakmp_parse_t *)result->v;
1248 ep = ALIGNED_CAST(struct isakmp_parse_t *)(result->v + result->l - sizeof(*ep));
52b7d2ce
A
1249
1250 tlen = len;
1251
1252 /* parse through general headers */
1253 while (0 < tlen && np != ISAKMP_NPTYPE_NONE) {
1254 if (tlen <= sizeof(struct isakmp_gen)) {
1255 /* don't send information, see isakmp_ident_r1() */
65c25746 1256 plog(ASL_LEVEL_ERR,
7ebaebe2 1257 "isakmp_parsewoh invalid length of payload (1)\n");
52b7d2ce
A
1258 vfree(result);
1259 return NULL;
1260 }
1261
7ebaebe2 1262 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1263 "seen nptype=%u(%s)\n", np, s_isakmp_nptype(np));
1264
1265 p->type = np;
1266 p->len = ntohs(gen->len);
1267 if (p->len < sizeof(struct isakmp_gen) || p->len > tlen) {
7ebaebe2
A
1268 plog(ASL_LEVEL_NOTICE,
1269 "isakmp_parsewoh invalid length of payload (2)\n");
52b7d2ce
A
1270 vfree(result);
1271 return NULL;
1272 }
1273 p->ptr = gen;
1274 p++;
1275 if (ep <= p) {
1276 int off;
1277
85f41bec 1278 off = p - ALIGNED_CAST(struct isakmp_parse_t *)result->v;
52b7d2ce
A
1279 result = vrealloc(result, result->l * 2);
1280 if (result == NULL) {
7ebaebe2 1281 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1282 "failed to realloc buffer.\n");
1283 vfree(result);
1284 return NULL;
1285 }
85f41bec 1286 ep = ALIGNED_CAST(struct isakmp_parse_t *)
52b7d2ce 1287 (result->v + result->l - sizeof(*ep));
85f41bec 1288 p = ALIGNED_CAST(struct isakmp_parse_t *)result->v;
52b7d2ce
A
1289 p += off;
1290 }
1291
1292 np = gen->np;
1293 plen = ntohs(gen->len);
1294 gen = (struct isakmp_gen *)((caddr_t)gen + plen);
1295 tlen -= plen;
1296 }
1297 p->type = ISAKMP_NPTYPE_NONE;
1298 p->len = 0;
1299 p->ptr = NULL;
1300
65c25746 1301 plog(ASL_LEVEL_DEBUG, "succeed.\n");
52b7d2ce
A
1302
1303 return result;
1304}
1305
1306/*
1307 * parse ISAKMP payloads, including ISAKMP base header.
1308 */
1309vchar_t *
1310isakmp_parse(buf)
1311 vchar_t *buf;
1312{
1313 struct isakmp *isakmp = (struct isakmp *)buf->v;
1314 struct isakmp_gen *gen;
1315 int tlen;
1316 vchar_t *result;
1317 u_char np;
1318
1319 np = isakmp->np;
1320 gen = (struct isakmp_gen *)(buf->v + sizeof(*isakmp));
1321 tlen = buf->l - sizeof(struct isakmp);
1322 result = isakmp_parsewoh(np, gen, tlen);
1323
1324 return result;
1325}
1326
d1e348cf 1327int
65c25746 1328isakmp_init(void)
d1e348cf 1329{
d1e348cf 1330
65c25746
A
1331 ike_session_initctdtree();
1332 ike_session_init_recvdpkt();
1333
1334 if (isakmp_open() < 0)
d1e348cf
A
1335 goto err;
1336
1337 return(0);
1338
1339err:
1340 isakmp_close();
1341 return(-1);
1342}
52b7d2ce
A
1343
1344void
1345isakmp_cleanup()
1346{
65c25746
A
1347 ike_session_clear_recvdpkt();
1348 ike_session_clear_contacted();
52b7d2ce
A
1349}
1350
1351/*
1352 * make strings containing i_cookie + r_cookie + msgid
1353 */
1354const char *
1355isakmp_pindex(index, msgid)
1356 const isakmp_index *index;
1357 const u_int32_t msgid;
1358{
1359 static char buf[64];
1360 const u_char *p;
1361 int i, j;
1362
1363 memset(buf, 0, sizeof(buf));
1364
1365 /* copy index */
1366 p = (const u_char *)index;
1367 for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
1368 snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
1369 j += 2;
1370 switch (i) {
1371 case 7:
1372 buf[j++] = ':';
1373 }
1374 }
1375
1376 if (msgid == 0)
1377 return buf;
1378
1379 /* copy msgid */
1380 snprintf((char *)&buf[j], sizeof(buf) - j, ":%08x", ntohs(msgid));
1381
1382 return buf;
1383}
1384
65c25746 1385
52b7d2ce
A
1386/* open ISAKMP sockets. */
1387int
65c25746 1388isakmp_open(void)
52b7d2ce
A
1389{
1390 const int yes = 1;
1391 int ifnum = 0, encap_ifnum = 0;
1392#ifdef INET6
1393 int pktinfo;
1394#endif
1395 struct myaddrs *p;
65c25746
A
1396 int tentative_failures = 0;
1397 int s;
1398
52b7d2ce
A
1399 for (p = lcconf->myaddrs; p; p = p->next) {
1400 if (!p->addr)
1401 continue;
52b7d2ce
A
1402 if (p->sock != -1) {
1403 ifnum++;
1404 if (p->udp_encap)
1405 encap_ifnum++;
1406 continue; // socket already open
1407 }
52b7d2ce
A
1408
1409 /* warn if wildcard address - should we forbid this? */
85f41bec 1410 switch (p->addr->ss_family) {
52b7d2ce
A
1411 case AF_INET:
1412 if (((struct sockaddr_in *)p->addr)->sin_addr.s_addr == 0)
65c25746 1413 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
1414 "listening to wildcard address,"
1415 "broadcast IKE packet may kill you\n");
1416 break;
1417#ifdef INET6
1418 case AF_INET6:
1419 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)p->addr)->sin6_addr))
65c25746 1420 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
1421 "listening to wildcard address, "
1422 "broadcast IKE packet may kill you\n");
1423 break;
1424#endif
1425 default:
65c25746 1426 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1427 "unsupported address family %d\n",
1428 lcconf->default_af);
1429 goto err_and_next;
1430 }
1431
1432#ifdef INET6
85f41bec 1433 if (p->addr->ss_family == AF_INET6 &&
52b7d2ce
A
1434 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)
1435 p->addr)->sin6_addr))
1436 {
7ebaebe2 1437 plog(ASL_LEVEL_NOTICE,
52b7d2ce 1438 "Ignoring multicast address %s\n",
85f41bec 1439 saddr2str((struct sockaddr *)p->addr));
52b7d2ce
A
1440 racoon_free(p->addr);
1441 p->addr = NULL;
1442 continue;
1443 }
1444#endif
1445
85f41bec 1446 if ((p->sock = socket(p->addr->ss_family, SOCK_DGRAM, 0)) < 0) {
65c25746 1447 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1448 "socket (%s)\n", strerror(errno));
1449 goto err_and_next;
1450 }
1451
d1e348cf 1452 if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1)
65c25746 1453 plog(ASL_LEVEL_ERR, "failed to put socket in non-blocking mode\n");
d1e348cf 1454
52b7d2ce 1455 /* receive my interface address on inbound packets. */
85f41bec 1456 switch (p->addr->ss_family) {
d06a7ccb
A
1457 case AF_INET: {
1458 int ifindex = if_nametoindex(p->ifname);
1459 if (ifindex != 0 &&
1460 setsockopt(p->sock, IPPROTO_IP,
1461 IP_BOUND_IF, &ifindex, sizeof(ifindex)) < 0) {
1462 plog(ASL_LEVEL_ERR,
1463 "setsockopt IP_BOUND_IF (%s)\n",
1464 strerror(errno));
1465 goto err_and_next;
1466 }
52b7d2ce 1467 if (setsockopt(p->sock, IPPROTO_IP,
52b7d2ce 1468 IP_RECVDSTADDR,
52b7d2ce 1469 (const void *)&yes, sizeof(yes)) < 0) {
65c25746 1470 plog(ASL_LEVEL_ERR,
d1e348cf
A
1471 "setsockopt IP_RECVDSTADDR (%s)\n",
1472 strerror(errno));
52b7d2ce
A
1473 goto err_and_next;
1474 }
1475 break;
d06a7ccb 1476 }
52b7d2ce 1477#ifdef INET6
d06a7ccb 1478 case AF_INET6: {
52b7d2ce 1479#ifdef INET6_ADVAPI
52b7d2ce 1480 pktinfo = IPV6_RECVPKTINFO;
52b7d2ce
A
1481#else
1482 pktinfo = IPV6_RECVDSTADDR;
1483#endif
d06a7ccb
A
1484 int ifindex = if_nametoindex(p->ifname);
1485 if (ifindex != 0 &&
1486 setsockopt(p->sock, IPPROTO_IPV6,
1487 IPV6_BOUND_IF, &ifindex, sizeof(ifindex)) < 0) {
1488 plog(ASL_LEVEL_ERR,
1489 "setsockopt IPV6_BOUND_IF (%s)\n",
1490 strerror(errno));
1491 goto err_and_next;
1492 }
52b7d2ce
A
1493 if (setsockopt(p->sock, IPPROTO_IPV6, pktinfo,
1494 (const void *)&yes, sizeof(yes)) < 0)
1495 {
65c25746 1496 plog(ASL_LEVEL_ERR,
d1e348cf 1497 "setsockopt IPV6_RECVDSTADDR (%d):%s\n",
52b7d2ce 1498 pktinfo, strerror(errno));
52b7d2ce
A
1499 goto err_and_next;
1500 }
1501 break;
d06a7ccb 1502 }
52b7d2ce
A
1503#endif
1504 }
1505
1506#ifdef IPV6_USE_MIN_MTU
85f41bec 1507 if (p->addr->ss_family == AF_INET6 &&
52b7d2ce
A
1508 setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
1509 (void *)&yes, sizeof(yes)) < 0) {
65c25746 1510 plog(ASL_LEVEL_ERR,
d1e348cf
A
1511 "setsockopt IPV6_USE_MIN_MTU (%s)\n",
1512 strerror(errno));
52b7d2ce
A
1513 return -1;
1514 }
1515#endif
1516
85f41bec 1517 if (setsockopt_bypass(p->sock, p->addr->ss_family) < 0)
52b7d2ce
A
1518 goto err_and_next;
1519
d9c572c0
A
1520 if (setsockopt(p->sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&yes, sizeof(yes)) < 0) {
1521 plog(ASL_LEVEL_ERR, "setsockopt SO_REUSEADDR (%s)\n", strerror(errno));
1522 goto err_and_next;
1523 }
1524
1525 if (setsockopt(p->sock, SOL_SOCKET, SO_REUSEPORT, (const void *)&yes, sizeof(yes)) < 0) {
1526 plog(ASL_LEVEL_ERR, "setsockopt SO_REUSEPORT (%s)\n", strerror(errno));
1527 goto err_and_next;
1528 }
1529
52b7d2ce
A
1530 if (extract_port(p->addr) == PORT_ISAKMP) {
1531 if (setsockopt(p->sock, SOL_SOCKET, SO_NOTIFYCONFLICT,
1532 (void *)&yes, sizeof(yes)) < 0) {
65c25746 1533 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1534 "setsockopt (%s)\n", strerror(errno));
1535 goto err_and_next;
1536 }
1537 }
52b7d2ce 1538
85f41bec 1539 if (bind(p->sock, (struct sockaddr *)p->addr, sysdep_sa_len((struct sockaddr *)p->addr)) < 0) {
e8d9021d 1540 int tmp_errno = errno;
65c25746 1541 plog(ASL_LEVEL_ERR,
52b7d2ce 1542 "failed to bind to address %s (%s).\n",
85f41bec 1543 saddr2str((struct sockaddr *)p->addr), strerror(tmp_errno));
e8d9021d
A
1544#ifdef INET6
1545 // if bind failed b/c of a tentative v6 address, try again later
85f41bec 1546 if (tmp_errno == EADDRNOTAVAIL && p->addr->ss_family == AF_INET6) {
e8d9021d
A
1547 struct in6_ifreq ifr6;
1548
1549 bzero(&ifr6, sizeof(ifr6));
1550 strlcpy(ifr6.ifr_name, p->ifname, sizeof(ifr6.ifr_name));
1551 memcpy(&ifr6.ifr_addr, p->addr, sizeof(ifr6.ifr_addr));
1552 if (ioctl(p->sock, SIOCGIFAFLAG_IN6, &ifr6) >= 0) {
1553 /*
1554 * the tentative flag may have cleared between the bind() and ioctl() calls (i.e due to timing), so
1555 * try infering that it was tentative from ensuring the absense other cases of EADDRNOTAVAIL.
1556 */
1557 if ((ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED | IN6_IFF_DEPRECATED)) == 0) {
1558 // address may have been tentantive... invalidate sock but leave address around for another try later
65c25746 1559 plog(ASL_LEVEL_ERR,
e8d9021d 1560 "failed to bind to address %s: because interface address is/was not ready (flags %x).\n",
85f41bec 1561 saddr2str((struct sockaddr *)p->addr), ifr6.ifr_ifru.ifru_flags6);
e8d9021d
A
1562 close(p->sock);
1563 p->sock = -1;
65c25746 1564 tentative_failures = 1;
e8d9021d
A
1565 continue;
1566 } else {
65c25746 1567 plog(ASL_LEVEL_ERR,
e8d9021d 1568 "failed to bind to address %s: because of interface address error, flags %x.\n",
85f41bec 1569 saddr2str((struct sockaddr *)p->addr), ifr6.ifr_ifru.ifru_flags6);
e8d9021d
A
1570 }
1571 } else {
65c25746 1572 plog(ASL_LEVEL_ERR,
e8d9021d 1573 "failed to bind to address %s: can't read interface address flags.\n",
85f41bec 1574 saddr2str((struct sockaddr *)p->addr));
e8d9021d
A
1575 }
1576 }
1577#endif
52b7d2ce 1578 close(p->sock);
47612122 1579 p->sock = -1;
52b7d2ce
A
1580 goto err_and_next;
1581 }
1582
1583 ifnum++;
52b7d2ce
A
1584 if (p->udp_encap)
1585 encap_ifnum++;
65c25746
A
1586
1587 s = p->sock;
1588
1589 if (p->source != NULL) {
1590 dispatch_source_cancel(p->source);
1591 p->source = NULL;
1592 }
1593 p->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, p->sock, 0, dispatch_get_main_queue());
1594 if (p->source == NULL) {
1595 plog(ASL_LEVEL_ERR, "could not create isakmp socket source.");
1596 return -1;
1597 }
1598 dispatch_source_set_event_handler(p->source,
1599 ^{
1600 isakmp_handler(s);
1601 });
1602 dispatch_source_t the_source = p->source;
1603 dispatch_source_set_cancel_handler(p->source,
1604 ^{
1605 close(s);
1606 dispatch_release(the_source);
1607 }); dispatch_resume(p->source);
1608
7ebaebe2 1609 plog(ASL_LEVEL_NOTICE,
52b7d2ce 1610 "%s used as isakmp port (fd=%d)\n",
85f41bec 1611 saddr2str((struct sockaddr *)p->addr), p->sock);
52b7d2ce
A
1612 continue;
1613
1614 err_and_next:
1615 racoon_free(p->addr);
1616 p->addr = NULL;
65c25746
A
1617 p->sock = -1;
1618 if (! lcconf->autograbaddr && lcconf->strict_address) {
52b7d2ce 1619 return -1;
65c25746
A
1620 }
1621
52b7d2ce
A
1622 continue;
1623 }
1624
1625 if (!ifnum) {
65c25746 1626 plog(ASL_LEVEL_ERR,
52b7d2ce 1627 "no address could be bound.\n");
65c25746 1628
52b7d2ce
A
1629 return -1;
1630 }
1631
1632#ifdef ENABLE_NATT
1633 if (natt_enabled_in_rmconf() && !encap_ifnum) {
65c25746 1634 plog(ASL_LEVEL_WARNING,
52b7d2ce 1635 "NAT-T is enabled in at least one remote{} section,\n");
65c25746 1636 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
1637 "but no 'isakmp_natt' address was specified!\n");
1638 }
1639#endif
1640
65c25746
A
1641 if (tentative_failures)
1642 sched_new(5, update_myaddrs, NULL);
1643
52b7d2ce
A
1644 return 0;
1645}
1646
65c25746
A
1647void
1648isakmp_suspend_sockets()
1649{
1650 struct myaddrs *p;
1651
1652 for (p = lcconf->myaddrs; p; p = p->next) {
1653 if (p->source)
1654 dispatch_suspend(p->source);
1655 }
1656}
1657
52b7d2ce
A
1658void
1659isakmp_close()
1660{
1661 isakmp_close_sockets();
1662 clear_myaddr();
1663}
1664
1665void
1666isakmp_close_sockets()
1667{
1668 struct myaddrs *p;
1669
1670 for (p = lcconf->myaddrs; p; p = p->next) {
1671
1672 if (!p->addr)
1673 continue;
1674
65c25746
A
1675 if (p->source) {
1676 dispatch_source_cancel(p->source);
1677 p->source = NULL;
1678 p->in_use = 0;
1679 p->sock = -1;
1680 }
52b7d2ce 1681 }
52b7d2ce
A
1682}
1683
1684
1685// close sockets for addresses that have gone away
1686void
1687isakmp_close_unused()
1688{
1689 struct myaddrs *p, *next, **prev;
1690
1691 prev = &(lcconf->myaddrs);
1692 for (p = lcconf->myaddrs; p; p = next) {
1693 next = p->next;
1694 if (p->in_use == 0) { // not in use ?
65c25746
A
1695 if (p->source) {
1696 dispatch_source_cancel(p->source);
1697 p->source = NULL;
1698 }
1699 *prev = p->next;
d1e348cf 1700 delmyaddr(p);
52b7d2ce 1701 } else
65c25746 1702 prev = &(p->next);
52b7d2ce
A
1703 }
1704}
1705
1706int
1707isakmp_send(iph1, sbuf)
65c25746 1708 phase1_handle_t *iph1;
52b7d2ce
A
1709 vchar_t *sbuf;
1710{
1711 int len = 0;
1712 int s;
1713 vchar_t *vbuf = NULL;
d9c572c0 1714
52b7d2ce
A
1715#ifdef ENABLE_NATT
1716 size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0;
1717
1718#ifdef ENABLE_FRAG
1719 /*
1720 * Do not add the non ESP marker for a packet that will
1721 * be fragmented. The non ESP marker should appear in
1722 * all fragment's packets, but not in the fragmented packet
1723 */
1724 if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN)
1725 extralen = 0;
1726#endif
1727 if (extralen)
65c25746 1728 plog (ASL_LEVEL_DEBUG, "Adding NON-ESP marker\n");
52b7d2ce
A
1729
1730 /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
1731 must added just before the packet itself. For this we must
1732 allocate a new buffer and release it at the end. */
1733 if (extralen) {
d1e348cf 1734 if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) {
65c25746 1735 plog(ASL_LEVEL_ERR,
d1e348cf
A
1736 "vbuf allocation failed\n");
1737 return -1;
1738 }
85f41bec 1739 *ALIGNED_CAST(u_int32_t *)vbuf->v = 0;
52b7d2ce
A
1740 memcpy (vbuf->v + extralen, sbuf->v, sbuf->l);
1741 sbuf = vbuf;
1742 }
1743#endif
1744
1745 /* select the socket to be sent */
85f41bec 1746 s = getsockmyaddr((struct sockaddr *)iph1->local);
52b7d2ce
A
1747 if (s == -1){
1748 if ( vbuf != NULL )
1749 vfree(vbuf);
1750 return -1;
1751 }
1752
65c25746 1753 plog (ASL_LEVEL_DEBUG, "%zu bytes %s\n", sbuf->l,
85f41bec 1754 saddr2str_fromto("from %s to %s", (struct sockaddr *)iph1->local, (struct sockaddr *)iph1->remote));
52b7d2ce
A
1755
1756#ifdef ENABLE_FRAG
1757 if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) {
1758 if (isakmp_sendfrags(iph1, sbuf) == -1) {
65c25746 1759 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1760 "isakmp_sendfrags failed\n");
1761 if ( vbuf != NULL )
1762 vfree(vbuf);
1763 return -1;
1764 }
1765 } else
1766#endif
1767 {
1768 len = sendfromto(s, sbuf->v, sbuf->l,
1769 iph1->local, iph1->remote, lcconf->count_persend);
1770 if (len == -1) {
65c25746 1771 plog(ASL_LEVEL_ERR, "sendfromto failed\n");
52b7d2ce
A
1772 if ( vbuf != NULL )
1773 vfree(vbuf);
1774 return -1;
1775 }
1776 }
1777
1778 if ( vbuf != NULL )
1779 vfree(vbuf);
1780
1781 return 0;
1782}
1783
1784/* called from scheduler */
1785void
1786isakmp_ph1resend_stub(p)
1787 void *p;
1788{
65c25746 1789 phase1_handle_t *iph1;
d1e348cf 1790
65c25746 1791 iph1=(phase1_handle_t *)p;
d1e348cf 1792 if(isakmp_ph1resend(iph1) < 0){
65c25746 1793 if(iph1->scr != 0){
d1e348cf
A
1794 /* Should not happen...
1795 */
65c25746 1796 SCHED_KILL(iph1->scr);
d1e348cf
A
1797 }
1798
65c25746 1799 ike_session_unlink_phase1(iph1);
d1e348cf 1800 }
52b7d2ce
A
1801}
1802
1803int
1804isakmp_ph1resend(iph1)
65c25746 1805 phase1_handle_t *iph1;
52b7d2ce 1806{
e8d9021d 1807 time_t retry_interval;
65c25746 1808
e8d9021d
A
1809 // make sure there is a buffer to send
1810 // isakmp_plist_set_all() could have returned NULL
1811 if (iph1->sendbuf == NULL)
1812 return -1;
1813
d1e348cf
A
1814 /* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function
1815 */
1816 if (iph1->retry_counter <= 0) {
6b88cae0 1817 plog(ASL_LEVEL_ERR,
65c25746 1818 "Phase 1 negotiation failed due to time up. %s\n",
52b7d2ce 1819 isakmp_pindex(&iph1->index, iph1->msgid));
d1e348cf
A
1820 if (iph1->side == INITIATOR && iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client) {
1821 /* to get around a bug on the peer, in which rekeys to port 4500 are dropped */
1822 if (isakmp_ph1rekeyretry(iph1) == 0)
1823 return 0;
1824 }
52b7d2ce 1825 return -1;
e8d9021d
A
1826 } else {
1827 ike_session_ph1_retransmits(iph1);
52b7d2ce
A
1828 }
1829
1830 if (isakmp_send(iph1, iph1->sendbuf) < 0){
65c25746
A
1831 plog(ASL_LEVEL_ERR,
1832 "Phase 1 negotiation failed due to send error. %s\n",
d1e348cf 1833 isakmp_pindex(&iph1->index, iph1->msgid));
52b7d2ce
A
1834 return -1;
1835 }
1836
7ebaebe2 1837 plog(ASL_LEVEL_NOTICE,
65c25746 1838 "Resend Phase 1 packet %s\n",
52b7d2ce
A
1839 isakmp_pindex(&iph1->index, iph1->msgid));
1840
1841 iph1->retry_counter--;
65c25746 1842 retry_interval = ike_session_get_exp_retx_interval((iph1->rmconf->retry_counter - iph1->retry_counter),
e8d9021d
A
1843 iph1->rmconf->retry_interval);
1844 iph1->scr = sched_new(retry_interval,
52b7d2ce
A
1845 isakmp_ph1resend_stub, iph1);
1846
1847 return 0;
1848}
1849
1850/* called from scheduler */
1851void
1852isakmp_ph2resend_stub(p)
1853 void *p;
1854{
65c25746 1855 phase2_handle_t *iph2;
d1e348cf 1856
65c25746 1857 iph2=(phase2_handle_t *)p;
52b7d2ce 1858
d1e348cf 1859 if(isakmp_ph2resend(iph2) < 0){
65c25746 1860 ike_session_unlink_phase2(iph2);
d1e348cf 1861 }
52b7d2ce
A
1862}
1863
1864int
1865isakmp_ph2resend(iph2)
65c25746 1866 phase2_handle_t *iph2;
52b7d2ce 1867{
e8d9021d
A
1868 time_t retry_interval;
1869
d1e348cf
A
1870 /* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function
1871 */
1872 //%%% BUG FIX - related to commit bit usage - crash happened here
1873 if (iph2->ph1 == 0) {
65c25746
A
1874 plog(ASL_LEVEL_ERR,
1875 "Internal error - attempt to re-send Phase 2 with no Phase 1 bound.\n");
d1e348cf
A
1876 return -1;
1877 }
65c25746
A
1878
1879 if (FSM_STATE_IS_EXPIRED(iph2->ph1->status)){
65c25746
A
1880 plog(ASL_LEVEL_ERR,
1881 "Phase 2 negotiation failed due to Phase 1 expired. %s\n",
d1e348cf
A
1882 isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1883 return -1;
1884 }
1885
1886 if (iph2->retry_counter <= 0) {
65c25746
A
1887 plog(ASL_LEVEL_ERR,
1888 "Phase 2 negotiation failed due to time up. %s\n",
52b7d2ce 1889 isakmp_pindex(&iph2->ph1->index, iph2->msgid));
52b7d2ce 1890 return -1;
fce29cd9
A
1891 } else {
1892 ike_session_ph2_retransmits(iph2);
52b7d2ce
A
1893 }
1894
d1e348cf 1895 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){
6b88cae0 1896 plog(ASL_LEVEL_ERR,
65c25746 1897 "Phase 2 negotiation failed due to send error. %s\n",
d1e348cf 1898 isakmp_pindex(&iph2->ph1->index, iph2->msgid));
52b7d2ce 1899
52b7d2ce 1900 return -1;
d1e348cf 1901 }
52b7d2ce 1902
7ebaebe2 1903 plog(ASL_LEVEL_NOTICE,
65c25746 1904 "Resend Phase 2 packet %s\n",
52b7d2ce
A
1905 isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1906
1907 iph2->retry_counter--;
65c25746 1908 retry_interval = ike_session_get_exp_retx_interval((iph2->ph1->rmconf->retry_counter - iph2->ph1->retry_counter),
e8d9021d
A
1909 iph2->ph1->rmconf->retry_interval);
1910 iph2->scr = sched_new(retry_interval,
52b7d2ce
A
1911 isakmp_ph2resend_stub, iph2);
1912
d1e348cf
A
1913#ifdef ENABLE_DPD
1914 if (iph2->scr) {
1915 isakmp_reschedule_info_monitor_if_pending(iph2->ph1,
65c25746 1916 "Phase 2 packets sent to peer: retransmit timer armed");
d1e348cf
A
1917 }
1918#endif /* DPD */
1919
52b7d2ce
A
1920 return 0;
1921}
1922
1923/* called from scheduler */
1924void
1925isakmp_ph1expire_stub(p)
1926 void *p;
1927{
1928
65c25746 1929 isakmp_ph1expire((phase1_handle_t *)p);
52b7d2ce
A
1930}
1931
1932void
1933isakmp_ph1expire(iph1)
65c25746 1934 phase1_handle_t *iph1;
52b7d2ce
A
1935{
1936 char *src, *dst;
65c25746 1937 phase1_handle_t *new_iph1;
52b7d2ce
A
1938
1939 SCHED_KILL(iph1->sce);
d1e348cf
A
1940#ifdef ENABLE_DPD
1941 SCHED_KILL(iph1->dpd_r_u);
1942#endif
52b7d2ce 1943
65c25746 1944 if(!FSM_STATE_IS_EXPIRED(iph1->status)){
85f41bec
A
1945 src = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
1946 dst = racoon_strdup(saddr2str((struct sockaddr *)iph1->remote));
d1e348cf
A
1947 STRDUP_FATAL(src);
1948 STRDUP_FATAL(dst);
1949
7ebaebe2 1950 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1951 "ISAKMP-SA expired %s-%s spi:%s\n",
1952 src, dst,
1953 isakmp_pindex(&iph1->index, 0));
1954 racoon_free(src);
1955 racoon_free(dst);
65c25746
A
1956 fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED);
1957 new_iph1 = ike_session_update_ph1_ph2tree(iph1);
52b7d2ce
A
1958 }
1959
1960 /*
1961 * the phase1 deletion is postponed until there is no phase2.
1962 */
65c25746 1963 if (LIST_FIRST(&iph1->bound_ph2tree) != NULL) {
52b7d2ce
A
1964 iph1->sce = sched_new(1, isakmp_ph1expire_stub, iph1);
1965 return;
1966 }
1967
1968 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
1969}
1970
d1e348cf
A
1971/* called from scheduler */
1972void
1973isakmp_ph1rekeyexpire_stub(p)
1974void *p;
1975{
1976
65c25746 1977 isakmp_ph1rekeyexpire((phase1_handle_t *)p, FALSE);
d1e348cf
A
1978}
1979
1980void
fce29cd9 1981isakmp_ph1rekeyexpire(iph1, ignore_sess_drop_policy)
65c25746 1982phase1_handle_t *iph1;
fce29cd9 1983int ignore_sess_drop_policy;
d1e348cf
A
1984{
1985 char *src, *dst;
1986 struct remoteconf *rmconf;
1987
1988 SCHED_KILL(iph1->sce_rekey);
1989
65c25746
A
1990 // We are going to start the rekey. Let's fire off the
1991 // phase1 expiration timer if it is not done yet.
1992 if (!iph1->sce && iph1->approval->lifetimegap) {
1993 iph1->sce = sched_new(iph1->approval->lifetimegap,
1994 isakmp_ph1expire_stub, iph1);
1995 }
1996
d1e348cf 1997 // early exit if iph2->sce == NULL, iph2 isn't established or if entire session is going down
65c25746
A
1998 if (iph1->sce == 0 ||
1999 !FSM_STATE_IS_ESTABLISHED(iph1->status) ||
d1e348cf
A
2000 iph1->is_dying) {
2001 return;
2002 }
2003
85f41bec
A
2004 src = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
2005 dst = racoon_strdup(saddr2str((struct sockaddr *)iph1->remote));
d1e348cf
A
2006 STRDUP_FATAL(src);
2007 STRDUP_FATAL(dst);
2008
7ebaebe2 2009 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
2010 "ISAKMP-SA rekey-timer expired %s-%s spi:%s\n",
2011 src, dst,
2012 isakmp_pindex(&iph1->index, 0));
2013 racoon_free(src);
2014 racoon_free(dst);
d9c572c0
A
2015
2016 if (!ignore_sess_drop_policy && ike_session_drop_rekey(iph1->parent_session, IKE_SESSION_REKEY_TYPE_PH1)) {
2017 return;
fce29cd9
A
2018 }
2019
d1e348cf
A
2020 // exit if there is another ph1 that is established (with a pending rekey timer)
2021 if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) {
7ebaebe2 2022 plog(ASL_LEVEL_NOTICE,
65c25746 2023 "Request for ISAKMP-SA rekey was ignored "
d1e348cf
A
2024 "due to another established ph1.\n");
2025 return;
2026 }
2027
2028 // if there is another ph1 that is negotiating, postpone this rekey for a few seconds later
2029 if (ike_session_has_other_negoing_ph1(iph1->parent_session, iph1)) {
65c25746 2030 plog(ASL_LEVEL_DEBUG, "Reschedule Phase 1 rekey.\n");
d1e348cf
A
2031 iph1->sce_rekey = sched_new(1,
2032 isakmp_ph1rekeyexpire_stub,
2033 iph1);
2034 return;
2035 }
2036
65c25746
A
2037 // get rmconf to initiate rekey with
2038 rmconf = iph1->rmconf;
2039 if (!rmconf)
2040 rmconf = getrmconf(iph1->remote);
2041
2042 if (rmconf) {
2043 /* begin quick mode */
7ebaebe2 2044 plog(ASL_LEVEL_NOTICE, "Begin Phase 1 rekey.\n");
d1e348cf
A
2045
2046 /* start phase 1 negotiation as a initiator. */
d06a7ccb 2047 if (ikev1_ph1begin_i(iph1->parent_session, rmconf, iph1->remote, iph1->local, 0, &iph1->nat64_prefix) < 0) {
7ebaebe2 2048 plog(ASL_LEVEL_NOTICE, "Phase 1 rekey Failed.\n");
d1e348cf 2049 }
d9c572c0 2050 iph1->is_rekey = TRUE;
d1e348cf 2051 } else {
65c25746 2052 plog(ASL_LEVEL_ERR,
d1e348cf 2053 "Phase1 rekey failed: no configuration found for %s.\n",
85f41bec 2054 saddrwop2str((struct sockaddr *)iph1->remote));
d1e348cf
A
2055 }
2056}
2057
2058int
2059isakmp_ph1rekeyretry(iph1)
65c25746 2060phase1_handle_t *iph1;
d1e348cf
A
2061{
2062 char *src, *dst;
2063 struct remoteconf *rmconf;
2064
2065 // this code path is meant for floated ph1 rekeys that are failing on the first message
65c25746
A
2066 if (iph1->sce != 0 ||
2067 iph1->sce_rekey != 0 ||
2068 ((iph1->status != IKEV1_STATE_IDENT_I_MSG1SENT &&
2069 iph1->status != IKEV1_STATE_AGG_I_MSG1SENT)
2070 || ((iph1->natt_flags & NAT_PORTS_CHANGED) == 0))
2071 || (extract_port(iph1->local) != PORT_ISAKMP_NATT && extract_port(iph1->remote) != PORT_ISAKMP_NATT)
2072 || iph1->is_dying) {
d1e348cf
A
2073 return -1;
2074 }
2075
85f41bec
A
2076 src = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
2077 dst = racoon_strdup(saddr2str((struct sockaddr *)iph1->remote));
d1e348cf
A
2078 STRDUP_FATAL(src);
2079 STRDUP_FATAL(dst);
2080
7ebaebe2 2081 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
2082 "ISAKMP-SA rekey failed... retrying %s-%s spi:%s\n",
2083 src, dst,
2084 isakmp_pindex(&iph1->index, 0));
2085 racoon_free(src);
2086 racoon_free(dst);
2087
e8d9021d 2088 if (ike_session_drop_rekey(iph1->parent_session, IKE_SESSION_REKEY_TYPE_PH1)) {
7ebaebe2 2089 plog(ASL_LEVEL_NOTICE,
e8d9021d
A
2090 "request for ISAKMP-SA rekey was ignored "
2091 "due to idleness.\n");
2092 return 0;
2093 }
2094
d1e348cf
A
2095 // exit if there is another ph1 that is established (with a pending rekey timer)
2096 if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) {
7ebaebe2 2097 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
2098 "request to retry ISAKMP-SA rekey was ignored "
2099 "due to another established ph1.\n");
2100 return -1;
2101 }
2102
2103 // some servers don't like respond to 4500 for rekeys... try accomodate them
2104 if (extract_port(iph1->local) == PORT_ISAKMP_NATT) {
2105 set_port(iph1->local, PORT_ISAKMP);
2106 }
2107 if (extract_port(iph1->remote) == PORT_ISAKMP_NATT) {
2108 set_port(iph1->remote, PORT_ISAKMP);
2109 }
2110 iph1->natt_flags &= ~NAT_PORTS_CHANGED;
2111 rmconf = getrmconf(iph1->remote);
2112 if (rmconf) {
2113 /* begin quick mode */
7ebaebe2 2114 plog(ASL_LEVEL_NOTICE, "begin Phase 1 rekey retry.\n");
d1e348cf
A
2115
2116 /* start phase 1 negotiation as a initiator. */
d06a7ccb 2117 if (ikev1_ph1begin_i(iph1->parent_session, rmconf, iph1->remote, iph1->local, 0, &iph1->nat64_prefix) < 0) {
7ebaebe2 2118 plog(ASL_LEVEL_NOTICE, "Phase 1 rekey retry Failed.\n");
d1e348cf
A
2119 return -1;
2120 }
65c25746 2121 iph1->is_rekey = TRUE;
d1e348cf 2122 } else {
65c25746
A
2123 plog(ASL_LEVEL_ERR,
2124 "Phase 1 rekey retry failed: no configuration found for %s.\n",
85f41bec 2125 saddrwop2str((struct sockaddr *)iph1->remote));
d1e348cf
A
2126 return -1;
2127 }
2128 return 0;
2129}
2130
52b7d2ce
A
2131/* called from scheduler */
2132void
2133isakmp_ph1delete_stub(p)
2134 void *p;
2135{
2136
65c25746 2137 isakmp_ph1delete((phase1_handle_t *)p);
52b7d2ce
A
2138}
2139
2140void
2141isakmp_ph1delete(iph1)
65c25746 2142 phase1_handle_t *iph1;
52b7d2ce
A
2143{
2144 char *src, *dst;
2145
d1e348cf
A
2146 SCHED_KILL(iph1->sce);
2147 SCHED_KILL(iph1->sce_rekey);
2148#ifdef ENABLE_DPD
2149 SCHED_KILL(iph1->dpd_r_u);
2150#endif
52b7d2ce 2151
65c25746 2152 if (LIST_FIRST(&iph1->bound_ph2tree) != NULL) {
52b7d2ce
A
2153 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
2154 return;
2155 }
65c25746 2156
d1e348cf
A
2157 isakmp_info_send_d1(iph1);
2158
52b7d2ce
A
2159 /* don't re-negosiation when the phase 1 SA expires. */
2160
85f41bec
A
2161 src = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
2162 dst = racoon_strdup(saddr2str((struct sockaddr *)iph1->remote));
d1e348cf
A
2163 STRDUP_FATAL(src);
2164 STRDUP_FATAL(dst);
2165
7ebaebe2
A
2166 plog(ASL_LEVEL_NOTICE,
2167 "ISAKMP-SA deleted spi:%s\n",
2168 isakmp_pindex(&iph1->index, 0));
2169 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
2170 "ISAKMP-SA deleted %s-%s spi:%s\n",
2171 src, dst, isakmp_pindex(&iph1->index, 0));
52b7d2ce
A
2172 racoon_free(src);
2173 racoon_free(dst);
65c25746
A
2174
2175 ike_session_unlink_phase1(iph1);
52b7d2ce
A
2176
2177 return;
2178}
2179
2180/* called from scheduler.
2181 * this function will call only isakmp_ph2delete().
2182 * phase 2 handler remain forever if kernel doesn't cry a expire of phase 2 SA
2183 * by something cause. That's why this function is called after phase 2 SA
2184 * expires in the userland.
2185 */
2186void
2187isakmp_ph2expire_stub(p)
2188 void *p;
2189{
2190
65c25746 2191 isakmp_ph2expire((phase2_handle_t *)p);
52b7d2ce
A
2192}
2193
2194void
2195isakmp_ph2expire(iph2)
65c25746 2196 phase2_handle_t *iph2;
52b7d2ce
A
2197{
2198 char *src, *dst;
2199
65c25746 2200 if (FSM_STATE_IS_EXPIRED(iph2->status)) {
80318cb7
A
2201 return;
2202 }
2203
52b7d2ce
A
2204 SCHED_KILL(iph2->sce);
2205
85f41bec
A
2206 src = racoon_strdup(saddrwop2str((struct sockaddr *)iph2->src));
2207 dst = racoon_strdup(saddrwop2str((struct sockaddr *)iph2->dst));
d1e348cf
A
2208 STRDUP_FATAL(src);
2209 STRDUP_FATAL(dst);
2210
7ebaebe2 2211 plog(ASL_LEVEL_NOTICE,
65c25746 2212 "Phase 2 sa expired %s-%s\n", src, dst);
52b7d2ce
A
2213 racoon_free(src);
2214 racoon_free(dst);
2215
d1e348cf 2216 // delete outgoing SAs
65c25746 2217 if (FSM_STATE_IS_ESTABLISHED(iph2->status) && iph2->approval) {
d1e348cf
A
2218 struct saproto *pr;
2219
2220 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
2221 if (pr->ok) {
2222 pfkey_send_delete(lcconf->sock_pfkey,
65c25746
A
2223 ipsecdoi2pfkey_proto(pr->proto_id),
2224 IPSEC_MODE_ANY,
2225 iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */);
d9c572c0 2226 }
d1e348cf
A
2227 }
2228 }
65c25746
A
2229 if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1)
2230 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED);
52b7d2ce 2231 iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2);
d9c572c0 2232
52b7d2ce
A
2233 return;
2234}
2235
2236/* called from scheduler */
2237void
2238isakmp_ph2delete_stub(p)
2239 void *p;
2240{
2241
65c25746 2242 isakmp_ph2delete((phase2_handle_t *)p);
52b7d2ce
A
2243}
2244
2245void
2246isakmp_ph2delete(iph2)
65c25746 2247 phase2_handle_t *iph2;
52b7d2ce
A
2248{
2249 char *src, *dst;
2250
2251 SCHED_KILL(iph2->sce);
2252
85f41bec
A
2253 src = racoon_strdup(saddrwop2str((struct sockaddr *)iph2->src));
2254 dst = racoon_strdup(saddrwop2str((struct sockaddr *)iph2->dst));
d1e348cf
A
2255 STRDUP_FATAL(src);
2256 STRDUP_FATAL(dst);
2257
7ebaebe2 2258 plog(ASL_LEVEL_NOTICE,
65c25746 2259 "Phase 2 sa deleted %s-%s\n", src, dst);
52b7d2ce
A
2260 racoon_free(src);
2261 racoon_free(dst);
2262
65c25746 2263 ike_session_unlink_phase2(iph2);
52b7d2ce
A
2264
2265 return;
2266}
2267
2268/* \f%%%
2269 * Interface between PF_KEYv2 and ISAKMP
2270 */
2271/*
2272 * receive ACQUIRE from kernel, and begin either phase1 or phase2.
2273 * if phase1 has been finished, begin phase2.
2274 */
2275int
65c25746 2276isakmp_post_acquire(phase2_handle_t *iph2)
52b7d2ce
A
2277{
2278 struct remoteconf *rmconf;
65c25746 2279 phase1_handle_t *iph1 = NULL;
d1e348cf 2280
65c25746 2281 plog(ASL_LEVEL_DEBUG, "In post_acquire\n");
52b7d2ce
A
2282
2283 /* search appropreate configuration with masking port. */
2284 rmconf = getrmconf(iph2->dst);
2285 if (rmconf == NULL) {
65c25746
A
2286 plog(ASL_LEVEL_ERR,
2287 "No configuration found for %s.\n",
85f41bec 2288 saddrwop2str((struct sockaddr *)iph2->dst));
52b7d2ce
A
2289 return -1;
2290 }
52b7d2ce
A
2291 /* if passive mode, ignore the acquire message */
2292 if (rmconf->passive) {
7ebaebe2 2293 plog(ASL_LEVEL_NOTICE,
65c25746 2294 "Because of passive mode, ignore the acquire message for %s.\n",
85f41bec 2295 saddrwop2str((struct sockaddr *)iph2->dst));
52b7d2ce
A
2296 return 0;
2297 }
2298
65c25746
A
2299
2300 // what if there is another ph2 that is negotiating
2301 if (ike_session_has_other_negoing_ph2(iph2->parent_session, iph2)) {
2302 // TODO: postpone this rekey for a second later
7ebaebe2 2303 plog(ASL_LEVEL_NOTICE,
65c25746
A
2304 "Request for establishing IPsec-SA was ignored due to another negoing ph2.\n");
2305 return -1;
2306 }
d1e348cf
A
2307
2308 // if this is a phase2 rekeys (the policy may not have the current port number).
2309 // so, use the appropriate ports.
2310 if (iph2->is_rekey) {
2311 ike_session_update_ph2_ports(iph2);
2312 }
65c25746
A
2313 if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1)
2314 iph1 = ike_session_update_ph2_ph1bind(iph2);
d1e348cf 2315
65c25746 2316 /* no IKE-SA found. */
52b7d2ce 2317 if (iph1 == NULL) {
52b7d2ce 2318 iph2->retry_checkph1 = lcconf->retry_checkph1;
65c25746 2319
52b7d2ce 2320 /* start phase 1 negotiation as a initiator. */
d9c572c0
A
2321 sched_new(1, isakmp_chkph1there_stub, iph2);
2322
7ebaebe2 2323 plog(ASL_LEVEL_NOTICE,
d9c572c0
A
2324 "IPsec-SA request for %s queued due to no Phase 1 found.\n",
2325 saddrwop2str((struct sockaddr *)iph2->dst));
2326
2327 // exit if there is another ph1 that is established (with a pending rekey timer)
2328 if (ike_session_has_negoing_ph1(iph2->parent_session)) {
7ebaebe2 2329 plog(ASL_LEVEL_NOTICE,
d9c572c0
A
2330 "Request for Phase 1 was ignored due to another negotiating Phase 1.\n");
2331 return 0;
2332 }
2333
d06a7ccb 2334 if (ikev1_ph1begin_i(iph2->parent_session, rmconf, iph2->dst, iph2->src, 0, &iph2->nat64_prefix) < 0) {
7ebaebe2 2335 plog(ASL_LEVEL_NOTICE,
d9c572c0 2336 "Request for Phase 1 failed. Will try later.\n");
52b7d2ce 2337 }
52b7d2ce
A
2338 return 0;
2339 /*NOTREACHED*/
2340 }
2341
2342 /* found ISAKMP-SA, but on negotiation. */
65c25746 2343 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
52b7d2ce
A
2344 iph2->retry_checkph1 = lcconf->retry_checkph1;
2345 sched_new(1, isakmp_chkph1there_stub, iph2);
7ebaebe2 2346 plog(ASL_LEVEL_NOTICE,
65c25746 2347 "Request for establishing IPsec-SA was queued due to no phase1 found.\n");
52b7d2ce
A
2348 return 0;
2349 /*NOTREACHED*/
2350 }
2351
2352 /* found established ISAKMP-SA */
52b7d2ce
A
2353
2354 /* found ISAKMP-SA. */
52b7d2ce
A
2355
2356 /* begin quick mode */
7ebaebe2 2357 plog(ASL_LEVEL_NOTICE, "Begin QUICK mode.\n");
d9c572c0
A
2358 if (ikev1_ph2begin_i(iph1, iph2))
2359 return -1;
52b7d2ce
A
2360 return 0;
2361}
2362
2363/*
2364 * receive GETSPI from kernel.
2365 */
2366int
65c25746 2367isakmp_post_getspi(phase2_handle_t *iph2)
52b7d2ce
A
2368{
2369#ifdef ENABLE_STATS
2370 struct timeval start, end;
2371#endif
65c25746
A
2372 int error = 0;
2373
2374 /* don't process it because there is no suitable phase1-sa. */
2375 if (FSM_STATE_IS_EXPIRED(iph2->ph1->status)) {
2376 plog(ASL_LEVEL_ERR,
2377 "the negotiation is stopped, "
2378 "because there is no suitable ISAKMP-SA.\n");
2379 return -1;
2380 }
2381 fsm_set_state(&iph2->status, iph2->side == INITIATOR ?
2382 IKEV1_STATE_QUICK_I_GETSPIDONE : IKEV1_STATE_QUICK_R_GETSPIDONE);
2383
52b7d2ce 2384#ifdef ENABLE_STATS
65c25746
A
2385 gettimeofday(&start, NULL);
2386#endif
2387 switch (iph2->side) {
2388 case INITIATOR:
2389 error = quick_i1send(iph2, NULL);
2390 break;
2391 case RESPONDER:
2392 error = quick_r2send(iph2, NULL);
2393 break;
2394 }
2395
2396 if (error) //%%%%%%%% log something ???
52b7d2ce
A
2397 return -1;
2398#ifdef ENABLE_STATS
2399 gettimeofday(&end, NULL);
65c25746
A
2400 plog(ASL_LEVEL_NOTICE, "%s(%s): %8.6f",
2401 "Phase 2",
52b7d2ce
A
2402 s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
2403 timedelta(&start, &end));
2404#endif
2405
2406 return 0;
2407}
2408
2409/* called by scheduler */
2410void
2411isakmp_chkph1there_stub(p)
2412 void *p;
2413{
65c25746 2414 isakmp_chkph1there((phase2_handle_t *)p);
52b7d2ce
A
2415}
2416
2417void
2418isakmp_chkph1there(iph2)
65c25746 2419 phase2_handle_t *iph2;
52b7d2ce 2420{
65c25746 2421 phase1_handle_t *iph1;
52b7d2ce 2422
65c25746
A
2423 if ((iph2->version == ISAKMP_VERSION_NUMBER_IKEV1 && iph2->status != IKEV1_STATE_QUICK_I_START) ||
2424 iph2->is_dying) {
7ebaebe2 2425 plog(ASL_LEVEL_NOTICE, "CHKPH1THERE: ph2 handle has advanced too far (status %d, START %d, dying %d)... ignoring\n", iph2->status, IKEV1_STATE_QUICK_I_START, iph2->is_dying);
869d26af
A
2426 return;
2427 }
2428
52b7d2ce 2429 iph2->retry_checkph1--;
65c25746
A
2430
2431 if (iph2->retry_checkph1 < 0 /* %%%%||
2432 ike_session_verify_ph2_parent_session(iph2) */) {
d1e348cf 2433 if (iph2->retry_checkph1 < 0) {
65c25746
A
2434 plog(ASL_LEVEL_ERR,
2435 "Phase 2 negotiation failed "
2436 "due to time up waiting for Phase 1. %s\n",
d1e348cf
A
2437 sadbsecas2str(iph2->dst, iph2->src,
2438 iph2->satype, 0, 0));
2439 } else {
65c25746
A
2440 plog(ASL_LEVEL_ERR,
2441 "Phase 2 negotiation failed "
d1e348cf
A
2442 "due to invalid parent session. %s\n",
2443 sadbsecas2str(iph2->dst, iph2->src,
2444 iph2->satype, 0, 0));
2445 }
7ebaebe2 2446 plog(ASL_LEVEL_NOTICE,
65c25746 2447 "delete Phase 2 handler.\n");
52b7d2ce
A
2448
2449 /* send acquire to kernel as error */
2450 pk_sendeacquire(iph2);
65c25746 2451 ike_session_unlink_phase2(iph2);
52b7d2ce
A
2452 return;
2453 }
2454
d1e348cf 2455 iph1 = ike_session_update_ph2_ph1bind(iph2);
52b7d2ce
A
2456
2457 /* XXX Even if ph1 as responder is there, should we not start
2458 * phase 2 negotiation ? */
2459 if (iph1 != NULL
65c25746 2460 && FSM_STATE_IS_ESTABLISHED(iph1->status)) {
52b7d2ce 2461 /* found isakmp-sa */
d1e348cf 2462
65c25746
A
2463 plog(ASL_LEVEL_DEBUG, "CHKPH1THERE: got a ph1 handler, setting ports.\n");
2464 plog(ASL_LEVEL_DEBUG, "iph1->local: %s\n", saddr2str((struct sockaddr *)iph1->local));
2465 plog(ASL_LEVEL_DEBUG, "iph1->remote: %s\n", saddr2str((struct sockaddr *)iph1->remote));
2466 plog(ASL_LEVEL_DEBUG, "before:\n");
2467 plog(ASL_LEVEL_DEBUG, "src: %s\n", saddr2str((struct sockaddr *)iph2->src));
2468 plog(ASL_LEVEL_DEBUG, "dst: %s\n", saddr2str((struct sockaddr *)iph2->dst));
d1e348cf
A
2469 set_port(iph2->src, extract_port(iph1->local));
2470 set_port(iph2->dst, extract_port(iph1->remote));
65c25746
A
2471 plog(ASL_LEVEL_DEBUG, "After:\n");
2472 plog(ASL_LEVEL_DEBUG, "src: %s\n", saddr2str((struct sockaddr *)iph2->src));
2473 plog(ASL_LEVEL_DEBUG, "dst: %s\n", saddr2str((struct sockaddr *)iph2->dst));
d1e348cf 2474
52b7d2ce 2475 /* begin quick mode */
d9c572c0
A
2476 if (ikev1_ph2begin_i(iph1, iph2)) {
2477 ike_session_unlink_phase2(iph2);
d1e348cf 2478 }
52b7d2ce
A
2479 return;
2480 }
d1e348cf
A
2481 if (!ike_session_has_negoing_ph1(iph2->parent_session)) {
2482 struct remoteconf *rmconf = getrmconf(iph2->dst);
2483 /* start phase 1 negotiation as a initiator. */
65c25746 2484 if (rmconf) {
d06a7ccb 2485 if (ikev1_ph1begin_i(iph2->parent_session, rmconf, iph2->dst, iph2->src, 0, iph1 != NULL ? &iph1->nat64_prefix : NULL) < 0) {
7ebaebe2 2486 plog(ASL_LEVEL_NOTICE, "CHKPH1THERE: no established/negoing ph1 handler found... failed to initiate new one\n");
d9c572c0 2487 }
65c25746 2488 } else if (rmconf == NULL) {
7ebaebe2 2489 plog(ASL_LEVEL_NOTICE, "CHKPH1THERE: no remoteconf found... failed to initiate new one\n");
d1e348cf
A
2490 }
2491 }
2492
7ebaebe2 2493 plog(ASL_LEVEL_NOTICE, "CHKPH1THERE: no established ph1 handler found\n");
52b7d2ce
A
2494
2495 /* no isakmp-sa found */
2496 sched_new(1, isakmp_chkph1there_stub, iph2);
2497
2498 return;
2499}
2500
2501/* copy variable data into ALLOCATED buffer. */
2502caddr_t
2503isakmp_set_attr_v(buf, type, val, len)
2504 caddr_t buf;
2505 int type;
2506 caddr_t val;
2507 int len;
2508{
2509 struct isakmp_data *data;
2510
2511 data = (struct isakmp_data *)buf;
2512 data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
2513 data->lorv = htons((u_int16_t)len);
2514 memcpy(data + 1, val, len);
2515
2516 return buf + sizeof(*data) + len;
2517}
2518
2519/* copy fixed length data into ALLOCATED buffer. */
2520caddr_t
2521isakmp_set_attr_l(buf, type, val)
2522 caddr_t buf;
2523 int type;
2524 u_int32_t val;
2525{
2526 struct isakmp_data *data;
2527
2528 data = (struct isakmp_data *)buf;
2529 data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
2530 data->lorv = htons((u_int16_t)val);
2531
2532 return buf + sizeof(*data);
2533}
2534
2535/* add a variable data attribute to the buffer by reallocating it. */
2536vchar_t *
2537isakmp_add_attr_v(buf0, type, val, len)
2538 vchar_t *buf0;
2539 int type;
2540 caddr_t val;
2541 int len;
2542{
2543 vchar_t *buf = NULL;
2544 struct isakmp_data *data;
2545 int tlen;
2546 int oldlen = 0;
2547
2548 tlen = sizeof(*data) + len;
2549
2550 if (buf0) {
2551 oldlen = buf0->l;
2552 buf = vrealloc(buf0, oldlen + tlen);
2553 } else
2554 buf = vmalloc(tlen);
2555 if (!buf) {
65c25746 2556 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2557 "failed to get a attribute buffer.\n");
2558 return NULL;
2559 }
2560
2561 data = (struct isakmp_data *)(buf->v + oldlen);
2562 data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
2563 data->lorv = htons((u_int16_t)len);
2564 memcpy(data + 1, val, len);
2565
2566 return buf;
2567}
2568
2569/* add a fixed data attribute to the buffer by reallocating it. */
2570vchar_t *
2571isakmp_add_attr_l(buf0, type, val)
2572 vchar_t *buf0;
2573 int type;
2574 u_int32_t val;
2575{
2576 vchar_t *buf = NULL;
2577 struct isakmp_data *data;
2578 int tlen;
2579 int oldlen = 0;
2580
2581 tlen = sizeof(*data);
2582
2583 if (buf0) {
2584 oldlen = buf0->l;
2585 buf = vrealloc(buf0, oldlen + tlen);
2586 } else
2587 buf = vmalloc(tlen);
2588 if (!buf) {
65c25746 2589 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2590 "failed to get a attribute buffer.\n");
2591 return NULL;
2592 }
2593
2594 data = (struct isakmp_data *)(buf->v + oldlen);
2595 data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
2596 data->lorv = htons((u_int16_t)val);
2597
2598 return buf;
2599}
2600
2601/*
2602 * calculate cookie and set.
2603 */
2604int
2605isakmp_newcookie(place, remote, local)
2606 caddr_t place;
85f41bec
A
2607 struct sockaddr_storage *remote;
2608 struct sockaddr_storage *local;
52b7d2ce
A
2609{
2610 vchar_t *buf = NULL, *buf2 = NULL;
2611 char *p;
2612 int blen;
2613 int alen;
2614 caddr_t sa1, sa2;
2615 time_t t;
2616 int error = -1;
2617 u_short port;
2618
2619
85f41bec 2620 if (remote->ss_family != local->ss_family) {
65c25746 2621 plog(ASL_LEVEL_ERR,
52b7d2ce 2622 "address family mismatch, remote:%d local:%d\n",
85f41bec 2623 remote->ss_family, local->ss_family);
52b7d2ce
A
2624 goto end;
2625 }
85f41bec 2626 switch (remote->ss_family) {
52b7d2ce
A
2627 case AF_INET:
2628 alen = sizeof(struct in_addr);
2629 sa1 = (caddr_t)&((struct sockaddr_in *)remote)->sin_addr;
2630 sa2 = (caddr_t)&((struct sockaddr_in *)local)->sin_addr;
2631 break;
2632#ifdef INET6
2633 case AF_INET6:
2634 alen = sizeof(struct in_addr);
2635 sa1 = (caddr_t)&((struct sockaddr_in6 *)remote)->sin6_addr;
2636 sa2 = (caddr_t)&((struct sockaddr_in6 *)local)->sin6_addr;
2637 break;
2638#endif
2639 default:
65c25746 2640 plog(ASL_LEVEL_ERR,
85f41bec 2641 "invalid family: %d\n", remote->ss_family);
52b7d2ce
A
2642 goto end;
2643 }
2644 blen = (alen + sizeof(u_short)) * 2
2645 + sizeof(time_t) + lcconf->secret_size;
2646 buf = vmalloc(blen);
2647 if (buf == NULL) {
65c25746 2648 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2649 "failed to get a cookie.\n");
2650 goto end;
2651 }
2652 p = buf->v;
2653
2654 /* copy my address */
2655 memcpy(p, sa1, alen);
2656 p += alen;
2657 port = ((struct sockaddr_in *)remote)->sin_port;
2658 memcpy(p, &port, sizeof(u_short));
2659 p += sizeof(u_short);
2660
2661 /* copy target address */
2662 memcpy(p, sa2, alen);
2663 p += alen;
2664 port = ((struct sockaddr_in *)local)->sin_port;
2665 memcpy(p, &port, sizeof(u_short));
2666 p += sizeof(u_short);
2667
2668 /* copy time */
2669 t = time(0);
2670 memcpy(p, (caddr_t)&t, sizeof(t));
2671 p += sizeof(t);
2672
2673 /* copy random value */
2674 buf2 = eay_set_random(lcconf->secret_size);
2675 if (buf2 == NULL)
2676 goto end;
2677 memcpy(p, buf2->v, lcconf->secret_size);
2678 p += lcconf->secret_size;
2679 vfree(buf2);
2680
2681 buf2 = eay_sha1_one(buf);
2682 memcpy(place, buf2->v, sizeof(cookie_t));
2683
2684 sa1 = val2str(place, sizeof (cookie_t));
65c25746 2685 plog(ASL_LEVEL_DEBUG, "new cookie:\n%s\n", sa1);
52b7d2ce
A
2686 racoon_free(sa1);
2687
2688 error = 0;
2689end:
2690 if (buf != NULL)
2691 vfree(buf);
2692 if (buf2 != NULL)
2693 vfree(buf2);
2694 return error;
2695}
2696
2697/*
2698 * save partner's(payload) data into phhandle.
2699 */
2700int
2701isakmp_p2ph(buf, gen)
2702 vchar_t **buf;
2703 struct isakmp_gen *gen;
2704{
2705 /* XXX to be checked in each functions for logging. */
2706 if (*buf) {
65c25746 2707 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
2708 "ignore this payload, same payload type exist.\n");
2709 return -1;
2710 }
2711
e8d9021d 2712 if (ntohs(gen->len) < sizeof(*gen)) {
65c25746 2713 plog(ASL_LEVEL_ERR,
e8d9021d
A
2714 "ignore this payload, invalid payload len %d.\n",
2715 ntohs(gen->len));
2716 return -1;
2717 }
2718
52b7d2ce
A
2719 *buf = vmalloc(ntohs(gen->len) - sizeof(*gen));
2720 if (*buf == NULL) {
65c25746 2721 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2722 "failed to get buffer.\n");
2723 return -1;
2724 }
2725 memcpy((*buf)->v, gen + 1, (*buf)->l);
2726
2727 return 0;
2728}
2729
2730u_int32_t
2731isakmp_newmsgid2(iph1)
65c25746 2732 phase1_handle_t *iph1;
52b7d2ce
A
2733{
2734 u_int32_t msgid2;
2735
2736 do {
2737 msgid2 = eay_random();
65c25746 2738 } while (ike_session_getph2bymsgid(iph1, msgid2));
52b7d2ce
A
2739
2740 return msgid2;
2741}
2742
2743/*
2744 * set values into allocated buffer of isakmp header for phase 1
2745 */
2746static caddr_t
2747set_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid)
2748 vchar_t *vbuf;
65c25746 2749 phase1_handle_t *iph1;
52b7d2ce
A
2750 int nptype;
2751 u_int8_t etype;
2752 u_int8_t flags;
2753 u_int32_t msgid;
2754{
2755 struct isakmp *isakmp;
2756
2757 if (vbuf->l < sizeof(*isakmp))
2758 return NULL;
2759
2760 isakmp = (struct isakmp *)vbuf->v;
2761
2762 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
2763 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
2764 isakmp->np = nptype;
2765 isakmp->v = iph1->version;
2766 isakmp->etype = etype;
2767 isakmp->flags = flags;
2768 isakmp->msgid = msgid;
2769 isakmp->len = htonl(vbuf->l);
2770
2771 return vbuf->v + sizeof(*isakmp);
2772}
2773
2774/*
2775 * set values into allocated buffer of isakmp header for phase 1
2776 */
2777caddr_t
2778set_isakmp_header1(vbuf, iph1, nptype)
2779 vchar_t *vbuf;
65c25746 2780 phase1_handle_t *iph1;
52b7d2ce
A
2781 int nptype;
2782{
2783 return set_isakmp_header (vbuf, iph1, nptype, iph1->etype, iph1->flags, iph1->msgid);
2784}
2785
2786/*
2787 * set values into allocated buffer of isakmp header for phase 2
2788 */
2789caddr_t
2790set_isakmp_header2(vbuf, iph2, nptype)
2791 vchar_t *vbuf;
65c25746 2792 phase2_handle_t *iph2;
52b7d2ce
A
2793 int nptype;
2794{
2795 return set_isakmp_header (vbuf, iph2->ph1, nptype, ISAKMP_ETYPE_QUICK, iph2->flags, iph2->msgid);
2796}
2797
2798/*
2799 * set values into allocated buffer of isakmp payload.
2800 */
2801caddr_t
2802set_isakmp_payload(buf, src, nptype)
2803 caddr_t buf;
2804 vchar_t *src;
2805 int nptype;
2806{
2807 struct isakmp_gen *gen;
2808 caddr_t p = buf;
2809
65c25746 2810 plog(ASL_LEVEL_DEBUG, "add payload of len %zu, next type %d\n",
52b7d2ce
A
2811 src->l, nptype);
2812
2813 gen = (struct isakmp_gen *)p;
2814 gen->np = nptype;
2815 gen->len = htons(sizeof(*gen) + src->l);
2816 p += sizeof(*gen);
2817 memcpy(p, src->v, src->l);
2818 p += src->l;
2819
2820 return p;
2821}
2822
52b7d2ce
A
2823
2824#ifdef HAVE_PRINT_ISAKMP_C
2825/* for print-isakmp.c */
2826char *snapend;
65c25746 2827extern void isakmp_print(const u_char *, u_int, const u_char *);
52b7d2ce 2828
65c25746 2829char *getname(const u_char *);
52b7d2ce 2830#ifdef INET6
65c25746 2831char *getname6(const u_char *);
52b7d2ce 2832#endif
65c25746 2833int safeputchar(int);
52b7d2ce
A
2834
2835/*
2836 * Return a name for the IP address pointed to by ap. This address
2837 * is assumed to be in network byte order.
2838 */
2839char *
2840getname(ap)
2841 const u_char *ap;
2842{
2843 struct sockaddr_in addr;
2844 static char ntop_buf[NI_MAXHOST];
2845
2846 memset(&addr, 0, sizeof(addr));
52b7d2ce 2847 addr.sin_len = sizeof(struct sockaddr_in);
52b7d2ce
A
2848 addr.sin_family = AF_INET;
2849 memcpy(&addr.sin_addr, ap, sizeof(addr.sin_addr));
85f41bec 2850 if (getnameinfo(&addr, sizeof(addr),
52b7d2ce
A
2851 ntop_buf, sizeof(ntop_buf), NULL, 0,
2852 NI_NUMERICHOST | niflags))
2853 strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2854
2855 return ntop_buf;
2856}
2857
2858#ifdef INET6
2859/*
2860 * Return a name for the IP6 address pointed to by ap. This address
2861 * is assumed to be in network byte order.
2862 */
2863char *
2864getname6(ap)
2865 const u_char *ap;
2866{
2867 struct sockaddr_in6 addr;
2868 static char ntop_buf[NI_MAXHOST];
2869
2870 memset(&addr, 0, sizeof(addr));
2871 addr.sin6_len = sizeof(struct sockaddr_in6);
2872 addr.sin6_family = AF_INET6;
2873 memcpy(&addr.sin6_addr, ap, sizeof(addr.sin6_addr));
85f41bec 2874 if (getnameinfo(&addr, addr.sin6_len,
52b7d2ce
A
2875 ntop_buf, sizeof(ntop_buf), NULL, 0,
2876 NI_NUMERICHOST | niflags))
2877 strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2878
2879 return ntop_buf;
2880}
2881#endif /* INET6 */
2882
2883int
2884safeputchar(c)
2885 int c;
2886{
2887 unsigned char ch;
2888
2889 ch = (unsigned char)(c & 0xff);
2890 if (c < 0x80 && isprint(c))
2891 return printf("%c", c & 0xff);
2892 else
2893 return printf("\\%03o", c & 0xff);
2894}
2895
2896void
2897isakmp_printpacket(msg, from, my, decoded)
2898 vchar_t *msg;
85f41bec
A
2899 struct sockaddr_storage *from;
2900 struct sockaddr_storage *my;
52b7d2ce
A
2901 int decoded;
2902{
2903#ifdef YIPS_DEBUG
2904 struct timeval tv;
2905 int s;
2906 char hostbuf[NI_MAXHOST];
2907 char portbuf[NI_MAXSERV];
2908 struct isakmp *isakmp;
2909 vchar_t *buf;
2910#endif
2911
65c25746 2912 if (loglevel < ASL_LEVEL_DEBUG)
52b7d2ce
A
2913 return;
2914
2915#ifdef YIPS_DEBUG
65c25746 2916 plog(ASL_LEVEL_DEBUG, "begin.\n");
52b7d2ce
A
2917
2918 gettimeofday(&tv, NULL);
2919 s = tv.tv_sec % 3600;
2920 printf("%02d:%02d.%06u ", s / 60, s % 60, (u_int32_t)tv.tv_usec);
2921
2922 if (from) {
85f41bec 2923 if (getnameinfo(from, sysdep_sa_len((struct sockaddr *)from), hostbuf, sizeof(hostbuf),
52b7d2ce
A
2924 portbuf, sizeof(portbuf),
2925 NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
2926 strlcpy(hostbuf, "?", sizeof(hostbuf));
2927 strlcpy(portbuf, "?", sizeof(portbuf));
2928 }
2929 printf("%s:%s", hostbuf, portbuf);
2930 } else
2931 printf("?");
2932 printf(" -> ");
2933 if (my) {
85f41bec 2934 if (getnameinfo(my, sysdep_sa_len((struct sockaddr *)my), hostbuf, sizeof(hostbuf),
52b7d2ce
A
2935 portbuf, sizeof(portbuf),
2936 NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
2937 strlcpy(hostbuf, "?", sizeof(hostbuf));
2938 strlcpy(portbuf, "?", sizeof(portbuf));
2939 }
2940 printf("%s:%s", hostbuf, portbuf);
2941 } else
2942 printf("?");
2943 printf(": ");
2944
2945 buf = vdup(msg);
2946 if (!buf) {
2947 printf("(malloc fail)\n");
2948 return;
2949 }
2950 if (decoded) {
2951 isakmp = (struct isakmp *)buf->v;
2952 if (isakmp->flags & ISAKMP_FLAG_E) {
2953#if 0
2954 int pad;
2955 pad = *(u_char *)(buf->v + buf->l - 1);
2956 if (buf->l < pad && 2 < vflag)
2957 printf("(wrong padding)");
2958#endif
2959 isakmp->flags &= ~ISAKMP_FLAG_E;
2960 }
2961 }
2962
2963 snapend = buf->v + buf->l;
2964 isakmp_print(buf->v, buf->l, NULL);
2965 vfree(buf);
2966 printf("\n");
2967 fflush(stdout);
2968
2969 return;
2970#endif
2971}
2972#endif /*HAVE_PRINT_ISAKMP_C*/
2973
2974int
2975copy_ph1addresses(iph1, rmconf, remote, local)
65c25746 2976 phase1_handle_t *iph1;
52b7d2ce 2977 struct remoteconf *rmconf;
85f41bec 2978 struct sockaddr_storage *remote, *local;
52b7d2ce
A
2979{
2980 u_short *port = NULL;
2981
2982 /* address portion must be grabbed from real remote address "remote" */
65c25746 2983 iph1->remote = dupsaddr(remote);
52b7d2ce 2984 if (iph1->remote == NULL) {
65c25746 2985 ike_session_delph1(iph1);
52b7d2ce
A
2986 return -1;
2987 }
2988
2989 /*
2990 * if remote has no port # (in case of initiator - from ACQUIRE msg)
2991 * - if remote.conf specifies port #, use that
2992 * - if remote.conf does not, use 500
2993 * if remote has port # (in case of responder - from recvfrom(2))
2994 * respect content of "remote".
2995 */
85f41bec 2996 switch (iph1->remote->ss_family) {
52b7d2ce
A
2997 case AF_INET:
2998 port = &((struct sockaddr_in *)iph1->remote)->sin_port;
2999 if (*port)
3000 break;
3001 *port = ((struct sockaddr_in *)rmconf->remote)->sin_port;
3002 if (*port)
3003 break;
3004 *port = htons(PORT_ISAKMP);
3005 break;
3006#ifdef INET6
3007 case AF_INET6:
3008 port = &((struct sockaddr_in6 *)iph1->remote)->sin6_port;
3009 if (*port)
3010 break;
3011 *port = ((struct sockaddr_in6 *)rmconf->remote)->sin6_port;
3012 if (*port)
3013 break;
3014 *port = htons(PORT_ISAKMP);
3015 break;
3016#endif
3017 default:
65c25746 3018 plog(ASL_LEVEL_ERR,
85f41bec 3019 "invalid family: %d\n", iph1->remote->ss_family);
65c25746 3020 ike_session_delph1(iph1);
52b7d2ce
A
3021 return -1;
3022 }
3023
3024 if (local == NULL)
85f41bec 3025 iph1->local = getlocaladdr((struct sockaddr *)iph1->remote);
52b7d2ce 3026 else
65c25746 3027 iph1->local = dupsaddr(local);
52b7d2ce 3028 if (iph1->local == NULL) {
65c25746 3029 ike_session_delph1(iph1);
52b7d2ce
A
3030 return -1;
3031 }
3032 port = NULL;
85f41bec 3033 switch (iph1->local->ss_family) {
52b7d2ce
A
3034 case AF_INET:
3035 port = &((struct sockaddr_in *)iph1->local)->sin_port;
3036 if (*port)
3037 break;
d1e348cf 3038 *port = ((struct sockaddr_in *)iph1->local)->sin_port;
52b7d2ce
A
3039 if (*port)
3040 break;
3041 *port = getmyaddrsport(iph1->local);
3042 break;
3043#ifdef INET6
3044 case AF_INET6:
3045 port = &((struct sockaddr_in6 *)iph1->local)->sin6_port;
3046 if (*port)
3047 break;
d1e348cf 3048 *port = ((struct sockaddr_in6 *)iph1->local)->sin6_port;
52b7d2ce
A
3049 if (*port)
3050 break;
3051 *port = getmyaddrsport(iph1->local);
3052 break;
3053#endif
3054 default:
65c25746 3055 plog(ASL_LEVEL_ERR,
85f41bec 3056 "invalid family: %d\n", iph1->local->ss_family);
65c25746 3057 ike_session_delph1(iph1);
52b7d2ce
A
3058 return -1;
3059 }
3060#ifdef ENABLE_NATT
3061 if ( port != NULL && *port == htons(lcconf->port_isakmp_natt) ) {
7ebaebe2 3062 plog (ASL_LEVEL_NOTICE, "Marking ports as changed\n");
52b7d2ce
A
3063 iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER;
3064 }
3065#endif
3066
3067 return 0;
3068}
3069
52b7d2ce
A
3070void
3071log_ph1established(iph1)
65c25746 3072 const phase1_handle_t *iph1;
52b7d2ce
A
3073{
3074 char *src, *dst;
3075
85f41bec
A
3076 src = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
3077 dst = racoon_strdup(saddr2str((struct sockaddr *)iph1->remote));
d1e348cf
A
3078 STRDUP_FATAL(src);
3079 STRDUP_FATAL(dst);
3080
7ebaebe2
A
3081 plog(ASL_LEVEL_NOTICE,
3082 "ISAKMP-SA established spi:%s\n",
52b7d2ce 3083 isakmp_pindex(&iph1->index, 0));
7ebaebe2
A
3084 plog(ASL_LEVEL_DEBUG,
3085 "ISAKMP-SA established %s-%s spi:%s\n",
3086 src, dst,
3087 isakmp_pindex(&iph1->index, 0));
d1e348cf 3088
52b7d2ce
A
3089 racoon_free(src);
3090 racoon_free(dst);
3091
65c25746 3092 IPSECLOGASLMSG("IPSec Phase 1 established (Initiated by %s).\n",
e8d9021d
A
3093 (iph1->side == INITIATOR)? "me" : "peer");
3094
52b7d2ce
A
3095 return;
3096}
3097
3098struct payload_list *
3099isakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_type)
3100{
3101 if (! plist) {
3102 plist = racoon_malloc (sizeof (struct payload_list));
3103 plist->prev = NULL;
3104 }
3105 else {
3106 plist->next = racoon_malloc (sizeof (struct payload_list));
3107 plist->next->prev = plist;
3108 plist = plist->next;
3109 }
3110
3111 plist->next = NULL;
3112 plist->payload = payload;
3113 plist->payload_type = payload_type;
3114
3115 return plist;
3116}
3117
3118vchar_t *
65c25746 3119isakmp_plist_set_all (struct payload_list **plist, phase1_handle_t *iph1)
52b7d2ce 3120{
d1e348cf 3121 struct payload_list *ptr = *plist, *first;
52b7d2ce 3122 size_t tlen = sizeof (struct isakmp), n = 0;
d1e348cf 3123 vchar_t *buf = NULL;
52b7d2ce
A
3124 char *p;
3125
52b7d2ce 3126 /* Seek to the first item. */
d1e348cf 3127 while (ptr->prev) ptr = ptr->prev;
52b7d2ce
A
3128 first = ptr;
3129
3130 /* Compute the whole length. */
3131 while (ptr) {
3132 tlen += ptr->payload->l + sizeof (struct isakmp_gen);
3133 ptr = ptr->next;
3134 }
3135
3136 buf = vmalloc(tlen);
3137 if (buf == NULL) {
65c25746 3138 plog(ASL_LEVEL_ERR,
52b7d2ce
A
3139 "failed to get buffer to send.\n");
3140 goto end;
3141 }
3142
3143 ptr = first;
3144
3145 p = set_isakmp_header1(buf, iph1, ptr->payload_type);
3146 if (p == NULL)
3147 goto end;
3148
3149 while (ptr)
3150 {
3151 p = set_isakmp_payload (p, ptr->payload, ptr->next ? ptr->next->payload_type : ISAKMP_NPTYPE_NONE);
3152 first = ptr;
3153 ptr = ptr->next;
3154 racoon_free (first);
3155 /* ptr->prev = NULL; first = NULL; ... omitted. */
3156 n++;
3157 }
3158
3159 *plist = NULL;
3160
3161 return buf;
3162end:
d1e348cf
A
3163 if (buf != NULL)
3164 vfree(buf);
52b7d2ce
A
3165 return NULL;
3166}
3167
3168#ifdef ENABLE_FRAG
65c25746 3169void
52b7d2ce 3170frag_handler(iph1, msg, remote, local)
65c25746 3171 phase1_handle_t *iph1;
52b7d2ce 3172 vchar_t *msg;
85f41bec
A
3173 struct sockaddr_storage *remote;
3174 struct sockaddr_storage *local;
52b7d2ce
A
3175{
3176 vchar_t *newmsg;
3177
3178 if (isakmp_frag_extract(iph1, msg) == 1) {
3179 if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) {
65c25746 3180 plog(ASL_LEVEL_ERR,
52b7d2ce 3181 "Packet reassembly failed\n");
65c25746 3182 return;
52b7d2ce 3183 }
e8d9021d
A
3184
3185 /* simply reply if the packet was processed. */
65c25746 3186 if (ike_session_check_recvdpkt(remote, local, newmsg) > 0) {
e8d9021d
A
3187 IPSECLOGASLMSG("Received (reassembled) retransmitted packet from %s.\n",
3188 saddr2str((struct sockaddr *)remote));
3189
65c25746 3190 plog(ASL_LEVEL_NOTICE,
e8d9021d
A
3191 "the reassembled packet is retransmitted by %s.\n",
3192 saddr2str((struct sockaddr *)remote));
65c25746
A
3193 vfree(newmsg);
3194 return;
e8d9021d
A
3195 }
3196
65c25746 3197 isakmp_main(newmsg, remote, local);
85f41bec 3198 vfree(newmsg);
52b7d2ce
A
3199 }
3200
52b7d2ce
A
3201 return;
3202}
65c25746 3203#endif
52b7d2ce
A
3204
3205void
3206purge_remote(iph1)
65c25746 3207 phase1_handle_t *iph1;
52b7d2ce
A
3208{
3209 vchar_t *buf = NULL;
3210 struct sadb_msg *msg, *next, *end;
3211 struct sadb_sa *sa;
85f41bec 3212 struct sockaddr_storage *src, *dst;
52b7d2ce
A
3213 caddr_t mhp[SADB_EXT_MAX + 1];
3214 u_int proto_id;
65c25746
A
3215 phase2_handle_t *iph2;
3216 phase1_handle_t *new_iph1;
52b7d2ce 3217
7ebaebe2 3218 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3219 "purging ISAKMP-SA spi=%s.\n",
3220 isakmp_pindex(&(iph1->index), iph1->msgid));
3221
3222 /* Mark as expired. */
65c25746 3223 fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED);
52b7d2ce 3224
d1e348cf 3225 new_iph1 = ike_session_update_ph1_ph2tree(iph1);
52b7d2ce
A
3226
3227 /*
3228 * Delete all orphaned or binded to the deleting ph1handle phase2 SAs.
3229 * Keep all others phase2 SAs.
3230 */
3231 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
3232 if (buf == NULL) {
7ebaebe2 3233 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3234 "pfkey_dump_sadb returned nothing.\n");
3235 return;
3236 }
3237
85f41bec
A
3238 msg = ALIGNED_CAST(struct sadb_msg *)buf->v;
3239 end = ALIGNED_CAST(struct sadb_msg *)(buf->v + buf->l);
52b7d2ce
A
3240
3241 while (msg < end) {
3242 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
3243 break;
85f41bec 3244 next = ALIGNED_CAST(struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
52b7d2ce
A
3245 if (msg->sadb_msg_type != SADB_DUMP) {
3246 msg = next;
3247 continue;
3248 }
3249
3250 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
65c25746 3251 plog(ASL_LEVEL_ERR,
52b7d2ce
A
3252 "pfkey_check (%s)\n", ipsec_strerror());
3253 msg = next;
3254 continue;
3255 }
3256
85f41bec 3257 sa = ALIGNED_CAST(struct sadb_sa *)(mhp[SADB_EXT_SA]);
52b7d2ce
A
3258 if (!sa ||
3259 !mhp[SADB_EXT_ADDRESS_SRC] ||
3260 !mhp[SADB_EXT_ADDRESS_DST]) {
3261 msg = next;
3262 continue;
3263 }
85f41bec
A
3264 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
3265 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
52b7d2ce
A
3266
3267 if (sa->sadb_sa_state != SADB_SASTATE_LARVAL &&
3268 sa->sadb_sa_state != SADB_SASTATE_MATURE &&
3269 sa->sadb_sa_state != SADB_SASTATE_DYING) {
3270 msg = next;
3271 continue;
3272 }
3273
d1e348cf
A
3274 /*
3275 * check in/outbound SAs.
3276 * Select only SAs where src == local and dst == remote (outgoing)
3277 * or src == remote and dst == local (incoming).
3278 */
52b7d2ce
A
3279 if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) &&
3280 (CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) {
3281 msg = next;
3282 continue;
3283 }
3284
3285 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
65c25746 3286 iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
52b7d2ce
A
3287
3288 /* Check if there is another valid ISAKMP-SA */
3289 if (new_iph1 != NULL) {
3290
3291 if (iph2 == NULL) {
3292 /* No handler... still send a pfkey_delete message, but log this !*/
7ebaebe2 3293 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3294 "Unknown IPsec-SA spi=%u, hmmmm?\n",
3295 ntohl(sa->sadb_sa_spi));
3296 }else{
3297
3298 /*
3299 * If we have a new ph1, do not purge IPsec-SAs binded
3300 * to a different ISAKMP-SA
3301 */
3302 if (iph2->ph1 != NULL && iph2->ph1 != iph1){
3303 msg = next;
3304 continue;
3305 }
3306
3307 /* If the ph2handle is established, do not purge IPsec-SA */
65c25746 3308 if (FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(iph2->status)) {
52b7d2ce 3309
7ebaebe2 3310 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3311 "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n",
3312 ntohl(sa->sadb_sa_spi),
3313 isakmp_pindex(&(new_iph1->index), new_iph1->msgid));
3314 msg = next;
3315 continue;
3316 }
3317 }
3318 }
3319
3320
3321 pfkey_send_delete(lcconf->sock_pfkey,
3322 msg->sadb_msg_satype,
3323 IPSEC_MODE_ANY,
3324 src, dst, sa->sadb_sa_spi);
3325
3326 /* delete a relative phase 2 handle. */
3327 if (iph2 != NULL) {
3328 delete_spd(iph2);
65c25746 3329 ike_session_unlink_phase2(iph2);
52b7d2ce
A
3330 }
3331
7ebaebe2 3332 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3333 "purged IPsec-SA spi=%u.\n",
3334 ntohl(sa->sadb_sa_spi));
3335
3336 msg = next;
3337 }
3338
3339 if (buf)
3340 vfree(buf);
3341
3342 /* Mark the phase1 handler as EXPIRED */
7ebaebe2 3343 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3344 "purged ISAKMP-SA spi=%s.\n",
3345 isakmp_pindex(&(iph1->index), iph1->msgid));
3346
d1e348cf 3347 SCHED_KILL(iph1->sce);
52b7d2ce
A
3348
3349 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
3350}
3351
3352void
3353delete_spd(iph2)
65c25746 3354 phase2_handle_t *iph2;
52b7d2ce
A
3355{
3356 if (iph2 == NULL)
3357 return;
3358
3359 /* Delete the SPD entry if we generated it
3360 */
3361 if (iph2->generated_spidx) {
85f41bec
A
3362 union {
3363 u_int64_t force_align; // Wcast-align fix - force alignment
3364 struct policyindex spidx;
3365 } u;
52b7d2ce
A
3366 struct sockaddr_storage addr;
3367 u_int8_t pref;
85f41bec
A
3368 struct sockaddr_storage *src = iph2->src;
3369 struct sockaddr_storage *dst = iph2->dst;
52b7d2ce
A
3370 int error;
3371 int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */
3372
7ebaebe2 3373 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3374 "generated policy, deleting it.\n");
3375
85f41bec
A
3376 memset(&u.spidx, 0, sizeof(u.spidx));
3377 iph2->spidx_gen = &u.spidx;
52b7d2ce
A
3378
3379 /* make inbound policy */
3380 iph2->src = dst;
3381 iph2->dst = src;
85f41bec
A
3382 u.spidx.dir = IPSEC_DIR_INBOUND;
3383 u.spidx.ul_proto = 0;
52b7d2ce
A
3384
3385 /*
3386 * Note: code from get_proposal_r
3387 */
3388
85f41bec 3389#define _XIDT(d) (ALIGNED_CAST(struct ipsecdoi_id_b *)((d)->v))->type
52b7d2ce
A
3390
3391 /*
3392 * make destination address in spidx from either ID payload
3393 * or phase 1 address into a address in spidx.
3394 */
3395 if (iph2->id != NULL
3396 && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
3397 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
3398 || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
3399 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
3400 /* get a destination address of a policy */
85f41bec 3401 error = ipsecdoi_id2sockaddr(iph2->id, &u.spidx.dst,
65c25746 3402 &u.spidx.prefd, &u.spidx.ul_proto, iph2->version);
52b7d2ce
A
3403 if (error)
3404 goto purge;
3405
3406#ifdef INET6
3407 /*
3408 * get scopeid from the SA address.
3409 * note that the phase 1 source address is used as
3410 * a destination address to search for a inbound
3411 * policy entry because rcoon is responder.
3412 */
3413 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
3414 if ((error =
85f41bec 3415 setscopeid(&u.spidx.dst, iph2->src)) != 0)
52b7d2ce
A
3416 goto purge;
3417 }
3418#endif
3419
3420 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
3421 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
3422 idi2type = _XIDT(iph2->id);
3423
3424 } else {
3425
7ebaebe2 3426 plog(ASL_LEVEL_NOTICE,
65c25746
A
3427 "Get a destination address of SP index "
3428 "from Phase 1 address "
52b7d2ce
A
3429 "due to no ID payloads found "
3430 "OR because ID type is not address.\n");
3431
3432 /*
3433 * copy the SOURCE address of IKE into the
3434 * DESTINATION address of the key to search the
3435 * SPD because the direction of policy is inbound.
3436 */
85f41bec
A
3437 memcpy(&u.spidx.dst, iph2->src, sysdep_sa_len((struct sockaddr *)iph2->src));
3438 switch (u.spidx.dst.ss_family) {
52b7d2ce 3439 case AF_INET:
85f41bec 3440 u.spidx.prefd =
52b7d2ce
A
3441 sizeof(struct in_addr) << 3;
3442 break;
3443#ifdef INET6
3444 case AF_INET6:
85f41bec 3445 u.spidx.prefd =
52b7d2ce
A
3446 sizeof(struct in6_addr) << 3;
3447 break;
3448#endif
3449 default:
85f41bec 3450 u.spidx.prefd = 0;
52b7d2ce
A
3451 break;
3452 }
3453 }
3454
3455 /* make source address in spidx */
3456 if (iph2->id_p != NULL
3457 && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
3458 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
3459 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
3460 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
3461 /* get a source address of inbound SA */
85f41bec 3462 error = ipsecdoi_id2sockaddr(iph2->id_p, &u.spidx.src,
65c25746 3463 &u.spidx.prefs, &u.spidx.ul_proto, iph2->version);
52b7d2ce
A
3464 if (error)
3465 goto purge;
3466
3467#ifdef INET6
3468 /*
3469 * get scopeid from the SA address.
3470 * for more detail, see above of this function.
3471 */
3472 if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
3473 error =
85f41bec 3474 setscopeid(&u.spidx.src, iph2->dst);
52b7d2ce
A
3475 if (error)
3476 goto purge;
3477 }
3478#endif
3479
3480 /* make id[src,dst] if both ID types are IP address and same */
3481 if (_XIDT(iph2->id_p) == idi2type
85f41bec 3482 && u.spidx.dst.ss_family == u.spidx.src.ss_family) {
52b7d2ce 3483 iph2->src_id =
65c25746 3484 dupsaddr(&u.spidx.dst);
52b7d2ce 3485 iph2->dst_id =
65c25746 3486 dupsaddr(&u.spidx.src);
52b7d2ce
A
3487 }
3488
3489 } else {
7ebaebe2 3490 plog(ASL_LEVEL_NOTICE,
65c25746
A
3491 "Get a source address of SP index "
3492 "from Phase 1 address "
52b7d2ce
A
3493 "due to no ID payloads found "
3494 "OR because ID type is not address.\n");
3495
3496 /* see above comment. */
85f41bec
A
3497 memcpy(&u.spidx.src, iph2->dst, sysdep_sa_len((struct sockaddr *)iph2->dst));
3498 switch (u.spidx.src.ss_family) {
52b7d2ce 3499 case AF_INET:
85f41bec 3500 u.spidx.prefs =
52b7d2ce
A
3501 sizeof(struct in_addr) << 3;
3502 break;
3503#ifdef INET6
3504 case AF_INET6:
85f41bec 3505 u.spidx.prefs =
52b7d2ce
A
3506 sizeof(struct in6_addr) << 3;
3507 break;
3508#endif
3509 default:
85f41bec 3510 u.spidx.prefs = 0;
52b7d2ce
A
3511 break;
3512 }
3513 }
3514
3515#undef _XIDT
3516
7ebaebe2
A
3517 plog(ASL_LEVEL_NOTICE,
3518 "get src/dst address from ID payload "
3519 "prefixlen=%u ul_proto=%u\n",
3520 u.spidx.prefs, u.spidx.ul_proto);
3521 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
3522 "get a src address from ID payload "
3523 "%s prefixlen=%u ul_proto=%u\n",
85f41bec
A
3524 saddr2str((struct sockaddr *)&u.spidx.src),
3525 u.spidx.prefs, u.spidx.ul_proto);
7ebaebe2 3526 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
3527 "get dst address from ID payload "
3528 "%s prefixlen=%u ul_proto=%u\n",
85f41bec
A
3529 saddr2str((struct sockaddr *)&u.spidx.dst),
3530 u.spidx.prefd, u.spidx.ul_proto);
52b7d2ce
A
3531
3532 /*
3533 * convert the ul_proto if it is 0
3534 * because 0 in ID payload means a wild card.
3535 */
85f41bec
A
3536 if (u.spidx.ul_proto == 0)
3537 u.spidx.ul_proto = IPSEC_ULPROTO_ANY;
52b7d2ce
A
3538
3539#undef _XIDT
3540
3541 /* End of code from get_proposal_r
3542 */
3543
3544 if (pk_sendspddelete(iph2) < 0) {
65c25746 3545 plog(ASL_LEVEL_ERR,
52b7d2ce
A
3546 "pfkey spddelete(inbound) failed.\n");
3547 }else{
7ebaebe2 3548 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3549 "pfkey spddelete(inbound) sent.\n");
3550 }
3551
3552#ifdef HAVE_POLICY_FWD
3553 /* make forward policy if required */
3554 if (tunnel_mode_prop(iph2->approval)) {
85f41bec 3555 u.spidx.dir = IPSEC_DIR_FWD;
52b7d2ce 3556 if (pk_sendspddelete(iph2) < 0) {
65c25746 3557 plog(ASL_LEVEL_ERR,
52b7d2ce
A
3558 "pfkey spddelete(forward) failed.\n");
3559 }else{
7ebaebe2 3560 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3561 "pfkey spddelete(forward) sent.\n");
3562 }
3563 }
3564#endif
3565
3566 /* make outbound policy */
3567 iph2->src = src;
3568 iph2->dst = dst;
85f41bec
A
3569 u.spidx.dir = IPSEC_DIR_OUTBOUND;
3570 addr = u.spidx.src;
3571 u.spidx.src = u.spidx.dst;
3572 u.spidx.dst = addr;
3573 pref = u.spidx.prefs;
3574 u.spidx.prefs = u.spidx.prefd;
3575 u.spidx.prefd = pref;
52b7d2ce
A
3576
3577 if (pk_sendspddelete(iph2) < 0) {
65c25746 3578 plog(ASL_LEVEL_ERR,
52b7d2ce
A
3579 "pfkey spddelete(outbound) failed.\n");
3580 }else{
7ebaebe2 3581 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
3582 "pfkey spddelete(outbound) sent.\n");
3583 }
3584purge:
3585 iph2->spidx_gen=NULL;
3586 }
3587}
3588
3589#ifdef INET6
3590u_int32_t
3591setscopeid(sp_addr0, sa_addr0)
85f41bec 3592 struct sockaddr_storage *sp_addr0, *sa_addr0;
52b7d2ce
A
3593{
3594 struct sockaddr_in6 *sp_addr, *sa_addr;
3595
3596 sp_addr = (struct sockaddr_in6 *)sp_addr0;
3597 sa_addr = (struct sockaddr_in6 *)sa_addr0;
3598
3599 if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr)
3600 && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr)
3601 && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr))
3602 return 0;
3603
3604 /* this check should not be here ? */
3605 if (sa_addr->sin6_family != AF_INET6) {
65c25746 3606 plog(ASL_LEVEL_ERR,
52b7d2ce
A
3607 "can't get scope ID: family mismatch\n");
3608 return -1;
3609 }
3610
3611 if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) {
65c25746 3612 plog(ASL_LEVEL_ERR,
52b7d2ce
A
3613 "scope ID is not supported except of lladdr.\n");
3614 return -1;
3615 }
3616
3617 sp_addr->sin6_scope_id = sa_addr->sin6_scope_id;
3618
3619 return 0;
3620}
3621#endif
b8c37798
A
3622
3623vchar_t *
3624isakmp_plist_append_initial_contact (iph1, plist)
65c25746 3625 phase1_handle_t *iph1;
e8d9021d 3626 struct payload_list *plist;
b8c37798 3627{
65c25746 3628 if (!iph1->is_rekey && iph1->rmconf->ini_contact && !ike_session_getcontacted(iph1->remote)) {
b8c37798
A
3629 vchar_t *notp_ini = NULL;
3630 struct isakmp_pl_n np, *nptr;
3631 char *cptr;
e8d9021d 3632
b8c37798
A
3633 np.doi = htonl(iph1->rmconf->doitype);
3634 np.proto_id = IPSECDOI_PROTO_ISAKMP;
3635 np.spi_size = sizeof(isakmp_index);
3636 np.type = htons(ISAKMP_NTYPE_INITIAL_CONTACT);
3637 if ((notp_ini = vmalloc(sizeof(struct isakmp_pl_n) - sizeof(struct isakmp_gen)
3638 + sizeof(isakmp_index)))) {
3639 nptr = &np;
3640 memcpy(notp_ini->v, &nptr->doi, sizeof(struct isakmp_pl_n) - sizeof(struct isakmp_gen));
3641 cptr = notp_ini->v + sizeof(struct isakmp_pl_n) - sizeof(struct isakmp_gen);
3642 memcpy(cptr, &iph1->index, sizeof(isakmp_index));
3643 plist = isakmp_plist_append(plist, notp_ini, ISAKMP_NPTYPE_N);
7ebaebe2 3644 plog(ASL_LEVEL_NOTICE,
b8c37798
A
3645 "added initial-contact payload.\n");
3646
3647 /* insert a node into contacted list. */
65c25746
A
3648 if (ike_session_inscontacted(iph1->remote) == -1) {
3649 plog(ASL_LEVEL_ERR,
b8c37798
A
3650 "failed to add contacted list.\n");
3651 /* ignore */
3652 }
3653 return notp_ini;
3654 } else {
65c25746 3655 plog(ASL_LEVEL_ERR,
b8c37798
A
3656 "failed to allocate notification payload.\n");
3657 return NULL;
3658 }
869d26af 3659 } else {
7ebaebe2 3660 plog(ASL_LEVEL_NOTICE, "failed to add initial-contact payload: rekey %d, ini-contact %d, contacted %d.\n",
65c25746 3661 iph1->is_rekey? 1:0, iph1->rmconf->ini_contact, ike_session_getcontacted(iph1->remote)? 1:0);
b8c37798
A
3662 }
3663 return NULL;
3664}