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