]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/isakmp_inf.c
ipsec-332.100.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_inf.c
CommitLineData
d1e348cf
A
1/* $NetBSD: isakmp_inf.c,v 1.14.4.8 2007/08/01 11:52:20 vanhu Exp $ */
2
3/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 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 */
33
34#include "config.h"
65c25746 35#include "racoon_types.h"
52b7d2ce
A
36
37#include <sys/types.h>
38#include <sys/param.h>
39#include <sys/socket.h>
40
65c25746 41#include <net/pfkeyv2.h>
52b7d2ce
A
42#include <netinet/in.h>
43#include <sys/queue.h>
44#ifndef HAVE_NETINET6_IPSEC
45#include <netinet/ipsec.h>
46#else
47#include <netinet6/ipsec.h>
48#endif
49
50#include <stdlib.h>
51#include <stdio.h>
52#include <string.h>
53#include <errno.h>
54#if TIME_WITH_SYS_TIME
55# include <sys/time.h>
56# include <time.h>
57#else
58# if HAVE_SYS_TIME_H
59# include <sys/time.h>
60# else
61# include <time.h>
62# endif
63#endif
64
65#include "libpfkey.h"
66
67#include "var.h"
68#include "vmbuf.h"
69#include "schedule.h"
70#include "str2val.h"
71#include "misc.h"
72#include "plog.h"
73#include "debug.h"
65c25746
A
74#include "fsm.h"
75#include "session.h"
76#include "ike_session.h"
52b7d2ce
A
77
78#include "localconf.h"
79#include "remoteconf.h"
80#include "sockmisc.h"
d1e348cf
A
81#include "handler.h"
82#include "policy.h"
83#include "proposal.h"
52b7d2ce 84#include "isakmp_var.h"
52b7d2ce
A
85#include "isakmp.h"
86#ifdef ENABLE_HYBRID
87#include "isakmp_xauth.h"
d1e348cf 88#include "isakmp_unity.h"
52b7d2ce
A
89#include "isakmp_cfg.h"
90#endif
91#include "isakmp_inf.h"
92#include "oakley.h"
52b7d2ce
A
93#include "ipsec_doi.h"
94#include "crypto_openssl.h"
95#include "pfkey.h"
96#include "policy.h"
97#include "algorithm.h"
98#include "proposal.h"
52b7d2ce
A
99#include "strnames.h"
100#ifdef ENABLE_NATT
101#include "nattraversal.h"
102#endif
103#include "vpn_control_var.h"
104#include "vpn_control.h"
d1e348cf 105#include "ike_session.h"
52b7d2ce
A
106
107/* information exchange */
65c25746
A
108static int isakmp_info_recv_n (phase1_handle_t *, struct isakmp_pl_n *, u_int32_t, int);
109static int isakmp_info_recv_d (phase1_handle_t *, struct isakmp_pl_d *, u_int32_t, int);
52b7d2ce
A
110
111#ifdef ENABLE_DPD
65c25746
A
112static int isakmp_info_recv_r_u (phase1_handle_t *, struct isakmp_pl_ru *, u_int32_t);
113static int isakmp_info_recv_r_u_ack (phase1_handle_t *, struct isakmp_pl_ru *, u_int32_t);
52b7d2ce
A
114#endif
115
116#ifdef ENABLE_VPNCONTROL_PORT
65c25746 117static int isakmp_info_recv_lb (phase1_handle_t *, struct isakmp_pl_lb *lb, int);
52b7d2ce
A
118#endif
119
d1e348cf 120static int
65c25746 121isakmp_ph1_responder_lifetime (phase1_handle_t *iph1, struct isakmp_pl_resp_lifetime *notify)
d1e348cf
A
122{
123 char *spi;
124
125 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
65c25746 126 plog(ASL_LEVEL_ERR,
d1e348cf
A
127 "invalid spi_size in notification payload.\n");
128 return -1;
129 }
130 spi = val2str((char *)(notify + 1), notify->spi_size);
131
7ebaebe2 132 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
133 "notification message ISAKMP-SA RESPONDER-LIFETIME, "
134 "doi=%d proto_id=%d spi=%s(size=%d).\n",
135 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
136
137 /* TODO */
138 #if 0
139 struct isakmp_pl_attr *attrpl;
140 int len = ntohs(notify->h.len) - (sizeof(*notify) + notify->spi_size);
141
142 attrpl = (struct isakmp_pl_attr *)((char *)(notify + 1) + notify->spi_size);
143 while (len > 0) {
144 }
145 #endif
146
147 racoon_free(spi);
148 return 0;
149}
150
151static int
65c25746 152isakmp_ph2_responder_lifetime (phase2_handle_t *iph2, struct isakmp_pl_resp_lifetime *notify)
d1e348cf
A
153{
154 char *spi;
155
156 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
65c25746 157 plog(ASL_LEVEL_ERR,
d1e348cf
A
158 "invalid spi_size in notification payload.\n");
159 return -1;
160 }
161 spi = val2str((char *)(notify + 1), notify->spi_size);
162
7ebaebe2 163 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
164 "notification message IPSEC-SA RESPONDER-LIFETIME, "
165 "doi=%d proto_id=%d spi=%s(size=%d).\n",
166 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
167
168 /* TODO */
169
170 racoon_free(spi);
171 return 0;
172}
173
52b7d2ce
A
174/* \f%%%
175 * Information Exchange
176 */
177/*
178 * receive Information
179 */
180int
65c25746 181isakmp_info_recv(phase1_handle_t *iph1, vchar_t *msg0)
52b7d2ce
A
182{
183 vchar_t *msg = NULL;
d1e348cf
A
184 vchar_t *pbuf = NULL;
185 u_int32_t msgid = 0;
52b7d2ce
A
186 int error = -1;
187 struct isakmp *isakmp;
188 struct isakmp_gen *gen;
85f41bec 189 struct isakmp_parse_t *pa;
52b7d2ce
A
190 void *p;
191 vchar_t *hash, *payload;
192 struct isakmp_gen *nd;
193 u_int8_t np;
194 int encrypted;
e8d9021d 195 int flag = 0;
d06a7ccb 196 int disconnect = 0;
52b7d2ce 197
7ebaebe2 198 plog(ASL_LEVEL_NOTICE, "receive Information.\n");
52b7d2ce
A
199
200 encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
d1e348cf 201 msgid = ((struct isakmp *)msg0->v)->msgid;
52b7d2ce
A
202
203 /* Use new IV to decrypt Informational message. */
204 if (encrypted) {
52b7d2ce
A
205 struct isakmp_ivm *ivm;
206
d1e348cf 207 if (iph1->ivm == NULL) {
65c25746 208 plog(ASL_LEVEL_ERR, "iph1->ivm == NULL\n");
d1e348cf
A
209 return -1;
210 }
211
52b7d2ce
A
212 /* compute IV */
213 ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
d1e348cf 214 if (ivm == NULL) {
65c25746 215 plog(ASL_LEVEL_ERR,
e8d9021d 216 "failed to compute IV\n");
52b7d2ce 217 return -1;
d1e348cf 218 }
52b7d2ce
A
219
220 msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
221 oakley_delivm(ivm);
d1e348cf 222 if (msg == NULL) {
65c25746 223 plog(ASL_LEVEL_ERR,
e8d9021d 224 "failed to decrypt packet\n");
52b7d2ce 225 return -1;
d1e348cf 226 }
52b7d2ce
A
227
228 } else
229 msg = vdup(msg0);
230
231 /* Safety check */
232 if (msg->l < sizeof(*isakmp) + sizeof(*gen)) {
65c25746 233 plog(ASL_LEVEL_ERR,
52b7d2ce
A
234 "ignore information because the "
235 "message is way too short\n");
236 goto end;
237 }
238
239 isakmp = (struct isakmp *)msg->v;
240 gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
241 np = gen->np;
242
243 if (encrypted) {
244 if (isakmp->np != ISAKMP_NPTYPE_HASH) {
65c25746 245 plog(ASL_LEVEL_ERR,
52b7d2ce
A
246 "ignore information because the "
247 "message has no hash payload.\n");
248 goto end;
249 }
250
65c25746 251 if (!FSM_STATE_IS_ESTABLISHED(iph1->status) &&
d1e348cf 252 (!iph1->approval || !iph1->skeyid_a)) {
65c25746 253 plog(ASL_LEVEL_ERR,
52b7d2ce
A
254 "ignore information because ISAKMP-SA "
255 "has not been established yet.\n");
256 goto end;
257 }
258
259 /* Safety check */
260 if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) {
65c25746 261 plog(ASL_LEVEL_ERR,
52b7d2ce
A
262 "ignore information because the "
263 "message is too short\n");
264 goto end;
265 }
266
267 p = (caddr_t) gen + sizeof(struct isakmp_gen);
268 nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len));
269
270 /* nd length check */
271 if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) +
272 ntohs(gen->len))) {
65c25746 273 plog(ASL_LEVEL_ERR,
52b7d2ce
A
274 "too long payload length (broken message?)\n");
275 goto end;
276 }
277
278 if (ntohs(nd->len) < sizeof(*nd)) {
65c25746 279 plog(ASL_LEVEL_ERR,
52b7d2ce
A
280 "too short payload length (broken message?)\n");
281 goto end;
282 }
283
284 payload = vmalloc(ntohs(nd->len));
285 if (payload == NULL) {
65c25746 286 plog(ASL_LEVEL_ERR,
52b7d2ce
A
287 "cannot allocate memory\n");
288 goto end;
289 }
290
291 memcpy(payload->v, (caddr_t) nd, ntohs(nd->len));
292
293 /* compute HASH */
294 hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
295 if (hash == NULL) {
65c25746 296 plog(ASL_LEVEL_ERR,
52b7d2ce
A
297 "cannot compute hash\n");
298
299 vfree(payload);
300 goto end;
301 }
302
303 if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) {
65c25746 304 plog(ASL_LEVEL_ERR,
52b7d2ce
A
305 "ignore information due to hash length mismatch\n");
306
307 vfree(hash);
308 vfree(payload);
309 goto end;
310 }
311
f255a978 312 if (timingsafe_bcmp(p, hash->v, hash->l) != 0) {
65c25746 313 plog(ASL_LEVEL_ERR,
52b7d2ce
A
314 "ignore information due to hash mismatch\n");
315
316 vfree(hash);
317 vfree(payload);
318 goto end;
319 }
320
65c25746 321 plog(ASL_LEVEL_DEBUG, "hash validated.\n");
52b7d2ce
A
322
323 vfree(hash);
324 vfree(payload);
325 } else {
65c25746 326 /* make sure phase 1 was not yet at encrypted state */
52b7d2ce
A
327 switch (iph1->etype) {
328 case ISAKMP_ETYPE_AGG:
65c25746
A
329 // %%%%% should also check for unity/mode cfg - last pkt is encrypted in such cases
330 if (!FSM_STATE_IS_ESTABLISHED(iph1->status) &&
331 ((iph1->side == INITIATOR && iph1->status == IKEV1_STATE_AGG_I_MSG3SENT) ||
332 (iph1->side == RESPONDER && iph1->status == IKEV1_STATE_AGG_R_MSG3RCVD))) {
333 break;
334 }
d06a7ccb 335 /*FALLTHRU*/
52b7d2ce 336 case ISAKMP_ETYPE_IDENT:
65c25746
A
337 if (!FSM_STATE_IS_ESTABLISHED(iph1->status) &&
338 ((iph1->side == INITIATOR && (iph1->status == IKEV1_STATE_IDENT_I_MSG5SENT
339 || iph1->status == IKEV1_STATE_IDENT_I_MSG6RCVD)) ||
340 (iph1->side == RESPONDER && (iph1->status == IKEV1_STATE_IDENT_R_MSG5RCVD)))) {
52b7d2ce
A
341 break;
342 }
343 /*FALLTHRU*/
344 default:
d06a7ccb
A
345 if ((np == ISAKMP_NPTYPE_NONE) &&
346 !FSM_STATE_IS_ESTABLISHED(iph1->status) &&
347 (iph1->side == INITIATOR && (iph1->status == IKEV1_STATE_AGG_I_MSG1SENT))) {
348 // proposal rejected by peer, terminate now.
349 disconnect = 1;
350 }
351
65c25746 352 plog(ASL_LEVEL_ERR,
d06a7ccb
A
353 "%s message must be encrypted, status 0x%x, side %d\n",
354 s_isakmp_nptype(np), iph1->status, iph1->side);
d1e348cf 355 error = 0;
52b7d2ce
A
356 goto end;
357 }
358 }
359
d1e348cf 360 if (!(pbuf = isakmp_parse(msg))) {
65c25746 361 plog(ASL_LEVEL_ERR,
d1e348cf
A
362 "failed to parse msg");
363 error = -1;
364 goto end;
365 }
366
367 error = 0;
85f41bec 368 for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { // Wcast-align fix (void*) - aligned buffer of aligned (unpacked) structs
d1e348cf
A
369 switch (pa->type) {
370 case ISAKMP_NPTYPE_HASH:
371 /* Handled above */
372 break;
373 case ISAKMP_NPTYPE_N:
d06a7ccb
A
374 if ((ntohs(((struct isakmp_pl_n *)pa->ptr)->type) == ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN) &&
375 !FSM_STATE_IS_ESTABLISHED(iph1->status) &&
376 (iph1->side == INITIATOR && (iph1->status == IKEV1_STATE_AGG_I_MSG1SENT))) {
377 // proposal rejected by peer, terminate now.
378 disconnect = 1;
379 plog(ASL_LEVEL_ERR,
380 "%s message with %s notification receveid, status 0x%x, side %d\n",
381 s_isakmp_nptype(np), s_isakmp_notify_msg(ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN), iph1->status, iph1->side);
382 break;
383 }
d1e348cf
A
384 error = isakmp_info_recv_n(iph1,
385 (struct isakmp_pl_n *)pa->ptr,
386 msgid, encrypted);
387 break;
388 case ISAKMP_NPTYPE_D:
389 error = isakmp_info_recv_d(iph1,
390 (struct isakmp_pl_d *)pa->ptr,
391 msgid, encrypted);
392 break;
393 case ISAKMP_NPTYPE_NONCE:
394 /* XXX to be 6.4.2 ike-01.txt */
395 /* XXX IV is to be synchronized. */
65c25746 396 plog(ASL_LEVEL_ERR,
d1e348cf
A
397 "ignore Acknowledged Informational\n");
398 break;
399 default:
400 /* don't send information, see isakmp_ident_r1() */
401 error = 0;
65c25746 402 plog(ASL_LEVEL_ERR,
d1e348cf
A
403 "reject the packet, "
404 "received unexpected payload type %s.\n",
405 s_isakmp_nptype(gen->np));
406 }
407 if(error < 0) {
408 break;
409 } else {
410 flag |= error;
411 }
412 }
d1e348cf 413end:
d1e348cf
A
414 if (msg != NULL)
415 vfree(msg);
416 if (pbuf != NULL)
417 vfree(pbuf);
d06a7ccb
A
418 if (disconnect) {
419 ike_session_t *session = NULL;
420
421 if (session = iph1->parent_session) {
422 gettimeofday(&session->stop_timestamp, NULL);
423 if (!session->term_reason) {
424 session->term_reason = ike_session_stopped_by_peer;
425 }
426 ike_session_purge_ph1s_by_session(session);
427 }
428 }
d1e348cf
A
429 return error;
430}
431
432/*
433 * handling of Notification payload
434 */
435static int
65c25746 436isakmp_info_recv_n(phase1_handle_t *iph1, struct isakmp_pl_n *notify, u_int32_t msgid, int encrypted)
d1e348cf
A
437{
438 u_int type;
d1e348cf
A
439 vchar_t *ndata;
440 char *nraw;
441 size_t l;
442 char *spi;
443
444 type = ntohs(notify->type);
445
446 switch (type) {
447 case ISAKMP_NTYPE_CONNECTED:
448 case ISAKMP_NTYPE_REPLAY_STATUS:
449#ifdef ENABLE_HYBRID
450 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
451#endif
452 /* do something */
52b7d2ce 453 break;
d1e348cf
A
454 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
455 if (encrypted) {
456 return(isakmp_ph1_responder_lifetime(iph1,
457 (struct isakmp_pl_resp_lifetime *)notify));
458 }
459 break;
460 case ISAKMP_NTYPE_INITIAL_CONTACT:
e8d9021d 461 if (encrypted) {
d1e348cf
A
462 info_recv_initialcontact(iph1);
463 return 0;
e8d9021d 464 }
52b7d2ce 465 break;
d1e348cf
A
466#ifdef ENABLE_DPD
467 case ISAKMP_NTYPE_R_U_THERE:
468 if (encrypted)
469 return isakmp_info_recv_r_u(iph1,
470 (struct isakmp_pl_ru *)notify, msgid);
471 break;
472 case ISAKMP_NTYPE_R_U_THERE_ACK:
473 if (encrypted)
474 return isakmp_info_recv_r_u_ack(iph1,
475 (struct isakmp_pl_ru *)notify, msgid);
52b7d2ce 476 break;
d1e348cf
A
477#endif
478#ifdef ENABLE_VPNCONTROL_PORT
479 case ISAKMP_NTYPE_LOAD_BALANCE:
480 isakmp_info_recv_lb(iph1, (struct isakmp_pl_lb *)notify, encrypted);
481 break;
482#endif
483
52b7d2ce 484 default:
d1e348cf
A
485 {
486 /* XXX there is a potential of dos attack. */
487 if(type >= ISAKMP_NTYPE_MINERROR &&
488 type <= ISAKMP_NTYPE_MAXERROR) {
489 if (msgid == 0) {
490 /* don't think this realy deletes ph1 ? */
65c25746
A
491 plog(ASL_LEVEL_ERR,
492 "Delete Phase 1 handle.\n");
d1e348cf
A
493 return -1;
494 } else {
65c25746
A
495 if (ike_session_getph2bymsgid(iph1, msgid) == NULL) {
496 plog(ASL_LEVEL_ERR,
497 "Fatal %s notify messsage, "
498 "Phase 1 should be deleted.\n",
d1e348cf
A
499 s_isakmp_notify_msg(type));
500 } else {
65c25746
A
501 plog(ASL_LEVEL_ERR,
502 "Fatal %s notify messsage, "
503 "Phase 2 should be deleted.\n",
d1e348cf
A
504 s_isakmp_notify_msg(type));
505 }
506 }
507 } else {
65c25746
A
508 plog(ASL_LEVEL_ERR,
509 "Unhandled notify message %s, "
510 "no Phase 2 handle found.\n",
d1e348cf
A
511 s_isakmp_notify_msg(type));
512 }
513 }
514 break;
515 }
516
517 /* get spi if specified and allocate */
518 if(notify->spi_size > 0) {
519 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
65c25746
A
520 plog(ASL_LEVEL_ERR,
521 "Invalid spi_size in notification payload.\n");
d1e348cf
A
522 return -1;
523 }
524 spi = val2str((char *)(notify + 1), notify->spi_size);
525
7ebaebe2 526 plog(ASL_LEVEL_NOTICE,
65c25746 527 "Notification message %d:%s, "
d1e348cf
A
528 "doi=%d proto_id=%d spi=%s(size=%d).\n",
529 type, s_isakmp_notify_msg(type),
530 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
531
532 racoon_free(spi);
533 }
534
535 /* Send the message data to the logs */
536 if(type >= ISAKMP_NTYPE_MINERROR &&
537 type <= ISAKMP_NTYPE_MAXERROR) {
538 l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
539 if (l > 0) {
540 nraw = (char*)notify;
541 nraw += sizeof(*notify) + notify->spi_size;
542 if ((ndata = vmalloc(l)) != NULL) {
543 memcpy(ndata->v, nraw, ndata->l);
65c25746 544 plog(ASL_LEVEL_ERR,
d1e348cf
A
545 "Message: '%s'.\n",
546 binsanitize(ndata->v, ndata->l));
547 vfree(ndata);
548 } else {
65c25746 549 plog(ASL_LEVEL_ERR,
d1e348cf
A
550 "Cannot allocate memory\n");
551 }
552 }
553 }
554 return 0;
555}
556
e8d9021d 557#ifdef ENABLE_VPNCONTROL_PORT
65c25746
A
558static void
559isakmp_info_vpncontrol_notify_ike_failed (phase1_handle_t *iph1, int isakmp_info_initiator, int type, vchar_t *data)
e8d9021d 560{
d06a7ccb 561 u_int32_t address = iph1_get_remote_v4_address(iph1);
e8d9021d
A
562 u_int32_t fail_reason;
563
564 /* notify the API that we have received the delete */
d06a7ccb 565
e8d9021d
A
566 if (isakmp_info_initiator == FROM_REMOTE) {
567 int premature = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_PREMATURE);
568 int expired = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_EXPIRED);
569
570 if (premature) {
571 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_PREMATURE;
65c25746 572 plog(ASL_LEVEL_NOTICE, ">>> Server reports client's certificate is pre-mature\n");
e8d9021d
A
573 } else if (expired) {
574 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_EXPIRED;
65c25746 575 plog(ASL_LEVEL_NOTICE, ">>> Server reports client's certificate is expired\n");
e8d9021d
A
576 } else {
577 fail_reason = type;
578 }
579 vpncontrol_notify_ike_failed(fail_reason, isakmp_info_initiator, address, 0, NULL);
580 return;
581 } else {
582 /* FROM_LOCAL */
583 if (type == ISAKMP_INTERNAL_ERROR ||
584 type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) {
585 int premature = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_PREMATURE);
586 int expired = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_EXPIRED);
587 int subjname = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_INVALID_SUBJNAME);
588 int subjaltname = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_INVALID_SUBJALTNAME);
589
590 if (premature) {
591 fail_reason = VPNCTL_NTYPE_PEER_CERT_PREMATURE;
65c25746 592 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate is pre-mature\n");
e8d9021d
A
593 } else if (expired) {
594 fail_reason = VPNCTL_NTYPE_PEER_CERT_EXPIRED;
65c25746 595 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate is expired\n");
e8d9021d
A
596 } else if (subjname) {
597 fail_reason = VPNCTL_NTYPE_PEER_CERT_INVALID_SUBJNAME;
65c25746 598 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate subject name not valid\n");
e8d9021d
A
599 } else if (subjaltname) {
600 fail_reason = VPNCTL_NTYPE_PEER_CERT_INVALID_SUBJALTNAME;
65c25746 601 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate subject alternate name not valid\n");
e8d9021d
A
602 } else {
603 fail_reason = type;
604 }
605 (void)vpncontrol_notify_ike_failed(fail_reason, isakmp_info_initiator, address,
606 (data ? data->l : 0), (u_int8_t *)(data ? data->v : NULL));
607 return;
608 }
609 }
610}
611#endif /* ENABLE_VPNCONTROL_PORT */
612
d1e348cf
A
613/*
614 * handling of Deletion payload
615 */
616static int
65c25746 617isakmp_info_recv_d(phase1_handle_t *iph1, struct isakmp_pl_d *delete, u_int32_t msgid, int encrypted)
d1e348cf
A
618{
619 int tlen, num_spi;
65c25746 620 phase1_handle_t *del_ph1;
d1e348cf
A
621 union {
622 u_int32_t spi32;
623 u_int16_t spi16[2];
624 } spi;
625
626 if (ntohl(delete->doi) != IPSEC_DOI) {
65c25746 627 plog(ASL_LEVEL_ERR,
d1e348cf
A
628 "delete payload with invalid doi:%d.\n",
629 ntohl(delete->doi));
630#ifdef ENABLE_HYBRID
631 /*
632 * At deconnexion time, Cisco VPN client does this
633 * with a zero DOI. Don't give up in that situation.
634 */
635 if (((iph1->mode_cfg->flags &
636 ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0))
637 return 0;
638#else
639 return 0;
640#endif
641 }
642
643 num_spi = ntohs(delete->num_spi);
644 tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d);
645
646 if (tlen != num_spi * delete->spi_size) {
65c25746 647 plog(ASL_LEVEL_ERR,
d1e348cf
A
648 "deletion payload with invalid length.\n");
649 return 0;
650 }
651
7ebaebe2 652 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
653 "delete payload for protocol %s\n",
654 s_ipsecdoi_proto(delete->proto_id));
655
656 if(!iph1->rmconf->weak_phase1_check && !encrypted) {
65c25746 657 plog(ASL_LEVEL_WARNING,
d1e348cf
A
658 "Ignoring unencrypted delete payload "
659 "(check the weak_phase1_check option)\n");
660 return 0;
661 }
662
663 switch (delete->proto_id) {
664 case IPSECDOI_PROTO_ISAKMP:
665 if (delete->spi_size != sizeof(isakmp_index)) {
65c25746 666 plog(ASL_LEVEL_ERR,
d1e348cf
A
667 "delete payload with strange spi "
668 "size %d(proto_id:%d)\n",
669 delete->spi_size, delete->proto_id);
670 return 0;
671 }
672
65c25746 673 del_ph1 = ike_session_getph1byindex(iph1->parent_session, (isakmp_index *)(delete + 1));
d1e348cf
A
674 if(del_ph1 != NULL){
675
676 // hack: start a rekey now, if one was pending (only for client).
677 if (del_ph1->sce_rekey &&
678 del_ph1->parent_session &&
679 del_ph1->parent_session->is_client &&
d9c572c0
A
680 del_ph1->parent_session->established &&
681 !(del_ph1->rmconf->natt_multiple_user &&
682 del_ph1->parent_session->is_l2tpvpn_ipsec)) {
fce29cd9 683 isakmp_ph1rekeyexpire(del_ph1, FALSE);
d1e348cf
A
684 }
685
d1e348cf
A
686 if (del_ph1->scr)
687 SCHED_KILL(del_ph1->scr);
688
689 /*
690 * Do not delete IPsec SAs when receiving an IKE delete notification.
691 * Just delete the IKE SA.
692 */
693#ifdef ENABLE_VPNCONTROL_PORT
e8d9021d 694 if (del_ph1->started_by_api || (del_ph1->is_rekey && del_ph1->parent_session && del_ph1->parent_session->is_client)) {
65c25746 695 if (ike_session_islast_ph1(del_ph1)) {
e8d9021d 696 isakmp_info_vpncontrol_notify_ike_failed(del_ph1, FROM_REMOTE, VPNCTL_NTYPE_PH1_DELETE, NULL);
d1e348cf 697 }
e8d9021d 698 }
d1e348cf 699#endif
1760d65d
A
700 if (del_ph1->rmconf->natt_multiple_user &&
701 del_ph1->parent_session->is_l2tpvpn_ipsec) {
7ebaebe2 702 plog(ASL_LEVEL_NOTICE, "Ignoring IKE delete from peer for L2TP server\n");
1760d65d
A
703 break;
704 }
d1e348cf
A
705 isakmp_ph1expire(del_ph1);
706 }
707 break;
708
709 case IPSECDOI_PROTO_IPSEC_AH:
710 case IPSECDOI_PROTO_IPSEC_ESP:
711 if (delete->spi_size != sizeof(u_int32_t)) {
65c25746 712 plog(ASL_LEVEL_ERR,
d1e348cf
A
713 "delete payload with strange spi "
714 "size %d(proto_id:%d)\n",
715 delete->spi_size, delete->proto_id);
716 return 0;
717 }
1760d65d
A
718 if (iph1->rmconf->natt_multiple_user &&
719 iph1->parent_session->is_l2tpvpn_ipsec) {
d9c572c0
A
720 uint32_t *ph2_spi = ALIGNED_CAST(u_int32_t *)(delete + 1);
721 phase2_handle_t *iph2 = ike_session_getph2bysaidx(iph1->local, iph1->remote, delete->proto_id, ph2_spi[0]);
722
723 if (iph2 != NULL) {
724 iph2->is_defunct = 1;
7ebaebe2 725 plog(ASL_LEVEL_NOTICE, "Ignoring SA delete from peer for L2TP server\n");
d9c572c0
A
726 break;
727 }
1760d65d 728 }
d1e348cf 729 purge_ipsec_spi(iph1->remote, delete->proto_id,
65c25746 730 ALIGNED_CAST(u_int32_t *)(delete + 1), num_spi, NULL, NULL); // Wcast-align fix (void*) - delete payload is aligned
52b7d2ce 731 break;
d1e348cf
A
732
733 case IPSECDOI_PROTO_IPCOMP:
734 /* need to handle both 16bit/32bit SPI */
735 memset(&spi, 0, sizeof(spi));
736 if (delete->spi_size == sizeof(spi.spi16[1])) {
737 memcpy(&spi.spi16[1], delete + 1,
738 sizeof(spi.spi16[1]));
739 } else if (delete->spi_size == sizeof(spi.spi32))
740 memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32));
741 else {
65c25746 742 plog(ASL_LEVEL_ERR,
d1e348cf
A
743 "delete payload with strange spi "
744 "size %d(proto_id:%d)\n",
745 delete->spi_size, delete->proto_id);
746 return 0;
747 }
748 purge_ipsec_spi(iph1->remote, delete->proto_id,
65c25746 749 &spi.spi32, num_spi, NULL, NULL);
d1e348cf
A
750 break;
751
752 default:
65c25746 753 plog(ASL_LEVEL_ERR,
d1e348cf
A
754 "deletion message received, "
755 "invalid proto_id: %d\n",
756 delete->proto_id);
757 return 0;
52b7d2ce
A
758 }
759
7ebaebe2 760 plog(ASL_LEVEL_NOTICE, "purged SAs.\n");
52b7d2ce
A
761
762 return 0;
763}
764
765/*
766 * send Delete payload (for ISAKMP SA) in Informational exchange.
767 */
768int
65c25746 769isakmp_info_send_d1(phase1_handle_t *iph1)
52b7d2ce
A
770{
771 struct isakmp_pl_d *d;
772 vchar_t *payload = NULL;
773 int tlen;
774 int error = 0;
775
65c25746 776 if (!FSM_STATE_IS_ESTABLISHED(iph1->status))
52b7d2ce
A
777 return 0;
778
779 /* create delete payload */
780
781 /* send SPIs of inbound SAs. */
782 /* XXX should send outbound SAs's ? */
783 tlen = sizeof(*d) + sizeof(isakmp_index);
784 payload = vmalloc(tlen);
785 if (payload == NULL) {
65c25746 786 plog(ASL_LEVEL_ERR,
52b7d2ce
A
787 "failed to get buffer for payload.\n");
788 return errno;
789 }
790
791 d = (struct isakmp_pl_d *)payload->v;
792 d->h.np = ISAKMP_NPTYPE_NONE;
793 d->h.len = htons(tlen);
794 d->doi = htonl(IPSEC_DOI);
795 d->proto_id = IPSECDOI_PROTO_ISAKMP;
796 d->spi_size = sizeof(isakmp_index);
797 d->num_spi = htons(1);
798 memcpy(d + 1, &iph1->index, sizeof(isakmp_index));
799
800 error = isakmp_info_send_common(iph1, payload,
801 ISAKMP_NPTYPE_D, 0);
802 vfree(payload);
52b7d2ce
A
803 return error;
804}
805
806/*
807 * send Delete payload (for IPsec SA) in Informational exchange, based on
808 * pfkey msg. It sends always single SPI.
809 */
810int
65c25746 811isakmp_info_send_d2(phase2_handle_t *iph2)
52b7d2ce 812{
65c25746 813 phase1_handle_t *iph1;
52b7d2ce
A
814 struct saproto *pr;
815 struct isakmp_pl_d *d;
816 vchar_t *payload = NULL;
817 int tlen;
818 int error = 0;
819 u_int8_t *spi;
820
65c25746 821 if (!FSM_STATE_IS_ESTABLISHED(iph2->status))
52b7d2ce 822 return 0;
d9c572c0 823
52b7d2ce
A
824 /*
825 * don't send delete information if there is no phase 1 handler.
826 * It's nonsensical to negotiate phase 1 to send the information.
827 */
d1e348cf
A
828 iph1 = ike_session_get_established_ph1(iph2->parent_session);
829 if (!iph1) {
65c25746 830 iph1 = ike_session_getph1byaddr(iph2->parent_session, iph2->src, iph2->dst);
d1e348cf
A
831 }
832 if (iph1 == NULL){
7ebaebe2 833 plog(ASL_LEVEL_NOTICE,
d1e348cf 834 "No ph1 handler found, could not send DELETE_SA\n");
52b7d2ce 835 return 0;
d1e348cf 836 }
52b7d2ce
A
837
838 /* create delete payload */
839 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
840
841 /* send SPIs of inbound SAs. */
842 /*
843 * XXX should I send outbound SAs's ?
844 * I send inbound SAs's SPI only at the moment because I can't
845 * decode any more if peer send encoded packet without aware of
846 * deletion of SA. Outbound SAs don't come under the situation.
847 */
848 tlen = sizeof(*d) + pr->spisize;
849 payload = vmalloc(tlen);
850 if (payload == NULL) {
6b88cae0 851 plog(ASL_LEVEL_ERR,
52b7d2ce
A
852 "failed to get buffer for payload.\n");
853 return errno;
854 }
855
856 d = (struct isakmp_pl_d *)payload->v;
857 d->h.np = ISAKMP_NPTYPE_NONE;
858 d->h.len = htons(tlen);
859 d->doi = htonl(IPSEC_DOI);
860 d->proto_id = pr->proto_id;
861 d->spi_size = pr->spisize;
862 d->num_spi = htons(1);
863 /*
864 * XXX SPI bits are left-filled, for use with IPComp.
865 * we should be switching to variable-length spi field...
866 */
867 spi = (u_int8_t *)&pr->spi;
868 spi += sizeof(pr->spi);
869 spi -= pr->spisize;
870 memcpy(d + 1, spi, pr->spisize);
871
872 error = isakmp_info_send_common(iph1, payload,
873 ISAKMP_NPTYPE_D, 0);
874 vfree(payload);
875 }
876
877 return error;
878}
879
880/*
65c25746 881 * send Notification payload (without ISAKMP SA) in an Informational exchange
52b7d2ce
A
882 */
883int
65c25746
A
884isakmp_info_send_nx(struct isakmp *isakmp, struct sockaddr_storage *remote, struct sockaddr_storage *local,
885 int type, vchar_t *data)
52b7d2ce 886{
65c25746 887 phase1_handle_t *iph1 = NULL;
52b7d2ce
A
888 struct remoteconf *rmconf;
889 vchar_t *payload = NULL;
890 int tlen;
891 int error = -1;
892 struct isakmp_pl_n *n;
893 int spisiz = 0; /* see below */
1760d65d 894 ike_session_t *sess = ike_session_get_session(local, remote, FALSE, NULL);
52b7d2ce
A
895
896 /* search appropreate configuration */
897 rmconf = getrmconf(remote);
898 if (rmconf == NULL) {
6b88cae0 899 plog(ASL_LEVEL_ERR,
52b7d2ce
A
900 "no configuration found for peer address.\n");
901 goto end;
902 }
903
904 /* add new entry to isakmp status table. */
65c25746 905 iph1 = ike_session_newph1(ISAKMP_VERSION_NUMBER_IKEV1);
d1e348cf 906 if (iph1 == NULL) {
6b88cae0 907 plog(ASL_LEVEL_ERR,
d1e348cf 908 "failed to allocate ph1");
52b7d2ce 909 return -1;
d1e348cf 910 }
52b7d2ce
A
911
912 memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
913 isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
65c25746 914 fsm_set_state(&iph1->status, IKEV1_STATE_INFO);
52b7d2ce 915 iph1->rmconf = rmconf;
65c25746 916 retain_rmconf(iph1->rmconf);
52b7d2ce
A
917 iph1->side = INITIATOR;
918 iph1->version = isakmp->v;
919 iph1->flags = 0;
920 iph1->msgid = 0; /* XXX */
921#ifdef ENABLE_HYBRID
d1e348cf
A
922 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
923 error = -1;
924 goto end;
925 }
52b7d2ce
A
926#endif
927#ifdef ENABLE_FRAG
928 iph1->frag = 0;
929 iph1->frag_chain = NULL;
930#endif
931
932 /* copy remote address */
d1e348cf 933 if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
6b88cae0 934 plog(ASL_LEVEL_ERR,
d1e348cf
A
935 "failed to copy ph1 addresses");
936 error = -1;
47612122 937 iph1 = NULL; /* deleted in copy_ph1addresses */
d1e348cf
A
938 goto end;
939 }
52b7d2ce
A
940
941 tlen = sizeof(*n) + spisiz;
942 if (data)
943 tlen += data->l;
944 payload = vmalloc(tlen);
945 if (payload == NULL) {
6b88cae0 946 plog(ASL_LEVEL_ERR,
52b7d2ce 947 "failed to get buffer to send.\n");
d1e348cf 948 error = -1;
52b7d2ce
A
949 goto end;
950 }
951
952 n = (struct isakmp_pl_n *)payload->v;
953 n->h.np = ISAKMP_NPTYPE_NONE;
954 n->h.len = htons(tlen);
955 n->doi = htonl(IPSEC_DOI);
956 n->proto_id = IPSECDOI_KEY_IKE;
957 n->spi_size = spisiz;
958 n->type = htons(type);
959 if (spisiz)
d1e348cf 960 memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */
52b7d2ce
A
961 if (data)
962 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
963
964#ifdef ENABLE_VPNCONTROL_PORT
e8d9021d 965 isakmp_info_vpncontrol_notify_ike_failed(iph1, FROM_LOCAL, type, data);
52b7d2ce 966#endif
65c25746
A
967 if (ike_session_link_phase1(sess, iph1))
968 fatal_error(-1);
969
52b7d2ce
A
970 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
971 vfree(payload);
6b88cae0 972end:
52b7d2ce 973 if (iph1 != NULL)
65c25746 974 ike_session_unlink_phase1(iph1);
52b7d2ce
A
975
976 return error;
977}
978
979/*
65c25746 980 * send Notification payload (with ISAKMP SA) in an Informational exchange
52b7d2ce
A
981 */
982int
65c25746 983isakmp_info_send_n1(phase1_handle_t *iph1, int type, vchar_t *data)
52b7d2ce
A
984{
985 vchar_t *payload = NULL;
986 int tlen;
987 int error = 0;
988 struct isakmp_pl_n *n;
989 int spisiz;
990
991 /*
992 * note on SPI size: which description is correct? I have chosen
993 * this to be 0.
994 *
995 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by
996 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0.
997 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified
998 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
999 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
1000 */
1001 if (type == ISAKMP_NTYPE_INITIAL_CONTACT ||
1002 type == ISAKMP_NTYPE_LOAD_BALANCE)
1003 spisiz = sizeof(isakmp_index);
1004 else
1005 spisiz = 0;
1006
1007 tlen = sizeof(*n) + spisiz;
1008 if (data)
1009 tlen += data->l;
1010 payload = vmalloc(tlen);
1011 if (payload == NULL) {
6b88cae0 1012 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1013 "failed to get buffer to send.\n");
1014 return errno;
1015 }
1016
1017 n = (struct isakmp_pl_n *)payload->v;
1018 n->h.np = ISAKMP_NPTYPE_NONE;
1019 n->h.len = htons(tlen);
1020 n->doi = htonl(iph1->rmconf->doitype);
1021 n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */
1022 n->spi_size = spisiz;
1023 n->type = htons(type);
1024 if (spisiz)
1025 memcpy(n + 1, &iph1->index, sizeof(isakmp_index));
1026 if (data)
1027 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
1028
1029#ifdef ENABLE_VPNCONTROL_PORT
e8d9021d 1030 isakmp_info_vpncontrol_notify_ike_failed(iph1, FROM_LOCAL, type, data);
52b7d2ce
A
1031#endif
1032
1033 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
1034 vfree(payload);
52b7d2ce
A
1035 return error;
1036}
1037
1038/*
65c25746 1039 * send Notification payload (with IPsec SA) in an Informational exchange
52b7d2ce
A
1040 */
1041int
65c25746 1042isakmp_info_send_n2(phase2_handle_t *iph2, int type, vchar_t *data)
52b7d2ce 1043{
65c25746 1044 phase1_handle_t *iph1 = iph2->ph1;
52b7d2ce
A
1045 vchar_t *payload = NULL;
1046 int tlen;
1047 int error = 0;
1048 struct isakmp_pl_n *n;
1049 struct saproto *pr;
1050
1051 if (!iph2->approval)
1052 return EINVAL;
1053
1054 pr = iph2->approval->head;
1055
1056 /* XXX must be get proper spi */
1057 tlen = sizeof(*n) + pr->spisize;
1058 if (data)
1059 tlen += data->l;
1060 payload = vmalloc(tlen);
1061 if (payload == NULL) {
6b88cae0 1062 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1063 "failed to get buffer to send.\n");
1064 return errno;
1065 }
1066
1067 n = (struct isakmp_pl_n *)payload->v;
1068 n->h.np = ISAKMP_NPTYPE_NONE;
1069 n->h.len = htons(tlen);
1070 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
1071 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
1072 n->spi_size = pr->spisize;
1073 n->type = htons(type);
85f41bec 1074 memcpy(n + 1, &pr->spi, sizeof(u_int32_t)); // Wcast-align fix - copy instead of assign
52b7d2ce
A
1075 if (data)
1076 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
1077
1078 iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */
1079 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
1080 vfree(payload);
52b7d2ce
A
1081 return error;
1082}
1083
1084/*
1085 * send Information
1086 * When ph1->skeyid_a == NULL, send message without encoding.
1087 */
1088int
65c25746 1089isakmp_info_send_common(phase1_handle_t *iph1, vchar_t *payload, u_int32_t np, int flags)
52b7d2ce 1090{
65c25746 1091 phase2_handle_t *iph2 = NULL;
52b7d2ce
A
1092 vchar_t *hash = NULL;
1093 struct isakmp *isakmp;
1094 struct isakmp_gen *gen;
1095 char *p;
1096 int tlen;
1097 int error = -1;
1098
1099 /* add new entry to isakmp status table */
65c25746 1100 iph2 = ike_session_newph2(ISAKMP_VERSION_NUMBER_IKEV1, PHASE2_TYPE_INFO);
d1e348cf 1101 if (iph2 == NULL) {
65c25746 1102 plog(ASL_LEVEL_ERR,
d1e348cf 1103 "failed to allocate ph2");
52b7d2ce 1104 goto end;
d1e348cf 1105 }
52b7d2ce 1106
65c25746 1107 iph2->dst = dupsaddr(iph1->remote);
d1e348cf 1108 if (iph2->dst == NULL) {
65c25746 1109 plog(ASL_LEVEL_ERR,
d1e348cf 1110 "failed to duplicate remote address");
65c25746 1111 ike_session_delph2(iph2);
d1e348cf
A
1112 goto end;
1113 }
65c25746 1114 iph2->src = dupsaddr(iph1->local);
d1e348cf 1115 if (iph2->src == NULL) {
65c25746 1116 plog(ASL_LEVEL_ERR,
d1e348cf 1117 "failed to duplicate local address");
65c25746 1118 ike_session_delph2(iph2);
d1e348cf
A
1119 goto end;
1120 }
85f41bec 1121 switch (iph1->remote->ss_family) {
52b7d2ce 1122 case AF_INET:
d1e348cf 1123#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
52b7d2ce
A
1124 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1125 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1126#endif
1127 break;
1128#ifdef INET6
1129 case AF_INET6:
d1e348cf 1130#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
52b7d2ce
A
1131 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1132 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
d1e348cf 1133#endif
52b7d2ce
A
1134 break;
1135#endif
1136 default:
65c25746 1137 plog(ASL_LEVEL_ERR,
85f41bec 1138 "invalid family: %d\n", iph1->remote->ss_family);
65c25746 1139 ike_session_delph2(iph2);
52b7d2ce
A
1140 goto end;
1141 }
52b7d2ce 1142 iph2->side = INITIATOR;
65c25746 1143 fsm_set_state(&iph2->status, IKEV1_STATE_INFO);
52b7d2ce
A
1144 iph2->msgid = isakmp_newmsgid2(iph1);
1145
1146 /* get IV and HASH(1) if skeyid_a was generated. */
1147 if (iph1->skeyid_a != NULL) {
1148 iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
1149 if (iph2->ivm == NULL) {
65c25746 1150 plog(ASL_LEVEL_ERR,
d1e348cf 1151 "failed to generate IV");
65c25746 1152 ike_session_delph2(iph2);
52b7d2ce
A
1153 goto end;
1154 }
1155
1156 /* generate HASH(1) */
65c25746 1157 hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
52b7d2ce 1158 if (hash == NULL) {
65c25746 1159 plog(ASL_LEVEL_ERR,
d1e348cf 1160 "failed to generate HASH");
65c25746 1161 ike_session_delph2(iph2);
52b7d2ce
A
1162 goto end;
1163 }
1164
1165 /* initialized total buffer length */
1166 tlen = hash->l;
1167 tlen += sizeof(*gen);
1168 } else {
1169 /* IKE-SA is not established */
1170 hash = NULL;
1171
1172 /* initialized total buffer length */
1173 tlen = 0;
1174 }
1175 if ((flags & ISAKMP_FLAG_A) == 0)
1176 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1177 else
1178 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1179
65c25746 1180 ike_session_link_ph2_to_ph1(iph1, iph2);
52b7d2ce
A
1181
1182 tlen += sizeof(*isakmp) + payload->l;
1183
1184 /* create buffer for isakmp payload */
1185 iph2->sendbuf = vmalloc(tlen);
1186 if (iph2->sendbuf == NULL) {
65c25746 1187 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1188 "failed to get buffer to send.\n");
1189 goto err;
1190 }
1191
1192 /* create isakmp header */
1193 isakmp = (struct isakmp *)iph2->sendbuf->v;
1194 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1195 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1196 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1197 isakmp->v = iph1->version;
1198 isakmp->etype = ISAKMP_ETYPE_INFO;
1199 isakmp->flags = iph2->flags;
1200 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1201 isakmp->len = htonl(tlen);
1202 p = (char *)(isakmp + 1);
1203
1204 /* create HASH payload */
1205 if (hash != NULL) {
1206 gen = (struct isakmp_gen *)p;
1207 gen->np = np & 0xff;
1208 gen->len = htons(sizeof(*gen) + hash->l);
1209 p += sizeof(*gen);
1210 memcpy(p, hash->v, hash->l);
1211 p += hash->l;
1212 }
1213
1214 /* add payload */
1215 memcpy(p, payload->v, payload->l);
1216 p += payload->l;
1217
1218#ifdef HAVE_PRINT_ISAKMP_C
1219 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1220#endif
1221
1222 /* encoding */
1223 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1224 vchar_t *tmp;
1225
1226 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
1227 iph2->ivm->iv);
1228 VPTRINIT(iph2->sendbuf);
d1e348cf 1229 if (tmp == NULL) {
65c25746 1230 plog(ASL_LEVEL_ERR,
d1e348cf 1231 "failed to encrypt packet");
52b7d2ce 1232 goto err;
d1e348cf 1233 }
52b7d2ce
A
1234 iph2->sendbuf = tmp;
1235 }
1236
1237 /* HDR*, HASH(1), N */
1238 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
65c25746 1239 plog(ASL_LEVEL_ERR,
d1e348cf 1240 "failed to send packet");
52b7d2ce
A
1241 VPTRINIT(iph2->sendbuf);
1242 goto err;
1243 }
1244
7ebaebe2 1245 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1246 "sendto Information %s.\n", s_isakmp_nptype(np));
1247
1248 /*
1249 * don't resend notify message because peer can use Acknowledged
1250 * Informational if peer requires the reply of the notify message.
1251 */
1252
1253 /* XXX If Acknowledged Informational required, don't delete ph2handle */
1254 error = 0;
1255 VPTRINIT(iph2->sendbuf);
1256 goto err; /* XXX */
1257
1258end:
1259 if (hash)
1260 vfree(hash);
1261 return error;
1262
1263err:
65c25746 1264 ike_session_unlink_phase2(iph2);
52b7d2ce
A
1265 goto end;
1266}
1267
1268/*
1269 * add a notify payload to buffer by reallocating buffer.
1270 * If buf == NULL, the function only create a notify payload.
1271 *
1272 * XXX Which is SPI to be included, inbound or outbound ?
1273 */
1274vchar_t *
65c25746 1275isakmp_add_pl_n(vchar_t *buf0, u_int8_t **np_p, int type, struct saproto *pr, vchar_t *data)
52b7d2ce
A
1276{
1277 vchar_t *buf = NULL;
1278 struct isakmp_pl_n *n;
1279 int tlen;
1280 int oldlen = 0;
1281
1282 if (*np_p)
1283 **np_p = ISAKMP_NPTYPE_N;
1284
1285 tlen = sizeof(*n) + pr->spisize;
1286
1287 if (data)
1288 tlen += data->l;
1289 if (buf0) {
1290 oldlen = buf0->l;
1291 buf = vrealloc(buf0, buf0->l + tlen);
1292 } else
1293 buf = vmalloc(tlen);
1294 if (!buf) {
65c25746 1295 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1296 "failed to get a payload buffer.\n");
1297 return NULL;
1298 }
1299
1300 n = (struct isakmp_pl_n *)(buf->v + oldlen);
1301 n->h.np = ISAKMP_NPTYPE_NONE;
1302 n->h.len = htons(tlen);
1303 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
1304 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
1305 n->spi_size = pr->spisize;
1306 n->type = htons(type);
85f41bec 1307 memcpy(n + 1, &pr->spi, sizeof(u_int32_t)); // Wcast-align fix - copy instead of assign with cast
52b7d2ce
A
1308 if (data)
1309 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
1310
1311 /* save the pointer of next payload type */
1312 *np_p = &n->h.np;
1313
1314 return buf;
1315}
1316
d1e348cf
A
1317
1318void
65c25746 1319purge_ipsec_spi(struct sockaddr_storage *dst0, int proto, u_int32_t *spi /*network byteorder*/, size_t n, u_int32_t *inbound_spi, size_t *max_inbound_spi)
52b7d2ce
A
1320{
1321 vchar_t *buf = NULL;
1322 struct sadb_msg *msg, *next, *end;
1323 struct sadb_sa *sa;
d1e348cf 1324 struct sadb_lifetime *lt;
85f41bec 1325 struct sockaddr_storage *src, *dst;
65c25746 1326 phase2_handle_t *iph2;
d1e348cf 1327 u_int64_t created;
65c25746 1328 size_t i, j = 0;
52b7d2ce
A
1329 caddr_t mhp[SADB_EXT_MAX + 1];
1330
1331 buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto));
1332 if (buf == NULL) {
7ebaebe2 1333 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1334 "pfkey_dump_sadb returned nothing.\n");
1335 return;
1336 }
1337
85f41bec
A
1338 msg = ALIGNED_CAST(struct sadb_msg *)buf->v;
1339 end = ALIGNED_CAST(struct sadb_msg *)(buf->v + buf->l);
52b7d2ce
A
1340
1341 while (msg < end) {
1342 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1343 break;
85f41bec 1344 next = ALIGNED_CAST(struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
52b7d2ce
A
1345 if (msg->sadb_msg_type != SADB_DUMP) {
1346 msg = next;
1347 continue;
1348 }
1349
1350 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
65c25746 1351 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1352 "pfkey_check (%s)\n", ipsec_strerror());
1353 msg = next;
1354 continue;
1355 }
1356
85f41bec 1357 sa = ALIGNED_CAST(struct sadb_sa *)(mhp[SADB_EXT_SA]); // Wcast-align fix (void*) - buffer of pointers to aligned structs
52b7d2ce
A
1358 if (!sa
1359 || !mhp[SADB_EXT_ADDRESS_SRC]
1360 || !mhp[SADB_EXT_ADDRESS_DST]) {
1361 msg = next;
1362 continue;
1363 }
85f41bec
A
1364 src = ALIGNED_CAST(struct sockaddr_storage*)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); // Wcast-align fix (void*) - buffer of pointers to aligned structs
1365 dst = ALIGNED_CAST(struct sockaddr_storage*)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1366 lt = ALIGNED_CAST(struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
d1e348cf
A
1367 if(lt != NULL)
1368 created = lt->sadb_lifetime_addtime;
1369 else
1370 created = 0;
52b7d2ce
A
1371
1372 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1373 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1374 msg = next;
1375 continue;
1376 }
1377
1378 /* XXX n^2 algorithm, inefficient */
1379
65c25746 1380 /* don't delete inbound SAs at the moment (just save them in inbound_spi) */
52b7d2ce 1381 /* XXX should we remove SAs with opposite direction as well? */
d1e348cf 1382 if (CMPSADDR2(dst0, dst)) {
52b7d2ce
A
1383 msg = next;
1384 continue;
1385 }
1386
1387 for (i = 0; i < n; i++) {
65c25746
A
1388 u_int32_t *i_spi;
1389
52b7d2ce
A
1390 if (spi[i] != sa->sadb_sa_spi)
1391 continue;
1392
52b7d2ce
A
1393 /*
1394 * delete a relative phase 2 handler.
1395 * continue to process if no relative phase 2 handler
1396 * exists.
1397 */
65c25746
A
1398 if (inbound_spi && max_inbound_spi && j < *max_inbound_spi) {
1399 i_spi = &inbound_spi[j];
1400 } else {
1401 i_spi = NULL;
1402 }
1403 iph2 = ike_session_getph2bysaidx2(src, dst, proto, spi[i], i_spi);
1404
1405 pfkey_send_delete(lcconf->sock_pfkey,
1406 msg->sadb_msg_satype,
1407 IPSEC_MODE_ANY,
1408 src, dst, sa->sadb_sa_spi);
1409
d1e348cf 1410 if(iph2 != NULL){
52b7d2ce 1411 delete_spd(iph2);
65c25746
A
1412 ike_session_unlink_phase2(iph2);
1413 if (i_spi) {
1414 j++;
1415 }
52b7d2ce
A
1416 }
1417
7ebaebe2 1418 plog(ASL_LEVEL_NOTICE, "Purged IPsec-SA proto_id=%s spi=%u.\n",
65c25746
A
1419 s_ipsecdoi_proto(proto),
1420 ntohl(spi[i]));
52b7d2ce
A
1421 }
1422
1423 msg = next;
1424 }
1425
65c25746
A
1426 if (max_inbound_spi) {
1427 *max_inbound_spi = j;
1428 }
1429
52b7d2ce
A
1430 if (buf)
1431 vfree(buf);
1432}
1433
1434/*
1435 * delete all phase2 sa relatived to the destination address.
1436 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
1437 * an INITIAL-CONTACT if we have contacted the peer. This matches the
1438 * Sun IKE behavior, and makes rekeying work much better when the peer
1439 * restarts.
1440 */
65c25746
A
1441void
1442info_recv_initialcontact(phase1_handle_t *iph1)
52b7d2ce
A
1443{
1444 vchar_t *buf = NULL;
1445 struct sadb_msg *msg, *next, *end;
1446 struct sadb_sa *sa;
85f41bec 1447 struct sockaddr_storage *src, *dst;
52b7d2ce
A
1448 caddr_t mhp[SADB_EXT_MAX + 1];
1449 int proto_id, i;
65c25746 1450 phase2_handle_t *iph2;
52b7d2ce
A
1451#if 0
1452 char *loc, *rem;
1453#endif
1454
1455 if (f_local)
1456 return;
1457
d1e348cf 1458 // TODO: make sure that is_rekey is cleared for this. and session indicates the same
52b7d2ce 1459#if 0
d1e348cf
A
1460 loc = racoon_strdup(saddrwop2str(iph1->local));
1461 rem = racoon_strdup(saddrwop2str(iph1->remote));
1462 STRDUP_FATAL(loc);
1463 STRDUP_FATAL(rem);
52b7d2ce
A
1464
1465 /*
1466 * Purge all IPSEC-SAs for the peer. We can do this
1467 * the easy way (using a PF_KEY SADB_DELETE extension)
1468 * or we can do it the hard way.
1469 */
1470 for (i = 0; i < pfkey_nsatypes; i++) {
1471 proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype);
1472
7ebaebe2 1473 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1474 "purging %s SAs for %s -> %s\n",
1475 pfkey_satypes[i].ps_name, loc, rem);
1476 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1477 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1478 iph1->local, iph1->remote) == -1) {
65c25746 1479 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1480 "delete_all %s -> %s failed for %s (%s)\n",
1481 loc, rem,
1482 pfkey_satypes[i].ps_name, ipsec_strerror());
1483 goto the_hard_way;
1484 }
1485
65c25746 1486 ike_session_deleteallph2(iph1->local, iph1->remote, proto_id);
52b7d2ce 1487
7ebaebe2 1488 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1489 "purging %s SAs for %s -> %s\n",
1490 pfkey_satypes[i].ps_name, rem, loc);
1491 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1492 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1493 iph1->remote, iph1->local) == -1) {
65c25746 1494 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1495 "delete_all %s -> %s failed for %s (%s)\n",
1496 rem, loc,
1497 pfkey_satypes[i].ps_name, ipsec_strerror());
1498 goto the_hard_way;
1499 }
1500
65c25746 1501 ike_session_deleteallph2(iph1->remote, iph1->local, proto_id);
52b7d2ce
A
1502 }
1503
1504 racoon_free(loc);
1505 racoon_free(rem);
1506 return;
1507
1508 the_hard_way:
1509 racoon_free(loc);
1510 racoon_free(rem);
1511#endif
1512
1513 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
1514 if (buf == NULL) {
7ebaebe2 1515 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1516 "pfkey_dump_sadb returned nothing.\n");
1517 return;
1518 }
1519
85f41bec
A
1520 msg = ALIGNED_CAST(struct sadb_msg *)buf->v;
1521 end = ALIGNED_CAST(struct sadb_msg *)(buf->v + buf->l);
52b7d2ce
A
1522
1523 while (msg < end) {
1524 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1525 break;
85f41bec 1526 next = ALIGNED_CAST(struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
52b7d2ce
A
1527 if (msg->sadb_msg_type != SADB_DUMP) {
1528 msg = next;
1529 continue;
1530 }
1531
1532 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
65c25746 1533 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1534 "pfkey_check (%s)\n", ipsec_strerror());
1535 msg = next;
1536 continue;
1537 }
1538
1539 if (mhp[SADB_EXT_SA] == NULL
1540 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1541 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1542 msg = next;
1543 continue;
1544 }
85f41bec
A
1545 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; // Wcast-align fix (void*) - buffer of pointers to aligned structs
1546 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1547 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
52b7d2ce
A
1548
1549 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1550 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1551 msg = next;
1552 continue;
1553 }
1554
1555 /*
1556 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that
1557 * announces the sender of the message was rebooted.
1558 * it is interpreted to delete all SAs which source address
1559 * is the sender of the message.
1560 * racoon only deletes SA which is matched both the
1561 * source address and the destination accress.
1562 */
1563#ifdef ENABLE_NATT
1564 /*
1565 * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs
1566 * from this peer !
1567 */
1568 if(iph1->natt_flags & NAT_DETECTED){
1569 if (CMPSADDR(iph1->local, src) == 0 &&
1570 CMPSADDR(iph1->remote, dst) == 0)
1571 ;
1572 else if (CMPSADDR(iph1->remote, src) == 0 &&
1573 CMPSADDR(iph1->local, dst) == 0)
1574 ;
1575 else {
1576 msg = next;
1577 continue;
1578 }
1579 } else
1580#endif
1581 /* If there is no NAT-T, we don't have to check addr + port...
1582 * XXX what about a configuration with a remote peers which is not
1583 * NATed, but which NATs some other peers ?
1584 * Here, the INITIAl-CONTACT would also flush all those NATed peers !!
1585 */
1586 if (cmpsaddrwop(iph1->local, src) == 0 &&
1587 cmpsaddrwop(iph1->remote, dst) == 0)
1588 ;
1589 else if (cmpsaddrwop(iph1->remote, src) == 0 &&
1590 cmpsaddrwop(iph1->local, dst) == 0)
1591 ;
1592 else {
1593 msg = next;
1594 continue;
1595 }
1596
1597 /*
1598 * Make sure this is an SATYPE that we manage.
1599 * This is gross; too bad we couldn't do it the
1600 * easy way.
1601 */
1602 for (i = 0; i < pfkey_nsatypes; i++) {
1603 if (pfkey_satypes[i].ps_satype ==
1604 msg->sadb_msg_satype)
1605 break;
1606 }
1607 if (i == pfkey_nsatypes) {
1608 msg = next;
1609 continue;
1610 }
1611
7ebaebe2 1612 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1613 "purging spi=%u.\n", ntohl(sa->sadb_sa_spi));
1614 pfkey_send_delete(lcconf->sock_pfkey,
1615 msg->sadb_msg_satype,
1616 IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi);
1617
1618 /*
1619 * delete a relative phase 2 handler.
1620 * continue to process if no relative phase 2 handler
1621 * exists.
1622 */
1623 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
65c25746 1624 iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
52b7d2ce
A
1625 if (iph2) {
1626 delete_spd(iph2);
65c25746 1627 ike_session_unlink_phase2(iph2);
52b7d2ce
A
1628 }
1629
1630 msg = next;
1631 }
1632
1633 vfree(buf);
1634}
1635
52b7d2ce 1636void
65c25746 1637isakmp_check_notify(struct isakmp_gen *gen /* points to Notify payload */, phase1_handle_t *iph1)
52b7d2ce
A
1638{
1639 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
1640
7ebaebe2 1641 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1642 "Notify Message received\n");
1643
1644 switch (ntohs(notify->type)) {
1645 case ISAKMP_NTYPE_CONNECTED:
52b7d2ce 1646 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
52b7d2ce 1647 case ISAKMP_NTYPE_REPLAY_STATUS:
d1e348cf
A
1648 case ISAKMP_NTYPE_HEARTBEAT:
1649#ifdef ENABLE_HYBRID
1650 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
1651#endif
65c25746
A
1652 plog(ASL_LEVEL_WARNING,
1653 "Ignore %s notification.\n",
d1e348cf 1654 s_isakmp_notify_msg(ntohs(notify->type)));
52b7d2ce
A
1655 break;
1656 case ISAKMP_NTYPE_INITIAL_CONTACT:
65c25746
A
1657 plog(ASL_LEVEL_WARNING,
1658 "Ignore INITIAL-CONTACT notification, "
1659 "because it is only accepted after Phase 1.\n");
52b7d2ce
A
1660 break;
1661 case ISAKMP_NTYPE_LOAD_BALANCE:
65c25746
A
1662 plog(ASL_LEVEL_WARNING,
1663 "Ignore LOAD-BALANCE notification, "
1664 "because it is only accepted after Phase 1.\n");
52b7d2ce 1665 break;
52b7d2ce
A
1666 default:
1667 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
65c25746
A
1668 plog(ASL_LEVEL_ERR,
1669 "Received unknown notification type %s.\n",
d1e348cf 1670 s_isakmp_notify_msg(ntohs(notify->type)));
52b7d2ce
A
1671 }
1672
1673 return;
1674}
1675
d1e348cf 1676void
65c25746 1677isakmp_check_ph2_notify(struct isakmp_gen *gen /* points to Notify payload */, phase2_handle_t *iph2)
d1e348cf
A
1678{
1679 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
1680
7ebaebe2 1681 plog(ASL_LEVEL_NOTICE,
65c25746 1682 "Phase 2 Notify Message received\n");
d1e348cf
A
1683
1684 switch (ntohs(notify->type)) {
1685 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
1686 return((void)isakmp_ph2_responder_lifetime(iph2,
1687 (struct isakmp_pl_resp_lifetime *)notify));
1688 break;
1689 case ISAKMP_NTYPE_CONNECTED:
1690 case ISAKMP_NTYPE_REPLAY_STATUS:
1691 case ISAKMP_NTYPE_HEARTBEAT:
1692#ifdef ENABLE_HYBRID
1693 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
1694#endif
65c25746
A
1695 plog(ASL_LEVEL_WARNING,
1696 "Ignore %s notification.\n",
d1e348cf
A
1697 s_isakmp_notify_msg(ntohs(notify->type)));
1698 break;
1699 case ISAKMP_NTYPE_INITIAL_CONTACT:
65c25746
A
1700 plog(ASL_LEVEL_WARNING,
1701 "Ignore INITIAL-CONTACT notification, "
1702 "because it is only accepted after Phase 1.\n");
d1e348cf
A
1703 break;
1704 case ISAKMP_NTYPE_LOAD_BALANCE:
65c25746
A
1705 plog(ASL_LEVEL_WARNING,
1706 "Ignore LOAD-BALANCE notification, "
1707 "because it is only accepted after Phase 1.\n");
d1e348cf
A
1708 break;
1709 default:
1710 isakmp_info_send_n1(iph2->ph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
65c25746
A
1711 plog(ASL_LEVEL_ERR,
1712 "Received unknown notification type %s.\n",
d1e348cf
A
1713 s_isakmp_notify_msg(ntohs(notify->type)));
1714 }
1715
1716 return;
1717}
1718
52b7d2ce
A
1719#ifdef ENABLE_VPNCONTROL_PORT
1720static int
65c25746 1721isakmp_info_recv_lb(phase1_handle_t *iph1, struct isakmp_pl_lb *n, int encrypted)
52b7d2ce
A
1722{
1723
1724 if (iph1->side != INITIATOR)
1725 {
7ebaebe2 1726 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1727 "LOAD-BALANCE notification ignored - we are not the initiator.\n");
1728 return 0;
1729 }
52b7d2ce 1730 if (!encrypted) {
7ebaebe2 1731 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1732 "LOAD-BALANCE notification ignored - not protected.\n");
1733 return 0;
1734 }
1735 if (ntohs(n->h.len) != sizeof(struct isakmp_pl_lb)) {
7ebaebe2
A
1736 plog(ASL_LEVEL_NOTICE,
1737 "isakmp_info_recv_lb Invalid length of payload\n");
52b7d2ce 1738 return -1;
d06a7ccb
A
1739 }
1740
52b7d2ce 1741 vpncontrol_notify_ike_failed(ISAKMP_NTYPE_LOAD_BALANCE, FROM_REMOTE,
d06a7ccb 1742 iph1_get_remote_v4_address(iph1), 4, (u_int8_t*)(&(n->address)));
52b7d2ce 1743
65c25746
A
1744 plog(ASL_LEVEL_NOTICE,
1745 "Received LOAD_BALANCE notification.\n");
52b7d2ce 1746
d1e348cf 1747 if (((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr != ntohl(n->address)) {
7ebaebe2 1748 plog(ASL_LEVEL_NOTICE,
65c25746 1749 "Deleting old Phase 1 because of LOAD_BALANCE notification - redirect address=%x.\n",
d1e348cf
A
1750 ntohl(n->address));
1751
65c25746 1752 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) {
d1e348cf
A
1753 isakmp_info_send_d1(iph1);
1754 }
1755 isakmp_ph1expire(iph1);
1756 }
1757
52b7d2ce
A
1758 return 0;
1759}
1760#endif
1761
1762#ifdef ENABLE_DPD
1763static int
65c25746 1764isakmp_info_recv_r_u (phase1_handle_t *iph1, struct isakmp_pl_ru *ru, u_int32_t msgid)
52b7d2ce
A
1765{
1766 struct isakmp_pl_ru *ru_ack;
1767 vchar_t *payload = NULL;
1768 int tlen;
1769 int error = 0;
1770
7ebaebe2 1771 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1772 "DPD R-U-There received\n");
1773
1774 /* XXX should compare cookies with iph1->index?
1775 Or is this already done by calling function? */
1776 tlen = sizeof(*ru_ack);
1777 payload = vmalloc(tlen);
1778 if (payload == NULL) {
6b88cae0 1779 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1780 "failed to get buffer to send.\n");
1781 return errno;
1782 }
1783
1784 ru_ack = (struct isakmp_pl_ru *)payload->v;
1785 ru_ack->h.np = ISAKMP_NPTYPE_NONE;
1786 ru_ack->h.len = htons(tlen);
1787 ru_ack->doi = htonl(IPSEC_DOI);
1788 ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK);
1789 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */
1790 ru_ack->spi_size = sizeof(isakmp_index);
1791 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t));
1792 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t));
1793 ru_ack->data = ru->data;
1794
1795 /* XXX Should we do FLAG_A ? */
1796 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
1797 ISAKMP_FLAG_E);
1798 vfree(payload);
7ebaebe2 1799 plog(ASL_LEVEL_NOTICE, "received a valid R-U-THERE, ACK sent\n");
52b7d2ce
A
1800
1801 /* Should we mark tunnel as active ? */
1802 return error;
1803}
1804
1805static int
65c25746 1806isakmp_info_recv_r_u_ack (phase1_handle_t *iph1, struct isakmp_pl_ru *ru, u_int32_t msgid)
52b7d2ce
A
1807{
1808
7ebaebe2 1809 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1810 "DPD R-U-There-Ack received\n");
1811
1812 /* XXX Maintain window of acceptable sequence numbers ?
1813 * => ru->data <= iph2->dpd_seq &&
1814 * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */
d1e348cf 1815 if (ntohl(ru->data) != iph1->dpd_seq) {
65c25746 1816 plog(ASL_LEVEL_ERR,
52b7d2ce 1817 "Wrong DPD sequence number (%d, %d expected).\n",
d1e348cf 1818 ntohl(ru->data), iph1->dpd_seq);
52b7d2ce
A
1819 return 0;
1820 }
1821
1822 if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) ||
1823 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) {
65c25746 1824 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1825 "Cookie mismatch in DPD ACK!.\n");
1826 return 0;
1827 }
1828
1829 iph1->dpd_fails = 0;
1830
d1e348cf
A
1831 iph1->dpd_seq++;
1832
52b7d2ce
A
1833 /* Useless ??? */
1834 iph1->dpd_lastack = time(NULL);
1835
d1e348cf 1836 SCHED_KILL(iph1->dpd_r_u);
52b7d2ce
A
1837
1838 isakmp_sched_r_u(iph1, 0);
1839
7ebaebe2 1840 plog(ASL_LEVEL_NOTICE, "received an R-U-THERE-ACK\n");
52b7d2ce 1841
e8d9021d
A
1842#ifdef ENABLE_VPNCONTROL_PORT
1843 vpncontrol_notify_peer_resp_ph1(1, iph1);
1844#endif /* ENABLE_VPNCONTROL_PORT */
1845
52b7d2ce
A
1846 return 0;
1847}
1848
1849
1850/*
1851 * send Delete payload (for ISAKMP SA) in Informational exchange.
1852 */
d1e348cf 1853void
65c25746 1854isakmp_info_send_r_u(void *arg)
52b7d2ce 1855{
65c25746 1856 phase1_handle_t *iph1 = arg;
52b7d2ce
A
1857
1858 /* create R-U-THERE payload */
1859 struct isakmp_pl_ru *ru;
1860 vchar_t *payload = NULL;
1861 int tlen;
1862 int error = 0;
1863
65c25746 1864 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
7ebaebe2 1865 plog(ASL_LEVEL_NOTICE, "DPD r-u send aborted, invalid Phase 1 status %d....\n",
d1e348cf
A
1866 iph1->status);
1867 return;
1868 }
52b7d2ce
A
1869
1870 if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
d06a7ccb 1871 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PEER_DEAD, FROM_LOCAL, iph1_get_remote_v4_address(iph1), 0, NULL);
d1e348cf 1872
52b7d2ce 1873 purge_remote(iph1);
7ebaebe2 1874 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1875 "DPD: remote seems to be dead\n");
1876
1877 /* Do not reschedule here: phase1 is deleted,
1878 * DPD will be reactivated when a new ph1 will be negociated
1879 */
1880 return;
1881 }
1882
52b7d2ce
A
1883 tlen = sizeof(*ru);
1884 payload = vmalloc(tlen);
1885 if (payload == NULL) {
6b88cae0 1886 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1887 "failed to get buffer for payload.\n");
1888 return;
1889 }
1890 ru = (struct isakmp_pl_ru *)payload->v;
1891 ru->h.np = ISAKMP_NPTYPE_NONE;
1892 ru->h.len = htons(tlen);
1893 ru->doi = htonl(IPSEC_DOI);
1894 ru->type = htons(ISAKMP_NTYPE_R_U_THERE);
1895 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/
1896 ru->spi_size = sizeof(isakmp_index);
1897
1898 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t));
1899 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t));
1900
1901 if (iph1->dpd_seq == 0){
1902 /* generate a random seq which is not too big */
1903 srand(time(NULL));
1904 iph1->dpd_seq = rand() & 0x0fff;
1905 }
1906
1907 ru->data = htonl(iph1->dpd_seq);
1908
1909 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
1910 vfree(payload);
7ebaebe2 1911 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1912 "DPD R-U-There sent (%d)\n", error);
1913
1914 /* will be decreased if ACK received... */
1915 iph1->dpd_fails++;
1916
52b7d2ce
A
1917 /* Reschedule the r_u_there with a short delay,
1918 * will be deleted/rescheduled if ACK received before */
1919 isakmp_sched_r_u(iph1, 1);
1920
7ebaebe2 1921 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
1922 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry);
1923}
1924
d1e348cf
A
1925/*
1926 * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange.
1927 */
1928static void
65c25746 1929isakmp_info_monitor_r_u_algo_inbound_detect (phase1_handle_t *iph1)
d1e348cf 1930{
65c25746 1931 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
7ebaebe2 1932 plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) aborted, invalid Phase 1 status %d....\n",
d1e348cf
A
1933 iph1->status);
1934 return;
1935 }
1936
7ebaebe2 1937 plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) ....\n");
d1e348cf
A
1938
1939 // check phase1 for ike packets received from peer
1940 if (iph1->peer_sent_ike) {
1941 // yes, reshedule check
1942 iph1->peer_sent_ike = 0;
1943
1944 /* ike packets received from peer... reschedule dpd */
1945 isakmp_sched_r_u(iph1, 0);
1946
7ebaebe2 1947 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
1948 "ike packets received from peer... reschedule monitor.\n");
1949
1950 return;
1951 }
1952
1953 // after ike packets, next we check if any data was received
1954 if (!iph1->parent_session->peer_sent_data_sc_dpd) {
1955 isakmp_info_send_r_u(iph1);
1956 } else {
1957 isakmp_sched_r_u(iph1, 0);
1958
7ebaebe2 1959 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
1960 "rescheduling DPD monitoring (for ALGORITHM_INBOUND_DETECT).\n");
1961 }
1962 iph1->parent_session->peer_sent_data_sc_dpd = 0;
1963}
1964
1965/*
e8d9021d 1966 * monitor DPD (ALGORITHM_BLACKHOLE_DETECT) Informational exchange.
d1e348cf
A
1967 */
1968static void
65c25746 1969isakmp_info_monitor_r_u_algo_blackhole_detect (phase1_handle_t *iph1)
d1e348cf 1970{
65c25746 1971 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
7ebaebe2 1972 plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) aborted, invalid Phase 1 status %d....\n",
d1e348cf
A
1973 iph1->status);
1974 return;
1975 }
1976
7ebaebe2 1977 plog(ASL_LEVEL_NOTICE, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) ....\n");
d1e348cf
A
1978
1979 // check if data was sent but none was received
1980 if (iph1->parent_session->i_sent_data_sc_dpd &&
1981 !iph1->parent_session->peer_sent_data_sc_dpd) {
1982 isakmp_info_send_r_u(iph1);
1983 } else {
1984 isakmp_sched_r_u(iph1, 0);
1985
7ebaebe2 1986 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
1987 "rescheduling DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) i = %d, peer %d.\n",
1988 iph1->parent_session->i_sent_data_sc_dpd,
1989 iph1->parent_session->peer_sent_data_sc_dpd);
1990 }
1991 iph1->parent_session->i_sent_data_sc_dpd = 0;
1992 iph1->parent_session->peer_sent_data_sc_dpd = 0;
1993}
1994
1995/*
1996 * monitor DPD Informational exchange.
1997 */
1998static void
65c25746 1999isakmp_info_monitor_r_u(void *arg)
d1e348cf 2000{
65c25746 2001 phase1_handle_t *iph1 = arg;
d1e348cf
A
2002
2003 if (iph1 && iph1->rmconf) {
2004 if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT) {
2005 isakmp_info_monitor_r_u_algo_inbound_detect(iph1);
2006 } else if (iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) {
2007 isakmp_info_monitor_r_u_algo_blackhole_detect(iph1);
2008 } else {
7ebaebe2 2009 plog(ASL_LEVEL_NOTICE, "DPD monitoring aborted, invalid algorithm %d....\n",
d1e348cf
A
2010 iph1->rmconf->dpd_algo);
2011 }
2012 }
2013}
2014
52b7d2ce
A
2015/* Schedule a new R-U-THERE */
2016int
65c25746 2017isakmp_sched_r_u(phase1_handle_t *iph1, int retry)
52b7d2ce
A
2018{
2019 if(iph1 == NULL ||
2020 iph1->rmconf == NULL)
2021 return 1;
2022
2023
2024 if(iph1->dpd_support == 0 ||
2025 iph1->rmconf->dpd_interval == 0)
2026 return 0;
2027
d1e348cf 2028 if(retry) {
52b7d2ce 2029 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry,
d1e348cf
A
2030 isakmp_info_send_r_u, iph1);
2031 } else {
2032 if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT ||
2033 iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) {
2034 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
2035 isakmp_info_monitor_r_u, iph1);
2036 } else {
2037 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
2038 isakmp_info_send_r_u, iph1);
2039 }
2040 }
52b7d2ce
A
2041
2042 return 0;
2043}
d1e348cf
A
2044
2045/*
2046 * punts dpd for later because of some activity that:
2047 * 1) implicitly does dpd (e.g. phase2 exchanges), or
2048 * 2) indicates liveness (e.g. received ike packets).
2049 */
2050void
65c25746 2051isakmp_reschedule_info_monitor_if_pending (phase1_handle_t *iph1, char *reason)
d1e348cf
A
2052{
2053 if (!iph1 ||
65c25746 2054 !FSM_STATE_IS_ESTABLISHED(iph1->status) ||
d1e348cf
A
2055 !iph1->dpd_support ||
2056 !iph1->rmconf->dpd_interval ||
2057 iph1->rmconf->dpd_algo == DPD_ALGO_DEFAULT) {
2058 return;
2059 }
2060
2061 if (!iph1->peer_sent_ike) {
2062 SCHED_KILL(iph1->dpd_r_u);
2063
2064 isakmp_sched_r_u(iph1, 0);
2065
7ebaebe2 2066 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
2067 "%s... rescheduling send_r_u.\n",
2068 reason);
2069 }
2070 iph1->peer_sent_ike++;
2071}
52b7d2ce 2072#endif