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