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