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