1 /* $NetBSD: isakmp_inf.c,v 1.14.4.16 2009/04/20 13:35:36 tteras 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 <net/pfkeyv2.h>
41 #include <netinet/in.h>
42 #include <sys/queue.h>
43 #include PATH_IPSEC_H
44
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include <errno.h>
49 #if TIME_WITH_SYS_TIME
50 # include <sys/time.h>
51 # include <time.h>
52 #else
53 # if HAVE_SYS_TIME_H
54 # include <sys/time.h>
55 # else
56 # include <time.h>
57 # endif
58 #endif
59 #ifdef ENABLE_HYBRID
60 #include <resolv.h>
61 #endif
62
63 #include "libpfkey.h"
64
65 #include "var.h"
66 #include "vmbuf.h"
67 #include "schedule.h"
68 #include "str2val.h"
69 #include "misc.h"
70 #include "plog.h"
71 #include "debug.h"
72
73 #include "localconf.h"
74 #include "remoteconf.h"
75 #include "sockmisc.h"
76 #include "handler.h"
77 #include "policy.h"
78 #include "proposal.h"
79 #include "isakmp_var.h"
80 #include "evt.h"
81 #include "isakmp.h"
82 #ifdef ENABLE_HYBRID
83 #include "isakmp_xauth.h"
84 #include "isakmp_unity.h"
85 #include "isakmp_cfg.h"
86 #endif
87 #include "isakmp_inf.h"
88 #include "oakley.h"
89 #include "ipsec_doi.h"
90 #include "crypto_openssl.h"
91 #include "pfkey.h"
92 #include "policy.h"
93 #include "algorithm.h"
94 #include "proposal.h"
95 #include "admin.h"
96 #include "strnames.h"
97 #ifdef ENABLE_NATT
98 #include "nattraversal.h"
99 #endif
100
101 /* information exchange */
102 static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int);
103 static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int);
104
105 #ifdef ENABLE_DPD
106 static int isakmp_info_recv_r_u __P((struct ph1handle *,
107 struct isakmp_pl_ru *, u_int32_t));
108 static int isakmp_info_recv_r_u_ack __P((struct ph1handle *,
109 struct isakmp_pl_ru *, u_int32_t));
110 static void isakmp_info_send_r_u __P((void *));
111 #endif
112
113 static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
114 static void info_recv_initialcontact __P((struct ph1handle *));
115
116 /* %%%
117 * Information Exchange
118 */
119 /*
120 * receive Information
121 */
122 int
isakmp_info_recv(iph1,msg0)123 isakmp_info_recv(iph1, msg0)
124 struct ph1handle *iph1;
125 vchar_t *msg0;
126 {
127 vchar_t *msg = NULL;
128 vchar_t *pbuf = NULL;
129 u_int32_t msgid = 0;
130 int error = -1;
131 struct isakmp *isakmp;
132 struct isakmp_gen *gen;
133 struct isakmp_parse_t *pa, *pap;
134 void *p;
135 vchar_t *hash, *payload;
136 struct isakmp_gen *nd;
137 u_int8_t np;
138 int encrypted;
139 int flag;
140
141 plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n");
142
143 encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
144 msgid = ((struct isakmp *)msg0->v)->msgid;
145
146 /* Use new IV to decrypt Informational message. */
147 if (encrypted) {
148 struct isakmp_ivm *ivm;
149
150 if (iph1->ivm == NULL) {
151 plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n");
152 return -1;
153 }
154
155 /* compute IV */
156 ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
157 if (ivm == NULL)
158 return -1;
159
160 msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
161 oakley_delivm(ivm);
162 if (msg == NULL)
163 return -1;
164
165 } else
166 msg = vdup(msg0);
167
168 /* Safety check */
169 if (msg->l < sizeof(*isakmp) + sizeof(*gen)) {
170 plog(LLV_ERROR, LOCATION, NULL,
171 "ignore information because the "
172 "message is way too short - %zu byte(s).\n", msg->l);
173 goto end;
174 }
175
176 isakmp = (struct isakmp *)msg->v;
177 gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
178 np = gen->np;
179
180 if (encrypted) {
181 if (isakmp->np != ISAKMP_NPTYPE_HASH) {
182 plog(LLV_ERROR, LOCATION, NULL,
183 "ignore information because the"
184 "message has no hash payload.\n");
185 goto end;
186 }
187
188 if (iph1->status != PHASE1ST_ESTABLISHED) {
189 plog(LLV_ERROR, LOCATION, NULL,
190 "ignore information because ISAKMP-SA"
191 "has not been established yet.\n");
192 goto end;
193 }
194
195 /* Safety check */
196 if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) {
197 plog(LLV_ERROR, LOCATION, NULL,
198 "ignore information because the "
199 "message is too short - %zu byte(s).\n", msg->l);
200 goto end;
201 }
202
203 p = (caddr_t) gen + sizeof(struct isakmp_gen);
204 nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len));
205
206 /* nd length check */
207 if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) +
208 ntohs(gen->len))) {
209 plog(LLV_ERROR, LOCATION, NULL,
210 "too long payload length (broken message?)\n");
211 goto end;
212 }
213
214 if (ntohs(nd->len) < sizeof(*nd)) {
215 plog(LLV_ERROR, LOCATION, NULL,
216 "too short payload length (broken message?)\n");
217 goto end;
218 }
219
220 payload = vmalloc(ntohs(nd->len));
221 if (payload == NULL) {
222 plog(LLV_ERROR, LOCATION, NULL,
223 "cannot allocate memory\n");
224 goto end;
225 }
226
227 memcpy(payload->v, (caddr_t) nd, ntohs(nd->len));
228
229 /* compute HASH */
230 hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
231 if (hash == NULL) {
232 plog(LLV_ERROR, LOCATION, NULL,
233 "cannot compute hash\n");
234
235 vfree(payload);
236 goto end;
237 }
238
239 if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) {
240 plog(LLV_ERROR, LOCATION, NULL,
241 "ignore information due to hash length mismatch\n");
242
243 vfree(hash);
244 vfree(payload);
245 goto end;
246 }
247
248 if (memcmp(p, hash->v, hash->l) != 0) {
249 plog(LLV_ERROR, LOCATION, NULL,
250 "ignore information due to hash mismatch\n");
251
252 vfree(hash);
253 vfree(payload);
254 goto end;
255 }
256
257 plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n");
258
259 vfree(hash);
260 vfree(payload);
261 } else {
262 /* make sure the packet was encrypted after the beginning of phase 1. */
263 switch (iph1->etype) {
264 case ISAKMP_ETYPE_AGG:
265 case ISAKMP_ETYPE_BASE:
266 case ISAKMP_ETYPE_IDENT:
267 if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT)
268 || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) {
269 break;
270 }
271 /*FALLTHRU*/
272 default:
273 plog(LLV_ERROR, LOCATION, iph1->remote,
274 "%s message must be encrypted\n",
275 s_isakmp_nptype(np));
276 error = 0;
277 goto end;
278 }
279 }
280
281 if (!(pbuf = isakmp_parse(msg))) {
282 error = -1;
283 goto end;
284 }
285
286 error = 0;
287 for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) {
288 switch (pa->type) {
289 case ISAKMP_NPTYPE_HASH:
290 /* Handled above */
291 break;
292 case ISAKMP_NPTYPE_N:
293 error = isakmp_info_recv_n(iph1,
294 (struct isakmp_pl_n *)pa->ptr,
295 msgid, encrypted);
296 break;
297 case ISAKMP_NPTYPE_D:
298 error = isakmp_info_recv_d(iph1,
299 (struct isakmp_pl_d *)pa->ptr,
300 msgid, encrypted);
301 break;
302 case ISAKMP_NPTYPE_NONCE:
303 /* XXX to be 6.4.2 ike-01.txt */
304 /* XXX IV is to be synchronized. */
305 plog(LLV_ERROR, LOCATION, iph1->remote,
306 "ignore Acknowledged Informational\n");
307 break;
308 default:
309 /* don't send information, see isakmp_ident_r1() */
310 error = 0;
311 plog(LLV_ERROR, LOCATION, iph1->remote,
312 "reject the packet, "
313 "received unexpected payload type %s.\n",
314 s_isakmp_nptype(gen->np));
315 }
316 if(error < 0) {
317 break;
318 } else {
319 flag |= error;
320 }
321 }
322 end:
323 if (msg != NULL)
324 vfree(msg);
325 if (pbuf != NULL)
326 vfree(pbuf);
327 return error;
328 }
329
330 /*
331 * handling of Notification payload
332 */
333 static int
isakmp_info_recv_n(iph1,notify,msgid,encrypted)334 isakmp_info_recv_n(iph1, notify, msgid, encrypted)
335 struct ph1handle *iph1;
336 struct isakmp_pl_n *notify;
337 u_int32_t msgid;
338 int encrypted;
339 {
340 u_int type;
341 vchar_t *pbuf;
342 char *nraw, *ndata;
343 size_t l;
344 char *spi;
345
346 type = ntohs(notify->type);
347
348 switch (type) {
349 case ISAKMP_NTYPE_CONNECTED:
350 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
351 case ISAKMP_NTYPE_REPLAY_STATUS:
352 #ifdef ENABLE_HYBRID
353 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
354 #endif
355 /* do something */
356 break;
357 case ISAKMP_NTYPE_INITIAL_CONTACT:
358 if (encrypted)
359 info_recv_initialcontact(iph1);
360 return 0;
361 break;
362 #ifdef ENABLE_DPD
363 case ISAKMP_NTYPE_R_U_THERE:
364 if (encrypted)
365 return isakmp_info_recv_r_u(iph1,
366 (struct isakmp_pl_ru *)notify, msgid);
367 break;
368 case ISAKMP_NTYPE_R_U_THERE_ACK:
369 if (encrypted)
370 return isakmp_info_recv_r_u_ack(iph1,
371 (struct isakmp_pl_ru *)notify, msgid);
372 break;
373 #endif
374 default:
375 {
376 /* XXX there is a potential of dos attack. */
377 if(type >= ISAKMP_NTYPE_MINERROR &&
378 type <= ISAKMP_NTYPE_MAXERROR) {
379 if (msgid == 0) {
380 /* don't think this realy deletes ph1 ? */
381 plog(LLV_ERROR, LOCATION, iph1->remote,
382 "delete phase1 handle.\n");
383 return -1;
384 } else {
385 if (getph2bymsgid(iph1, msgid) == NULL) {
386 plog(LLV_ERROR, LOCATION, iph1->remote,
387 "fatal %s notify messsage, "
388 "phase1 should be deleted.\n",
389 s_isakmp_notify_msg(type));
390 } else {
391 plog(LLV_ERROR, LOCATION, iph1->remote,
392 "fatal %s notify messsage, "
393 "phase2 should be deleted.\n",
394 s_isakmp_notify_msg(type));
395 }
396 }
397 } else {
398 plog(LLV_ERROR, LOCATION, iph1->remote,
399 "unhandled notify message %s, "
400 "no phase2 handle found.\n",
401 s_isakmp_notify_msg(type));
402 }
403 }
404 break;
405 }
406
407 /* get spi if specified and allocate */
408 if(notify->spi_size > 0) {
409 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
410 plog(LLV_ERROR, LOCATION, iph1->remote,
411 "invalid spi_size in notification payload.\n");
412 return -1;
413 }
414 spi = val2str((char *)(notify + 1), notify->spi_size);
415
416 plog(LLV_DEBUG, LOCATION, iph1->remote,
417 "notification message %d:%s, "
418 "doi=%d proto_id=%d spi=%s(size=%d).\n",
419 type, s_isakmp_notify_msg(type),
420 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
421
422 racoon_free(spi);
423 }
424
425 /* Send the message data to the logs */
426 if(type >= ISAKMP_NTYPE_MINERROR &&
427 type <= ISAKMP_NTYPE_MAXERROR) {
428 l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
429 if (l > 0) {
430 nraw = (char*)notify;
431 nraw += sizeof(*notify) + notify->spi_size;
432 ndata = binsanitize(nraw, l);
433 if (ndata != NULL) {
434 plog(LLV_ERROR, LOCATION, iph1->remote,
435 "Message: '%s'.\n",
436 ndata);
437 racoon_free(ndata);
438 } else {
439 plog(LLV_ERROR, LOCATION, iph1->remote,
440 "Cannot allocate memory\n");
441 }
442 }
443 }
444 return 0;
445 }
446
447 /*
448 * handling of Deletion payload
449 */
450 static int
isakmp_info_recv_d(iph1,delete,msgid,encrypted)451 isakmp_info_recv_d(iph1, delete, msgid, encrypted)
452 struct ph1handle *iph1;
453 struct isakmp_pl_d *delete;
454 u_int32_t msgid;
455 int encrypted;
456 {
457 int tlen, num_spi;
458 vchar_t *pbuf;
459 int protected = 0;
460 struct ph1handle *del_ph1;
461 struct ph2handle *iph2;
462 union {
463 u_int32_t spi32;
464 u_int16_t spi16[2];
465 } spi;
466
467 if (ntohl(delete->doi) != IPSEC_DOI) {
468 plog(LLV_ERROR, LOCATION, iph1->remote,
469 "delete payload with invalid doi:%d.\n",
470 ntohl(delete->doi));
471 #ifdef ENABLE_HYBRID
472 /*
473 * At deconnexion time, Cisco VPN client does this
474 * with a zero DOI. Don't give up in that situation.
475 */
476 if (((iph1->mode_cfg->flags &
477 ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0))
478 return 0;
479 #else
480 return 0;
481 #endif
482 }
483
484 num_spi = ntohs(delete->num_spi);
485 tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d);
486
487 if (tlen != num_spi * delete->spi_size) {
488 plog(LLV_ERROR, LOCATION, iph1->remote,
489 "deletion payload with invalid length.\n");
490 return 0;
491 }
492
493 plog(LLV_DEBUG, LOCATION, iph1->remote,
494 "delete payload for protocol %s\n",
495 s_ipsecdoi_proto(delete->proto_id));
496
497 if(!iph1->rmconf->weak_phase1_check && !encrypted) {
498 plog(LLV_WARNING, LOCATION, iph1->remote,
499 "Ignoring unencrypted delete payload "
500 "(check the weak_phase1_check option)\n");
501 return 0;
502 }
503
504 switch (delete->proto_id) {
505 case IPSECDOI_PROTO_ISAKMP:
506 if (delete->spi_size != sizeof(isakmp_index)) {
507 plog(LLV_ERROR, LOCATION, iph1->remote,
508 "delete payload with strange spi "
509 "size %d(proto_id:%d)\n",
510 delete->spi_size, delete->proto_id);
511 return 0;
512 }
513
514 del_ph1=getph1byindex((isakmp_index *)(delete + 1));
515 if(del_ph1 != NULL){
516
517 EVT_PUSH(del_ph1->local, del_ph1->remote,
518 EVTT_PEERPH1_NOPROP, NULL);
519 if (del_ph1->scr)
520 SCHED_KILL(del_ph1->scr);
521
522 /*
523 * Do not delete IPsec SAs when receiving an IKE delete notification.
524 * Just delete the IKE SA.
525 */
526 isakmp_ph1expire(del_ph1);
527 }
528 break;
529
530 case IPSECDOI_PROTO_IPSEC_AH:
531 case IPSECDOI_PROTO_IPSEC_ESP:
532 if (delete->spi_size != sizeof(u_int32_t)) {
533 plog(LLV_ERROR, LOCATION, iph1->remote,
534 "delete payload with strange spi "
535 "size %d(proto_id:%d)\n",
536 delete->spi_size, delete->proto_id);
537 return 0;
538 }
539 EVT_PUSH(iph1->local, iph1->remote,
540 EVTT_PEER_DELETE, NULL);
541 purge_ipsec_spi(iph1->remote, delete->proto_id,
542 (u_int32_t *)(delete + 1), num_spi);
543 break;
544
545 case IPSECDOI_PROTO_IPCOMP:
546 /* need to handle both 16bit/32bit SPI */
547 memset(&spi, 0, sizeof(spi));
548 if (delete->spi_size == sizeof(spi.spi16[1])) {
549 memcpy(&spi.spi16[1], delete + 1,
550 sizeof(spi.spi16[1]));
551 } else if (delete->spi_size == sizeof(spi.spi32))
552 memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32));
553 else {
554 plog(LLV_ERROR, LOCATION, iph1->remote,
555 "delete payload with strange spi "
556 "size %d(proto_id:%d)\n",
557 delete->spi_size, delete->proto_id);
558 return 0;
559 }
560 purge_ipsec_spi(iph1->remote, delete->proto_id,
561 &spi.spi32, num_spi);
562 break;
563
564 default:
565 plog(LLV_ERROR, LOCATION, iph1->remote,
566 "deletion message received, "
567 "invalid proto_id: %d\n",
568 delete->proto_id);
569 return 0;
570 }
571
572 plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n");
573
574 return 0;
575 }
576
577 /*
578 * send Delete payload (for ISAKMP SA) in Informational exchange.
579 */
580 int
isakmp_info_send_d1(iph1)581 isakmp_info_send_d1(iph1)
582 struct ph1handle *iph1;
583 {
584 struct isakmp_pl_d *d;
585 vchar_t *payload = NULL;
586 int tlen;
587 int error = 0;
588
589 if (iph1->status != PHASE2ST_ESTABLISHED)
590 return 0;
591
592 /* create delete payload */
593
594 /* send SPIs of inbound SAs. */
595 /* XXX should send outbound SAs's ? */
596 tlen = sizeof(*d) + sizeof(isakmp_index);
597 payload = vmalloc(tlen);
598 if (payload == NULL) {
599 plog(LLV_ERROR, LOCATION, NULL,
600 "failed to get buffer for payload.\n");
601 return errno;
602 }
603
604 d = (struct isakmp_pl_d *)payload->v;
605 d->h.np = ISAKMP_NPTYPE_NONE;
606 d->h.len = htons(tlen);
607 d->doi = htonl(IPSEC_DOI);
608 d->proto_id = IPSECDOI_PROTO_ISAKMP;
609 d->spi_size = sizeof(isakmp_index);
610 d->num_spi = htons(1);
611 memcpy(d + 1, &iph1->index, sizeof(isakmp_index));
612
613 error = isakmp_info_send_common(iph1, payload,
614 ISAKMP_NPTYPE_D, 0);
615 vfree(payload);
616
617 return error;
618 }
619
620 /*
621 * send Delete payload (for IPsec SA) in Informational exchange, based on
622 * pfkey msg. It sends always single SPI.
623 */
624 int
isakmp_info_send_d2(iph2)625 isakmp_info_send_d2(iph2)
626 struct ph2handle *iph2;
627 {
628 struct ph1handle *iph1;
629 struct saproto *pr;
630 struct isakmp_pl_d *d;
631 vchar_t *payload = NULL;
632 int tlen;
633 int error = 0;
634 u_int8_t *spi;
635
636 if (iph2->status != PHASE2ST_ESTABLISHED)
637 return 0;
638
639 /*
640 * don't send delete information if there is no phase 1 handler.
641 * It's nonsensical to negotiate phase 1 to send the information.
642 */
643 iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
644 if (iph1 == NULL){
645 plog(LLV_DEBUG2, LOCATION, NULL,
646 "No ph1 handler found, could not send DELETE_SA\n");
647 return 0;
648 }
649
650 /* create delete payload */
651 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
652
653 /* send SPIs of inbound SAs. */
654 /*
655 * XXX should I send outbound SAs's ?
656 * I send inbound SAs's SPI only at the moment because I can't
657 * decode any more if peer send encoded packet without aware of
658 * deletion of SA. Outbound SAs don't come under the situation.
659 */
660 tlen = sizeof(*d) + pr->spisize;
661 payload = vmalloc(tlen);
662 if (payload == NULL) {
663 plog(LLV_ERROR, LOCATION, NULL,
664 "failed to get buffer for payload.\n");
665 return errno;
666 }
667
668 d = (struct isakmp_pl_d *)payload->v;
669 d->h.np = ISAKMP_NPTYPE_NONE;
670 d->h.len = htons(tlen);
671 d->doi = htonl(IPSEC_DOI);
672 d->proto_id = pr->proto_id;
673 d->spi_size = pr->spisize;
674 d->num_spi = htons(1);
675 /*
676 * XXX SPI bits are left-filled, for use with IPComp.
677 * we should be switching to variable-length spi field...
678 */
679 spi = (u_int8_t *)&pr->spi;
680 spi += sizeof(pr->spi);
681 spi -= pr->spisize;
682 memcpy(d + 1, spi, pr->spisize);
683
684 error = isakmp_info_send_common(iph1, payload,
685 ISAKMP_NPTYPE_D, 0);
686 vfree(payload);
687 }
688
689 return error;
690 }
691
692 /*
693 * send Notification payload (for without ISAKMP SA) in Informational exchange
694 */
695 int
isakmp_info_send_nx(isakmp,remote,local,type,data)696 isakmp_info_send_nx(isakmp, remote, local, type, data)
697 struct isakmp *isakmp;
698 struct sockaddr *remote, *local;
699 int type;
700 vchar_t *data;
701 {
702 struct ph1handle *iph1 = NULL;
703 struct remoteconf *rmconf;
704 vchar_t *payload = NULL;
705 int tlen;
706 int error = -1;
707 struct isakmp_pl_n *n;
708 int spisiz = 0; /* see below */
709
710 /* search appropreate configuration */
711 rmconf = getrmconf(remote);
712 if (rmconf == NULL) {
713 plog(LLV_ERROR, LOCATION, remote,
714 "no configuration found for peer address.\n");
715 goto end;
716 }
717
718 /* add new entry to isakmp status table. */
719 iph1 = newph1();
720 if (iph1 == NULL)
721 return -1;
722
723 memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
724 isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
725 iph1->status = PHASE1ST_START;
726 iph1->rmconf = rmconf;
727 iph1->side = INITIATOR;
728 iph1->version = isakmp->v;
729 iph1->flags = 0;
730 iph1->msgid = 0; /* XXX */
731 #ifdef ENABLE_HYBRID
732 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL)
733 goto end;
734 #endif
735 #ifdef ENABLE_FRAG
736 iph1->frag = 0;
737 iph1->frag_chain = NULL;
738 #endif
739
740 /* copy remote address */
741 if (copy_ph1addresses(iph1, rmconf, remote, local) < 0)
742 goto end;
743
744 tlen = sizeof(*n) + spisiz;
745 if (data)
746 tlen += data->l;
747 payload = vmalloc(tlen);
748 if (payload == NULL) {
749 plog(LLV_ERROR, LOCATION, NULL,
750 "failed to get buffer to send.\n");
751 goto end;
752 }
753
754 n = (struct isakmp_pl_n *)payload->v;
755 n->h.np = ISAKMP_NPTYPE_NONE;
756 n->h.len = htons(tlen);
757 n->doi = htonl(IPSEC_DOI);
758 n->proto_id = IPSECDOI_KEY_IKE;
759 n->spi_size = spisiz;
760 n->type = htons(type);
761 if (spisiz)
762 memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */
763 if (data)
764 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
765
766 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
767 vfree(payload);
768
769 end:
770 if (iph1 != NULL)
771 delph1(iph1);
772
773 return error;
774 }
775
776 /*
777 * send Notification payload (for ISAKMP SA) in Informational exchange
778 */
779 int
isakmp_info_send_n1(iph1,type,data)780 isakmp_info_send_n1(iph1, type, data)
781 struct ph1handle *iph1;
782 int type;
783 vchar_t *data;
784 {
785 vchar_t *payload = NULL;
786 int tlen;
787 int error = 0;
788 struct isakmp_pl_n *n;
789 int spisiz;
790
791 /*
792 * note on SPI size: which description is correct? I have chosen
793 * this to be 0.
794 *
795 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by
796 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0.
797 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified
798 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
799 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
800 */
801 if (type == ISAKMP_NTYPE_INITIAL_CONTACT)
802 spisiz = sizeof(isakmp_index);
803 else
804 spisiz = 0;
805
806 tlen = sizeof(*n) + spisiz;
807 if (data)
808 tlen += data->l;
809 payload = vmalloc(tlen);
810 if (payload == NULL) {
811 plog(LLV_ERROR, LOCATION, NULL,
812 "failed to get buffer to send.\n");
813 return errno;
814 }
815
816 n = (struct isakmp_pl_n *)payload->v;
817 n->h.np = ISAKMP_NPTYPE_NONE;
818 n->h.len = htons(tlen);
819 n->doi = htonl(iph1->rmconf->doitype);
820 n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */
821 n->spi_size = spisiz;
822 n->type = htons(type);
823 if (spisiz)
824 memcpy(n + 1, &iph1->index, sizeof(isakmp_index));
825 if (data)
826 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
827
828 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
829 vfree(payload);
830
831 return error;
832 }
833
834 /*
835 * send Notification payload (for IPsec SA) in Informational exchange
836 */
837 int
isakmp_info_send_n2(iph2,type,data)838 isakmp_info_send_n2(iph2, type, data)
839 struct ph2handle *iph2;
840 int type;
841 vchar_t *data;
842 {
843 struct ph1handle *iph1 = iph2->ph1;
844 vchar_t *payload = NULL;
845 int tlen;
846 int error = 0;
847 struct isakmp_pl_n *n;
848 struct saproto *pr;
849
850 if (!iph2->approval)
851 return EINVAL;
852
853 pr = iph2->approval->head;
854
855 /* XXX must be get proper spi */
856 tlen = sizeof(*n) + pr->spisize;
857 if (data)
858 tlen += data->l;
859 payload = vmalloc(tlen);
860 if (payload == NULL) {
861 plog(LLV_ERROR, LOCATION, NULL,
862 "failed to get buffer to send.\n");
863 return errno;
864 }
865
866 n = (struct isakmp_pl_n *)payload->v;
867 n->h.np = ISAKMP_NPTYPE_NONE;
868 n->h.len = htons(tlen);
869 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
870 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
871 n->spi_size = pr->spisize;
872 n->type = htons(type);
873 *(u_int32_t *)(n + 1) = pr->spi;
874 if (data)
875 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
876
877 iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */
878 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
879 vfree(payload);
880
881 return error;
882 }
883
884 /*
885 * send Information
886 * When ph1->skeyid_a == NULL, send message without encoding.
887 */
888 int
isakmp_info_send_common(iph1,payload,np,flags)889 isakmp_info_send_common(iph1, payload, np, flags)
890 struct ph1handle *iph1;
891 vchar_t *payload;
892 u_int32_t np;
893 int flags;
894 {
895 struct ph2handle *iph2 = NULL;
896 vchar_t *hash = NULL;
897 struct isakmp *isakmp;
898 struct isakmp_gen *gen;
899 char *p;
900 int tlen;
901 int error = -1;
902
903 /* add new entry to isakmp status table */
904 iph2 = newph2();
905 if (iph2 == NULL)
906 goto end;
907
908 iph2->dst = dupsaddr(iph1->remote);
909 if (iph2->dst == NULL) {
910 delph2(iph2);
911 goto end;
912 }
913 iph2->src = dupsaddr(iph1->local);
914 if (iph2->src == NULL) {
915 delph2(iph2);
916 goto end;
917 }
918 #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
919 if (set_port(iph2->dst, 0) == NULL ||
920 set_port(iph2->src, 0) == NULL) {
921 plog(LLV_ERROR, LOCATION, NULL,
922 "invalid family: %d\n", iph1->remote->sa_family);
923 delph2(iph2);
924 goto end;
925 }
926 #endif
927 iph2->ph1 = iph1;
928 iph2->side = INITIATOR;
929 iph2->status = PHASE2ST_START;
930 iph2->msgid = isakmp_newmsgid2(iph1);
931
932 /* get IV and HASH(1) if skeyid_a was generated. */
933 if (iph1->skeyid_a != NULL) {
934 iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
935 if (iph2->ivm == NULL) {
936 delph2(iph2);
937 goto end;
938 }
939
940 /* generate HASH(1) */
941 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
942 if (hash == NULL) {
943 delph2(iph2);
944 goto end;
945 }
946
947 /* initialized total buffer length */
948 tlen = hash->l;
949 tlen += sizeof(*gen);
950 } else {
951 /* IKE-SA is not established */
952 hash = NULL;
953
954 /* initialized total buffer length */
955 tlen = 0;
956 }
957 if ((flags & ISAKMP_FLAG_A) == 0)
958 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
959 else
960 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
961
962 insph2(iph2);
963 bindph12(iph1, iph2);
964
965 tlen += sizeof(*isakmp) + payload->l;
966
967 /* create buffer for isakmp payload */
968 iph2->sendbuf = vmalloc(tlen);
969 if (iph2->sendbuf == NULL) {
970 plog(LLV_ERROR, LOCATION, NULL,
971 "failed to get buffer to send.\n");
972 goto err;
973 }
974
975 /* create isakmp header */
976 isakmp = (struct isakmp *)iph2->sendbuf->v;
977 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
978 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
979 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
980 isakmp->v = iph1->version;
981 isakmp->etype = ISAKMP_ETYPE_INFO;
982 isakmp->flags = iph2->flags;
983 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
984 isakmp->len = htonl(tlen);
985 p = (char *)(isakmp + 1);
986
987 /* create HASH payload */
988 if (hash != NULL) {
989 gen = (struct isakmp_gen *)p;
990 gen->np = np & 0xff;
991 gen->len = htons(sizeof(*gen) + hash->l);
992 p += sizeof(*gen);
993 memcpy(p, hash->v, hash->l);
994 p += hash->l;
995 }
996
997 /* add payload */
998 memcpy(p, payload->v, payload->l);
999 p += payload->l;
1000
1001 #ifdef HAVE_PRINT_ISAKMP_C
1002 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1003 #endif
1004
1005 /* encoding */
1006 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1007 vchar_t *tmp;
1008
1009 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
1010 iph2->ivm->iv);
1011 VPTRINIT(iph2->sendbuf);
1012 if (tmp == NULL)
1013 goto err;
1014 iph2->sendbuf = tmp;
1015 }
1016
1017 /* HDR*, HASH(1), N */
1018 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1019 VPTRINIT(iph2->sendbuf);
1020 goto err;
1021 }
1022
1023 plog(LLV_DEBUG, LOCATION, NULL,
1024 "sendto Information %s.\n", s_isakmp_nptype(np));
1025
1026 /*
1027 * don't resend notify message because peer can use Acknowledged
1028 * Informational if peer requires the reply of the notify message.
1029 */
1030
1031 /* XXX If Acknowledged Informational required, don't delete ph2handle */
1032 error = 0;
1033 VPTRINIT(iph2->sendbuf);
1034 goto err; /* XXX */
1035
1036 end:
1037 if (hash)
1038 vfree(hash);
1039 return error;
1040
1041 err:
1042 unbindph12(iph2);
1043 remph2(iph2);
1044 delph2(iph2);
1045 goto end;
1046 }
1047
1048 /*
1049 * add a notify payload to buffer by reallocating buffer.
1050 * If buf == NULL, the function only create a notify payload.
1051 *
1052 * XXX Which is SPI to be included, inbound or outbound ?
1053 */
1054 vchar_t *
isakmp_add_pl_n(buf0,np_p,type,pr,data)1055 isakmp_add_pl_n(buf0, np_p, type, pr, data)
1056 vchar_t *buf0;
1057 u_int8_t **np_p;
1058 int type;
1059 struct saproto *pr;
1060 vchar_t *data;
1061 {
1062 vchar_t *buf = NULL;
1063 struct isakmp_pl_n *n;
1064 int tlen;
1065 int oldlen = 0;
1066
1067 if (*np_p)
1068 **np_p = ISAKMP_NPTYPE_N;
1069
1070 tlen = sizeof(*n) + pr->spisize;
1071
1072 if (data)
1073 tlen += data->l;
1074 if (buf0) {
1075 oldlen = buf0->l;
1076 buf = vrealloc(buf0, buf0->l + tlen);
1077 } else
1078 buf = vmalloc(tlen);
1079 if (!buf) {
1080 plog(LLV_ERROR, LOCATION, NULL,
1081 "failed to get a payload buffer.\n");
1082 return NULL;
1083 }
1084
1085 n = (struct isakmp_pl_n *)(buf->v + oldlen);
1086 n->h.np = ISAKMP_NPTYPE_NONE;
1087 n->h.len = htons(tlen);
1088 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
1089 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
1090 n->spi_size = pr->spisize;
1091 n->type = htons(type);
1092 *(u_int32_t *)(n + 1) = pr->spi; /* XXX */
1093 if (data)
1094 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
1095
1096 /* save the pointer of next payload type */
1097 *np_p = &n->h.np;
1098
1099 return buf;
1100 }
1101
1102 static void
purge_isakmp_spi(proto,spi,n)1103 purge_isakmp_spi(proto, spi, n)
1104 int proto;
1105 isakmp_index *spi; /*network byteorder*/
1106 size_t n;
1107 {
1108 struct ph1handle *iph1;
1109 size_t i;
1110
1111 for (i = 0; i < n; i++) {
1112 iph1 = getph1byindex(&spi[i]);
1113 if (!iph1)
1114 continue;
1115
1116 plog(LLV_INFO, LOCATION, NULL,
1117 "purged ISAKMP-SA proto_id=%s spi=%s.\n",
1118 s_ipsecdoi_proto(proto),
1119 isakmp_pindex(&spi[i], 0));
1120
1121 SCHED_KILL(iph1->sce);
1122 iph1->status = PHASE1ST_EXPIRED;
1123 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
1124 }
1125 }
1126
1127
1128
1129 void
purge_ipsec_spi(dst0,proto,spi,n)1130 purge_ipsec_spi(dst0, proto, spi, n)
1131 struct sockaddr *dst0;
1132 int proto;
1133 u_int32_t *spi; /*network byteorder*/
1134 size_t n;
1135 {
1136 vchar_t *buf = NULL;
1137 struct sadb_msg *msg, *next, *end;
1138 struct sadb_sa *sa;
1139 struct sadb_lifetime *lt;
1140 struct sockaddr *src, *dst;
1141 struct ph2handle *iph2;
1142 u_int64_t created;
1143 size_t i;
1144 caddr_t mhp[SADB_EXT_MAX + 1];
1145 #ifdef ENABLE_NATT
1146 struct sadb_x_nat_t_type *natt_type;
1147 struct sadb_x_nat_t_port *natt_port;
1148 #endif
1149
1150 plog(LLV_DEBUG2, LOCATION, NULL,
1151 "purge_ipsec_spi:\n");
1152 plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0));
1153 plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0]));
1154
1155 buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto));
1156 if (buf == NULL) {
1157 plog(LLV_DEBUG, LOCATION, NULL,
1158 "pfkey_dump_sadb returned nothing.\n");
1159 return;
1160 }
1161
1162 msg = (struct sadb_msg *)buf->v;
1163 end = (struct sadb_msg *)(buf->v + buf->l);
1164
1165 while (msg < end) {
1166 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1167 break;
1168 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
1169 if (msg->sadb_msg_type != SADB_DUMP) {
1170 msg = next;
1171 continue;
1172 }
1173
1174 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
1175 plog(LLV_ERROR, LOCATION, NULL,
1176 "pfkey_check (%s)\n", ipsec_strerror());
1177 msg = next;
1178 continue;
1179 }
1180
1181 sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
1182 if (!sa
1183 || !mhp[SADB_EXT_ADDRESS_SRC]
1184 || !mhp[SADB_EXT_ADDRESS_DST]) {
1185 msg = next;
1186 continue;
1187 }
1188 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1189 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1190 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
1191 if(lt != NULL)
1192 created = lt->sadb_lifetime_addtime;
1193 else
1194 created = 0;
1195
1196 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1197 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1198 msg = next;
1199 continue;
1200 }
1201 #ifdef ENABLE_NATT
1202 natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE];
1203 if (natt_type && natt_type->sadb_x_nat_t_type_type) {
1204 /* NAT-T is enabled for this SADB entry; copy
1205 * the ports from NAT-T extensions */
1206 natt_port = (void *)mhp[SADB_X_EXT_NAT_T_SPORT];
1207 if (extract_port(src) == 0 && natt_port != NULL)
1208 set_port(src, ntohs(natt_port->sadb_x_nat_t_port_port));
1209
1210 natt_port = (void *)mhp[SADB_X_EXT_NAT_T_DPORT];
1211 if (extract_port(dst) == 0 && natt_port != NULL)
1212 set_port(dst, ntohs(natt_port->sadb_x_nat_t_port_port));
1213 }else{
1214 /* Force default UDP ports, so CMPSADDR will match SAs with NO encapsulation
1215 */
1216 set_port(src, PORT_ISAKMP);
1217 set_port(dst, PORT_ISAKMP);
1218 }
1219 #endif
1220 plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
1221 plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst));
1222
1223 /* XXX n^2 algorithm, inefficient */
1224
1225 /* don't delete inbound SAs at the moment */
1226 /* XXX should we remove SAs with opposite direction as well? */
1227 if (CMPSADDR(dst0, dst)) {
1228 msg = next;
1229 continue;
1230 }
1231
1232 #ifdef ENABLE_NATT
1233 if (natt_type == NULL ||
1234 ! natt_type->sadb_x_nat_t_type_type) {
1235 /* Set back port to 0 if it was forced to default UDP port
1236 */
1237 set_port(src, 0);
1238 set_port(dst, 0);
1239 }
1240 #endif
1241 for (i = 0; i < n; i++) {
1242 plog(LLV_DEBUG, LOCATION, NULL,
1243 "check spi(packet)=%u spi(db)=%u.\n",
1244 ntohl(spi[i]), ntohl(sa->sadb_sa_spi));
1245 if (spi[i] != sa->sadb_sa_spi)
1246 continue;
1247
1248 pfkey_send_delete(lcconf->sock_pfkey,
1249 msg->sadb_msg_satype,
1250 IPSEC_MODE_ANY,
1251 src, dst, sa->sadb_sa_spi);
1252
1253 /*
1254 * delete a relative phase 2 handler.
1255 * continue to process if no relative phase 2 handler
1256 * exists.
1257 */
1258 iph2 = getph2bysaidx(src, dst, proto, spi[i]);
1259 if(iph2 != NULL){
1260 delete_spd(iph2, created);
1261 unbindph12(iph2);
1262 remph2(iph2);
1263 delph2(iph2);
1264 }
1265
1266 plog(LLV_INFO, LOCATION, NULL,
1267 "purged IPsec-SA proto_id=%s spi=%u.\n",
1268 s_ipsecdoi_proto(proto),
1269 ntohl(spi[i]));
1270 }
1271
1272 msg = next;
1273 }
1274
1275 if (buf)
1276 vfree(buf);
1277 }
1278
1279 /*
1280 * delete all phase2 sa relatived to the destination address.
1281 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
1282 * an INITIAL-CONTACT if we have contacted the peer. This matches the
1283 * Sun IKE behavior, and makes rekeying work much better when the peer
1284 * restarts.
1285 */
1286 static void
info_recv_initialcontact(iph1)1287 info_recv_initialcontact(iph1)
1288 struct ph1handle *iph1;
1289 {
1290 vchar_t *buf = NULL;
1291 struct sadb_msg *msg, *next, *end;
1292 struct sadb_sa *sa;
1293 struct sockaddr *src, *dst;
1294 caddr_t mhp[SADB_EXT_MAX + 1];
1295 int proto_id, i;
1296 struct ph2handle *iph2;
1297 #if 0
1298 char *loc, *rem;
1299 #endif
1300
1301 if (f_local)
1302 return;
1303
1304 #if 0
1305 loc = racoon_strdup(saddrwop2str(iph1->local));
1306 rem = racoon_strdup(saddrwop2str(iph1->remote));
1307 STRDUP_FATAL(loc);
1308 STRDUP_FATAL(rem);
1309
1310 /*
1311 * Purge all IPSEC-SAs for the peer. We can do this
1312 * the easy way (using a PF_KEY SADB_DELETE extension)
1313 * or we can do it the hard way.
1314 */
1315 for (i = 0; i < pfkey_nsatypes; i++) {
1316 proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype);
1317
1318 plog(LLV_INFO, LOCATION, NULL,
1319 "purging %s SAs for %s -> %s\n",
1320 pfkey_satypes[i].ps_name, loc, rem);
1321 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1322 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1323 iph1->local, iph1->remote) == -1) {
1324 plog(LLV_ERROR, LOCATION, NULL,
1325 "delete_all %s -> %s failed for %s (%s)\n",
1326 loc, rem,
1327 pfkey_satypes[i].ps_name, ipsec_strerror());
1328 goto the_hard_way;
1329 }
1330
1331 deleteallph2(iph1->local, iph1->remote, proto_id);
1332
1333 plog(LLV_INFO, LOCATION, NULL,
1334 "purging %s SAs for %s -> %s\n",
1335 pfkey_satypes[i].ps_name, rem, loc);
1336 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1337 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1338 iph1->remote, iph1->local) == -1) {
1339 plog(LLV_ERROR, LOCATION, NULL,
1340 "delete_all %s -> %s failed for %s (%s)\n",
1341 rem, loc,
1342 pfkey_satypes[i].ps_name, ipsec_strerror());
1343 goto the_hard_way;
1344 }
1345
1346 deleteallph2(iph1->remote, iph1->local, proto_id);
1347 }
1348
1349 racoon_free(loc);
1350 racoon_free(rem);
1351 return;
1352
1353 the_hard_way:
1354 racoon_free(loc);
1355 racoon_free(rem);
1356 #endif
1357
1358 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
1359 if (buf == NULL) {
1360 plog(LLV_DEBUG, LOCATION, NULL,
1361 "pfkey_dump_sadb returned nothing.\n");
1362 return;
1363 }
1364
1365 msg = (struct sadb_msg *)buf->v;
1366 end = (struct sadb_msg *)(buf->v + buf->l);
1367
1368 while (msg < end) {
1369 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1370 break;
1371 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
1372 if (msg->sadb_msg_type != SADB_DUMP) {
1373 msg = next;
1374 continue;
1375 }
1376
1377 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
1378 plog(LLV_ERROR, LOCATION, NULL,
1379 "pfkey_check (%s)\n", ipsec_strerror());
1380 msg = next;
1381 continue;
1382 }
1383
1384 if (mhp[SADB_EXT_SA] == NULL
1385 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1386 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1387 msg = next;
1388 continue;
1389 }
1390 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1391 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1392 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1393
1394 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1395 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1396 msg = next;
1397 continue;
1398 }
1399
1400 /*
1401 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that
1402 * announces the sender of the message was rebooted.
1403 * it is interpreted to delete all SAs which source address
1404 * is the sender of the message.
1405 * racoon only deletes SA which is matched both the
1406 * source address and the destination accress.
1407 */
1408 #ifdef ENABLE_NATT
1409 /*
1410 * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs
1411 * from this peer !
1412 */
1413 if(iph1->natt_flags & NAT_DETECTED){
1414 if (CMPSADDR(iph1->local, src) == 0 &&
1415 CMPSADDR(iph1->remote, dst) == 0)
1416 ;
1417 else if (CMPSADDR(iph1->remote, src) == 0 &&
1418 CMPSADDR(iph1->local, dst) == 0)
1419 ;
1420 else {
1421 msg = next;
1422 continue;
1423 }
1424 } else
1425 #endif
1426 /* If there is no NAT-T, we don't have to check addr + port...
1427 * XXX what about a configuration with a remote peers which is not
1428 * NATed, but which NATs some other peers ?
1429 * Here, the INITIAl-CONTACT would also flush all those NATed peers !!
1430 */
1431 if (cmpsaddrwop(iph1->local, src) == 0 &&
1432 cmpsaddrwop(iph1->remote, dst) == 0)
1433 ;
1434 else if (cmpsaddrwop(iph1->remote, src) == 0 &&
1435 cmpsaddrwop(iph1->local, dst) == 0)
1436 ;
1437 else {
1438 msg = next;
1439 continue;
1440 }
1441
1442 /*
1443 * Make sure this is an SATYPE that we manage.
1444 * This is gross; too bad we couldn't do it the
1445 * easy way.
1446 */
1447 for (i = 0; i < pfkey_nsatypes; i++) {
1448 if (pfkey_satypes[i].ps_satype ==
1449 msg->sadb_msg_satype)
1450 break;
1451 }
1452 if (i == pfkey_nsatypes) {
1453 msg = next;
1454 continue;
1455 }
1456
1457 plog(LLV_INFO, LOCATION, NULL,
1458 "purging spi=%u.\n", ntohl(sa->sadb_sa_spi));
1459 pfkey_send_delete(lcconf->sock_pfkey,
1460 msg->sadb_msg_satype,
1461 IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi);
1462
1463 /*
1464 * delete a relative phase 2 handler.
1465 * continue to process if no relative phase 2 handler
1466 * exists.
1467 */
1468 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1469 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1470 if (iph2) {
1471 delete_spd(iph2, 0);
1472 unbindph12(iph2);
1473 remph2(iph2);
1474 delph2(iph2);
1475 }
1476
1477 msg = next;
1478 }
1479
1480 vfree(buf);
1481 }
1482
1483 void
isakmp_check_notify(gen,iph1)1484 isakmp_check_notify(gen, iph1)
1485 struct isakmp_gen *gen; /* points to Notify payload */
1486 struct ph1handle *iph1;
1487 {
1488 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
1489
1490 plog(LLV_DEBUG, LOCATION, iph1->remote,
1491 "Notify Message received\n");
1492
1493 switch (ntohs(notify->type)) {
1494 case ISAKMP_NTYPE_CONNECTED:
1495 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
1496 case ISAKMP_NTYPE_REPLAY_STATUS:
1497 case ISAKMP_NTYPE_HEARTBEAT:
1498 #ifdef ENABLE_HYBRID
1499 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
1500 #endif
1501 plog(LLV_WARNING, LOCATION, iph1->remote,
1502 "ignore %s notification.\n",
1503 s_isakmp_notify_msg(ntohs(notify->type)));
1504 break;
1505 case ISAKMP_NTYPE_INITIAL_CONTACT:
1506 plog(LLV_WARNING, LOCATION, iph1->remote,
1507 "ignore INITIAL-CONTACT notification, "
1508 "because it is only accepted after phase1.\n");
1509 break;
1510 default:
1511 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
1512 plog(LLV_ERROR, LOCATION, iph1->remote,
1513 "received unknown notification type %s.\n",
1514 s_isakmp_notify_msg(ntohs(notify->type)));
1515 }
1516
1517 return;
1518 }
1519
1520
1521 #ifdef ENABLE_DPD
1522 static int
isakmp_info_recv_r_u(iph1,ru,msgid)1523 isakmp_info_recv_r_u (iph1, ru, msgid)
1524 struct ph1handle *iph1;
1525 struct isakmp_pl_ru *ru;
1526 u_int32_t msgid;
1527 {
1528 struct isakmp_pl_ru *ru_ack;
1529 vchar_t *payload = NULL;
1530 int tlen;
1531 int error = 0;
1532
1533 plog(LLV_DEBUG, LOCATION, iph1->remote,
1534 "DPD R-U-There received\n");
1535
1536 /* XXX should compare cookies with iph1->index?
1537 Or is this already done by calling function? */
1538 tlen = sizeof(*ru_ack);
1539 payload = vmalloc(tlen);
1540 if (payload == NULL) {
1541 plog(LLV_ERROR, LOCATION, NULL,
1542 "failed to get buffer to send.\n");
1543 return errno;
1544 }
1545
1546 ru_ack = (struct isakmp_pl_ru *)payload->v;
1547 ru_ack->h.np = ISAKMP_NPTYPE_NONE;
1548 ru_ack->h.len = htons(tlen);
1549 ru_ack->doi = htonl(IPSEC_DOI);
1550 ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK);
1551 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */
1552 ru_ack->spi_size = sizeof(isakmp_index);
1553 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t));
1554 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t));
1555 ru_ack->data = ru->data;
1556
1557 /* XXX Should we do FLAG_A ? */
1558 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
1559 ISAKMP_FLAG_E);
1560 vfree(payload);
1561
1562 plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n");
1563
1564 /* Should we mark tunnel as active ? */
1565 return error;
1566 }
1567
1568 static int
isakmp_info_recv_r_u_ack(iph1,ru,msgid)1569 isakmp_info_recv_r_u_ack (iph1, ru, msgid)
1570 struct ph1handle *iph1;
1571 struct isakmp_pl_ru *ru;
1572 u_int32_t msgid;
1573 {
1574
1575 plog(LLV_DEBUG, LOCATION, iph1->remote,
1576 "DPD R-U-There-Ack received\n");
1577
1578 /* XXX Maintain window of acceptable sequence numbers ?
1579 * => ru->data <= iph2->dpd_seq &&
1580 * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */
1581 if (ntohl(ru->data) != iph1->dpd_seq-1) {
1582 plog(LLV_ERROR, LOCATION, iph1->remote,
1583 "Wrong DPD sequence number (%d, %d expected).\n",
1584 ntohl(ru->data), iph1->dpd_seq-1);
1585 return 0;
1586 }
1587
1588 if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) ||
1589 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) {
1590 plog(LLV_ERROR, LOCATION, iph1->remote,
1591 "Cookie mismatch in DPD ACK!.\n");
1592 return 0;
1593 }
1594
1595 iph1->dpd_fails = 0;
1596
1597 /* Useless ??? */
1598 iph1->dpd_lastack = time(NULL);
1599
1600 SCHED_KILL(iph1->dpd_r_u);
1601
1602 isakmp_sched_r_u(iph1, 0);
1603
1604 plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
1605
1606 return 0;
1607 }
1608
1609
1610
1611
1612 /*
1613 * send DPD R-U-THERE payload in Informational exchange.
1614 */
1615 static void
isakmp_info_send_r_u(arg)1616 isakmp_info_send_r_u(arg)
1617 void *arg;
1618 {
1619 struct ph1handle *iph1 = arg;
1620
1621 /* create R-U-THERE payload */
1622 struct isakmp_pl_ru *ru;
1623 vchar_t *payload = NULL;
1624 int tlen;
1625 int error = 0;
1626
1627 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n");
1628
1629 iph1->dpd_r_u=NULL;
1630
1631 if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
1632
1633 plog(LLV_INFO, LOCATION, iph1->remote,
1634 "DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n",
1635 isakmp_pindex(&iph1->index, 0));
1636
1637 EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL);
1638 purge_remote(iph1);
1639
1640 /* Do not reschedule here: phase1 is deleted,
1641 * DPD will be reactivated when a new ph1 will be negociated
1642 */
1643 return;
1644 }
1645
1646 /* TODO: check recent activity to avoid useless sends... */
1647
1648 tlen = sizeof(*ru);
1649 payload = vmalloc(tlen);
1650 if (payload == NULL) {
1651 plog(LLV_ERROR, LOCATION, NULL,
1652 "failed to get buffer for payload.\n");
1653 return;
1654 }
1655 ru = (struct isakmp_pl_ru *)payload->v;
1656 ru->h.np = ISAKMP_NPTYPE_NONE;
1657 ru->h.len = htons(tlen);
1658 ru->doi = htonl(IPSEC_DOI);
1659 ru->type = htons(ISAKMP_NTYPE_R_U_THERE);
1660 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/
1661 ru->spi_size = sizeof(isakmp_index);
1662
1663 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t));
1664 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t));
1665
1666 if (iph1->dpd_seq == 0){
1667 /* generate a random seq which is not too big */
1668 srand(time(NULL));
1669 iph1->dpd_seq = rand() & 0x0fff;
1670 }
1671
1672 ru->data = htonl(iph1->dpd_seq);
1673
1674 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
1675 vfree(payload);
1676
1677 plog(LLV_DEBUG, LOCATION, iph1->remote,
1678 "DPD R-U-There sent (%d)\n", error);
1679
1680 /* will be decreased if ACK received... */
1681 iph1->dpd_fails++;
1682
1683 /* XXX should be increased only when ACKed ? */
1684 iph1->dpd_seq++;
1685
1686 /* Reschedule the r_u_there with a short delay,
1687 * will be deleted/rescheduled if ACK received before */
1688 isakmp_sched_r_u(iph1, 1);
1689
1690 plog(LLV_DEBUG, LOCATION, iph1->remote,
1691 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry);
1692 }
1693
1694 /* Schedule a new R-U-THERE */
1695 int
isakmp_sched_r_u(iph1,retry)1696 isakmp_sched_r_u(iph1, retry)
1697 struct ph1handle *iph1;
1698 int retry;
1699 {
1700 if(iph1 == NULL ||
1701 iph1->rmconf == NULL)
1702 return 1;
1703
1704
1705 if(iph1->dpd_support == 0 ||
1706 iph1->rmconf->dpd_interval == 0)
1707 return 0;
1708
1709 if(retry)
1710 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry,
1711 isakmp_info_send_r_u, iph1);
1712 else
1713 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
1714 isakmp_info_send_r_u, iph1);
1715
1716 return 0;
1717 }
1718 #endif
1719