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