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