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