1 /* $NetBSD: isakmp_inf.c,v 1.47 2011/03/15 13:20:14 vanhu Exp $ */
2
3 /* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39
40 #include <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((struct sched *));
111 #endif
112
113 static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
114
115 /* %%%
116 * Information Exchange
117 */
118 /*
119 * receive Information
120 */
121 int
isakmp_info_recv(iph1,msg0)122 isakmp_info_recv(iph1, msg0)
123 struct ph1handle *iph1;
124 vchar_t *msg0;
125 {
126 vchar_t *msg = NULL;
127 vchar_t *pbuf = NULL;
128 u_int32_t msgid = 0;
129 int error = -1;
130 struct isakmp *isakmp;
131 struct isakmp_gen *gen;
132 struct isakmp_parse_t *pa, *pap;
133 void *p;
134 vchar_t *hash, *payload;
135 struct isakmp_gen *nd;
136 u_int8_t np;
137 int encrypted;
138
139 plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n");
140
141 encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
142 msgid = ((struct isakmp *)msg0->v)->msgid;
143
144 /* Use new IV to decrypt Informational message. */
145 if (encrypted) {
146 struct isakmp_ivm *ivm;
147
148 if (iph1->ivm == NULL) {
149 plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n");
150 return -1;
151 }
152
153 /* compute IV */
154 ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
155 if (ivm == NULL)
156 return -1;
157
158 msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
159 oakley_delivm(ivm);
160 if (msg == NULL)
161 return -1;
162
163 } else
164 msg = vdup(msg0);
165
166 /* Safety check */
167 if (msg->l < sizeof(*isakmp) + sizeof(*gen)) {
168 plog(LLV_ERROR, LOCATION, NULL,
169 "ignore information because the "
170 "message is way too short - %zu byte(s).\n",
171 msg->l);
172 goto end;
173 }
174
175 isakmp = (struct isakmp *)msg->v;
176 gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
177 np = gen->np;
178
179 if (encrypted) {
180 if (isakmp->np != ISAKMP_NPTYPE_HASH) {
181 plog(LLV_ERROR, LOCATION, NULL,
182 "ignore information because the "
183 "message has no hash payload.\n");
184 goto end;
185 }
186
187 if (iph1->status != PHASE1ST_ESTABLISHED &&
188 iph1->status != PHASE1ST_DYING) {
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",
200 msg->l);
201 goto end;
202 }
203
204 p = (caddr_t) gen + sizeof(struct isakmp_gen);
205 nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len));
206
207 /* nd length check */
208 if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) +
209 ntohs(gen->len))) {
210 plog(LLV_ERROR, LOCATION, NULL,
211 "too long payload length (broken message?)\n");
212 goto end;
213 }
214
215 if (ntohs(nd->len) < sizeof(*nd)) {
216 plog(LLV_ERROR, LOCATION, NULL,
217 "too short payload length (broken message?)\n");
218 goto end;
219 }
220
221 payload = vmalloc(ntohs(nd->len));
222 if (payload == NULL) {
223 plog(LLV_ERROR, LOCATION, NULL,
224 "cannot allocate memory\n");
225 goto end;
226 }
227
228 memcpy(payload->v, (caddr_t) nd, ntohs(nd->len));
229
230 /* compute HASH */
231 hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
232 if (hash == NULL) {
233 plog(LLV_ERROR, LOCATION, NULL,
234 "cannot compute hash\n");
235
236 vfree(payload);
237 goto end;
238 }
239
240 if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) {
241 plog(LLV_ERROR, LOCATION, NULL,
242 "ignore information due to hash length mismatch\n");
243
244 vfree(hash);
245 vfree(payload);
246 goto end;
247 }
248
249 if (memcmp(p, hash->v, hash->l) != 0) {
250 plog(LLV_ERROR, LOCATION, NULL,
251 "ignore information due to hash mismatch\n");
252
253 vfree(hash);
254 vfree(payload);
255 goto end;
256 }
257
258 plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n");
259
260 vfree(hash);
261 vfree(payload);
262 } else {
263 /* make sure the packet was encrypted after the beginning of phase 1. */
264 switch (iph1->etype) {
265 case ISAKMP_ETYPE_AGG:
266 case ISAKMP_ETYPE_BASE:
267 case ISAKMP_ETYPE_IDENT:
268 if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT)
269 || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) {
270 break;
271 }
272 /*FALLTHRU*/
273 default:
274 plog(LLV_ERROR, LOCATION, iph1->remote,
275 "%s message must be encrypted\n",
276 s_isakmp_nptype(np));
277 error = 0;
278 goto end;
279 }
280 }
281
282 if (!(pbuf = isakmp_parse(msg))) {
283 error = -1;
284 goto end;
285 }
286
287 error = 0;
288 for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) {
289 switch (pa->type) {
290 case ISAKMP_NPTYPE_HASH:
291 /* Handled above */
292 break;
293 case ISAKMP_NPTYPE_N:
294 error = isakmp_info_recv_n(iph1,
295 (struct isakmp_pl_n *)pa->ptr,
296 msgid, encrypted);
297 break;
298 case ISAKMP_NPTYPE_D:
299 error = isakmp_info_recv_d(iph1,
300 (struct isakmp_pl_d *)pa->ptr,
301 msgid, encrypted);
302 break;
303 case ISAKMP_NPTYPE_NONCE:
304 /* XXX to be 6.4.2 ike-01.txt */
305 /* XXX IV is to be synchronized. */
306 plog(LLV_ERROR, LOCATION, iph1->remote,
307 "ignore Acknowledged Informational\n");
308 break;
309 default:
310 /* don't send information, see isakmp_ident_r1() */
311 error = 0;
312 plog(LLV_ERROR, LOCATION, iph1->remote,
313 "reject the packet, "
314 "received unexpected payload type %s.\n",
315 s_isakmp_nptype(gen->np));
316 }
317 if (error < 0)
318 break;
319 }
320 end:
321 if (msg != NULL)
322 vfree(msg);
323 if (pbuf != NULL)
324 vfree(pbuf);
325 return error;
326 }
327
328
329 /*
330 * log unhandled / unallowed Notification payload
331 */
332 int
isakmp_log_notify(iph1,notify,exchange)333 isakmp_log_notify(iph1, notify, exchange)
334 struct ph1handle *iph1;
335 struct isakmp_pl_n *notify;
336 const char *exchange;
337 {
338 u_int type;
339 char *nraw, *ndata, *nhex;
340 size_t l;
341
342 type = ntohs(notify->type);
343 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
344 plog(LLV_ERROR, LOCATION, iph1->remote,
345 "invalid spi_size in %s notification in %s.\n",
346 s_isakmp_notify_msg(type), exchange);
347 return -1;
348 }
349
350 plog(LLV_ERROR, LOCATION, iph1->remote,
351 "notification %s received in %s.\n",
352 s_isakmp_notify_msg(type), exchange);
353
354 nraw = ((char*) notify) + sizeof(*notify) + notify->spi_size;
355 l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
356 if (l > 0) {
357 if (type >= ISAKMP_NTYPE_MINERROR &&
358 type <= ISAKMP_NTYPE_MAXERROR) {
359 ndata = binsanitize(nraw, l);
360 if (ndata != NULL) {
361 plog(LLV_ERROR, LOCATION, iph1->remote,
362 "error message: '%s'.\n",
363 ndata);
364 racoon_free(ndata);
365 } else {
366 plog(LLV_ERROR, LOCATION, iph1->remote,
367 "Cannot allocate memory\n");
368 }
369 } else {
370 nhex = val2str(nraw, l);
371 if (nhex != NULL) {
372 plog(LLV_ERROR, LOCATION, iph1->remote,
373 "notification payload: %s.\n",
374 nhex);
375 racoon_free(nhex);
376 } else {
377 plog(LLV_ERROR, LOCATION, iph1->remote,
378 "Cannot allocate memory\n");
379 }
380 }
381 }
382
383 return 0;
384 }
385
386
387 /*
388 * handling of Notification payload
389 */
390 static int
isakmp_info_recv_n(iph1,notify,msgid,encrypted)391 isakmp_info_recv_n(iph1, notify, msgid, encrypted)
392 struct ph1handle *iph1;
393 struct isakmp_pl_n *notify;
394 u_int32_t msgid;
395 int encrypted;
396 {
397 u_int type;
398
399 type = ntohs(notify->type);
400 switch (type) {
401 case ISAKMP_NTYPE_CONNECTED:
402 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
403 case ISAKMP_NTYPE_REPLAY_STATUS:
404 #ifdef ENABLE_HYBRID
405 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
406 #endif
407 /* do something */
408 break;
409 case ISAKMP_NTYPE_INITIAL_CONTACT:
410 if (encrypted)
411 return isakmp_info_recv_initialcontact(iph1, NULL);
412 break;
413 #ifdef ENABLE_DPD
414 case ISAKMP_NTYPE_R_U_THERE:
415 if (encrypted)
416 return isakmp_info_recv_r_u(iph1,
417 (struct isakmp_pl_ru *)notify, msgid);
418 break;
419 case ISAKMP_NTYPE_R_U_THERE_ACK:
420 if (encrypted)
421 return isakmp_info_recv_r_u_ack(iph1,
422 (struct isakmp_pl_ru *)notify, msgid);
423 break;
424 #endif
425 }
426
427 /* If we receive a error notification we should delete the related
428 * phase1 / phase2 handle, and send an event to racoonctl.
429 * However, since phase1 error notifications are not encrypted and
430 * can not be authenticated, it would allow a DoS attack possibility
431 * to handle them.
432 * Phase2 error notifications should be encrypted, so we could handle
433 * those, but it needs implementing (the old code didn't implement
434 * that either).
435 * So we are good to just log the messages here.
436 */
437 if (encrypted)
438 isakmp_log_notify(iph1, notify, "informational exchange");
439 else
440 isakmp_log_notify(iph1, notify, "unencrypted informational exchange");
441
442 return 0;
443 }
444
445 /*
446 * handling of Deletion payload
447 */
448 static int
isakmp_info_recv_d(iph1,delete,msgid,encrypted)449 isakmp_info_recv_d(iph1, delete, msgid, encrypted)
450 struct ph1handle *iph1;
451 struct isakmp_pl_d *delete;
452 u_int32_t msgid;
453 int encrypted;
454 {
455 int tlen, num_spi;
456 vchar_t *pbuf;
457 int protected = 0;
458 struct ph1handle *del_ph1;
459 struct ph2handle *iph2;
460 union {
461 u_int32_t spi32;
462 u_int16_t spi16[2];
463 } spi;
464
465 if (ntohl(delete->doi) != IPSEC_DOI) {
466 plog(LLV_ERROR, LOCATION, iph1->remote,
467 "delete payload with invalid doi:%d.\n",
468 ntohl(delete->doi));
469 #ifdef ENABLE_HYBRID
470 /*
471 * At deconnexion time, Cisco VPN client does this
472 * with a zero DOI. Don't give up in that situation.
473 */
474 if (((iph1->mode_cfg->flags &
475 ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0))
476 return 0;
477 #else
478 return 0;
479 #endif
480 }
481
482 num_spi = ntohs(delete->num_spi);
483 tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d);
484
485 if (tlen != num_spi * delete->spi_size) {
486 plog(LLV_ERROR, LOCATION, iph1->remote,
487 "deletion payload with invalid length.\n");
488 return 0;
489 }
490
491 plog(LLV_DEBUG, LOCATION, iph1->remote,
492 "delete payload for protocol %s\n",
493 s_ipsecdoi_proto(delete->proto_id));
494
495 if(!iph1->rmconf->weak_phase1_check && !encrypted) {
496 plog(LLV_WARNING, LOCATION, iph1->remote,
497 "Ignoring unencrypted delete payload "
498 "(check the weak_phase1_check option)\n");
499 return 0;
500 }
501
502 switch (delete->proto_id) {
503 case IPSECDOI_PROTO_ISAKMP:
504 if (delete->spi_size != sizeof(isakmp_index)) {
505 plog(LLV_ERROR, LOCATION, iph1->remote,
506 "delete payload with strange spi "
507 "size %d(proto_id:%d)\n",
508 delete->spi_size, delete->proto_id);
509 return 0;
510 }
511
512 del_ph1=getph1byindex((isakmp_index *)(delete + 1));
513 if(del_ph1 != NULL){
514
515 evt_phase1(iph1, EVT_PHASE1_PEER_DELETED, NULL);
516 sched_cancel(&del_ph1->scr);
517
518 /*
519 * Delete also IPsec-SAs if rekeying is enabled.
520 */
521 if (ph1_rekey_enabled(del_ph1))
522 purge_remote(del_ph1);
523 else
524 isakmp_ph1expire(del_ph1);
525 }
526 break;
527
528 case IPSECDOI_PROTO_IPSEC_AH:
529 case IPSECDOI_PROTO_IPSEC_ESP:
530 if (delete->spi_size != sizeof(u_int32_t)) {
531 plog(LLV_ERROR, LOCATION, iph1->remote,
532 "delete payload with strange spi "
533 "size %d(proto_id:%d)\n",
534 delete->spi_size, delete->proto_id);
535 return 0;
536 }
537 purge_ipsec_spi(iph1->remote, delete->proto_id,
538 (u_int32_t *)(delete + 1), num_spi);
539 break;
540
541 case IPSECDOI_PROTO_IPCOMP:
542 /* need to handle both 16bit/32bit SPI */
543 memset(&spi, 0, sizeof(spi));
544 if (delete->spi_size == sizeof(spi.spi16[1])) {
545 memcpy(&spi.spi16[1], delete + 1,
546 sizeof(spi.spi16[1]));
547 } else if (delete->spi_size == sizeof(spi.spi32))
548 memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32));
549 else {
550 plog(LLV_ERROR, LOCATION, iph1->remote,
551 "delete payload with strange spi "
552 "size %d(proto_id:%d)\n",
553 delete->spi_size, delete->proto_id);
554 return 0;
555 }
556 purge_ipsec_spi(iph1->remote, delete->proto_id,
557 &spi.spi32, num_spi);
558 break;
559
560 default:
561 plog(LLV_ERROR, LOCATION, iph1->remote,
562 "deletion message received, "
563 "invalid proto_id: %d\n",
564 delete->proto_id);
565 return 0;
566 }
567
568 plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n");
569
570 return 0;
571 }
572
573 /*
574 * send Delete payload (for ISAKMP SA) in Informational exchange.
575 */
576 int
isakmp_info_send_d1(iph1)577 isakmp_info_send_d1(iph1)
578 struct ph1handle *iph1;
579 {
580 struct isakmp_pl_d *d;
581 vchar_t *payload = NULL;
582 int tlen;
583 int error = 0;
584
585 if (iph1->status != PHASE2ST_ESTABLISHED)
586 return 0;
587
588 /* create delete payload */
589
590 /* send SPIs of inbound SAs. */
591 /* XXX should send outbound SAs's ? */
592 tlen = sizeof(*d) + sizeof(isakmp_index);
593 payload = vmalloc(tlen);
594 if (payload == NULL) {
595 plog(LLV_ERROR, LOCATION, NULL,
596 "failed to get buffer for payload.\n");
597 return errno;
598 }
599
600 d = (struct isakmp_pl_d *)payload->v;
601 d->h.np = ISAKMP_NPTYPE_NONE;
602 d->h.len = htons(tlen);
603 d->doi = htonl(IPSEC_DOI);
604 d->proto_id = IPSECDOI_PROTO_ISAKMP;
605 d->spi_size = sizeof(isakmp_index);
606 d->num_spi = htons(1);
607 memcpy(d + 1, &iph1->index, sizeof(isakmp_index));
608
609 error = isakmp_info_send_common(iph1, payload,
610 ISAKMP_NPTYPE_D, 0);
611 vfree(payload);
612
613 return error;
614 }
615
616 /*
617 * send Delete payload (for IPsec SA) in Informational exchange, based on
618 * pfkey msg. It sends always single SPI.
619 */
620 int
isakmp_info_send_d2(iph2)621 isakmp_info_send_d2(iph2)
622 struct ph2handle *iph2;
623 {
624 struct ph1handle *iph1;
625 struct saproto *pr;
626 struct isakmp_pl_d *d;
627 vchar_t *payload = NULL;
628 int tlen;
629 int error = 0;
630 u_int8_t *spi;
631
632 if (iph2->status != PHASE2ST_ESTABLISHED)
633 return 0;
634
635 /*
636 * don't send delete information if there is no phase 1 handler.
637 * It's nonsensical to negotiate phase 1 to send the information.
638 */
639 iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
640 if (iph1 == NULL){
641 plog(LLV_DEBUG2, LOCATION, NULL,
642 "No ph1 handler found, could not send DELETE_SA\n");
643 return 0;
644 }
645
646 /* create delete payload */
647 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
648
649 /* send SPIs of inbound SAs. */
650 /*
651 * XXX should I send outbound SAs's ?
652 * I send inbound SAs's SPI only at the moment because I can't
653 * decode any more if peer send encoded packet without aware of
654 * deletion of SA. Outbound SAs don't come under the situation.
655 */
656 tlen = sizeof(*d) + pr->spisize;
657 payload = vmalloc(tlen);
658 if (payload == NULL) {
659 plog(LLV_ERROR, LOCATION, NULL,
660 "failed to get buffer for payload.\n");
661 return errno;
662 }
663
664 d = (struct isakmp_pl_d *)payload->v;
665 d->h.np = ISAKMP_NPTYPE_NONE;
666 d->h.len = htons(tlen);
667 d->doi = htonl(IPSEC_DOI);
668 d->proto_id = pr->proto_id;
669 d->spi_size = pr->spisize;
670 d->num_spi = htons(1);
671 /*
672 * XXX SPI bits are left-filled, for use with IPComp.
673 * we should be switching to variable-length spi field...
674 */
675 spi = (u_int8_t *)&pr->spi;
676 spi += sizeof(pr->spi);
677 spi -= pr->spisize;
678 memcpy(d + 1, spi, pr->spisize);
679
680 error = isakmp_info_send_common(iph1, payload,
681 ISAKMP_NPTYPE_D, 0);
682 vfree(payload);
683 }
684
685 return error;
686 }
687
688 /*
689 * send Notification payload (for without ISAKMP SA) in Informational exchange
690 */
691 int
isakmp_info_send_nx(isakmp,remote,local,type,data)692 isakmp_info_send_nx(isakmp, remote, local, type, data)
693 struct isakmp *isakmp;
694 struct sockaddr *remote, *local;
695 int type;
696 vchar_t *data;
697 {
698 struct ph1handle *iph1 = NULL;
699 vchar_t *payload = NULL;
700 int tlen;
701 int error = -1;
702 struct isakmp_pl_n *n;
703 int spisiz = 0; /* see below */
704
705 /* add new entry to isakmp status table. */
706 iph1 = newph1();
707 if (iph1 == NULL)
708 return -1;
709
710 memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
711 isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
712 iph1->status = PHASE1ST_START;
713 iph1->side = INITIATOR;
714 iph1->version = isakmp->v;
715 iph1->flags = 0;
716 iph1->msgid = 0; /* XXX */
717 #ifdef ENABLE_HYBRID
718 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL)
719 goto end;
720 #endif
721 #ifdef ENABLE_FRAG
722 iph1->frag = 0;
723 iph1->frag_chain = NULL;
724 #endif
725
726 /* copy remote address */
727 if (copy_ph1addresses(iph1, NULL, remote, local) < 0)
728 goto end;
729
730 tlen = sizeof(*n) + spisiz;
731 if (data)
732 tlen += data->l;
733 payload = vmalloc(tlen);
734 if (payload == NULL) {
735 plog(LLV_ERROR, LOCATION, NULL,
736 "failed to get buffer to send.\n");
737 goto end;
738 }
739
740 n = (struct isakmp_pl_n *)payload->v;
741 n->h.np = ISAKMP_NPTYPE_NONE;
742 n->h.len = htons(tlen);
743 n->doi = htonl(IPSEC_DOI);
744 n->proto_id = IPSECDOI_KEY_IKE;
745 n->spi_size = spisiz;
746 n->type = htons(type);
747 if (spisiz)
748 memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */
749 if (data)
750 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
751
752 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
753 vfree(payload);
754
755 end:
756 if (iph1 != NULL)
757 delph1(iph1);
758
759 return error;
760 }
761
762 /*
763 * send Notification payload (for ISAKMP SA) in Informational exchange
764 */
765 int
isakmp_info_send_n1(iph1,type,data)766 isakmp_info_send_n1(iph1, type, data)
767 struct ph1handle *iph1;
768 int type;
769 vchar_t *data;
770 {
771 vchar_t *payload = NULL;
772 int tlen;
773 int error = 0;
774 struct isakmp_pl_n *n;
775 int spisiz;
776
777 /*
778 * note on SPI size: which description is correct? I have chosen
779 * this to be 0.
780 *
781 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by
782 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0.
783 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified
784 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
785 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
786 */
787 if (type == ISAKMP_NTYPE_INITIAL_CONTACT)
788 spisiz = sizeof(isakmp_index);
789 else
790 spisiz = 0;
791
792 tlen = sizeof(*n) + spisiz;
793 if (data)
794 tlen += data->l;
795 payload = vmalloc(tlen);
796 if (payload == NULL) {
797 plog(LLV_ERROR, LOCATION, NULL,
798 "failed to get buffer to send.\n");
799 return errno;
800 }
801
802 n = (struct isakmp_pl_n *)payload->v;
803 n->h.np = ISAKMP_NPTYPE_NONE;
804 n->h.len = htons(tlen);
805 n->doi = htonl(iph1->rmconf->doitype);
806 n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */
807 n->spi_size = spisiz;
808 n->type = htons(type);
809 if (spisiz)
810 memcpy(n + 1, &iph1->index, sizeof(isakmp_index));
811 if (data)
812 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
813
814 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
815 vfree(payload);
816
817 return error;
818 }
819
820 /*
821 * send Notification payload (for IPsec SA) in Informational exchange
822 */
823 int
isakmp_info_send_n2(iph2,type,data)824 isakmp_info_send_n2(iph2, type, data)
825 struct ph2handle *iph2;
826 int type;
827 vchar_t *data;
828 {
829 struct ph1handle *iph1 = iph2->ph1;
830 vchar_t *payload = NULL;
831 int tlen;
832 int error = 0;
833 struct isakmp_pl_n *n;
834 struct saproto *pr;
835
836 if (!iph2->approval)
837 return EINVAL;
838
839 pr = iph2->approval->head;
840
841 /* XXX must be get proper spi */
842 tlen = sizeof(*n) + pr->spisize;
843 if (data)
844 tlen += data->l;
845 payload = vmalloc(tlen);
846 if (payload == NULL) {
847 plog(LLV_ERROR, LOCATION, NULL,
848 "failed to get buffer to send.\n");
849 return errno;
850 }
851
852 n = (struct isakmp_pl_n *)payload->v;
853 n->h.np = ISAKMP_NPTYPE_NONE;
854 n->h.len = htons(tlen);
855 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
856 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
857 n->spi_size = pr->spisize;
858 n->type = htons(type);
859 *(u_int32_t *)(n + 1) = pr->spi;
860 if (data)
861 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
862
863 iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */
864 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
865 vfree(payload);
866
867 return error;
868 }
869
870 /*
871 * send Information
872 * When ph1->skeyid_a == NULL, send message without encoding.
873 */
874 int
isakmp_info_send_common(iph1,payload,np,flags)875 isakmp_info_send_common(iph1, payload, np, flags)
876 struct ph1handle *iph1;
877 vchar_t *payload;
878 u_int32_t np;
879 int flags;
880 {
881 struct ph2handle *iph2 = NULL;
882 vchar_t *hash = NULL;
883 struct isakmp *isakmp;
884 struct isakmp_gen *gen;
885 char *p;
886 int tlen;
887 int error = -1;
888
889 /* add new entry to isakmp status table */
890 iph2 = newph2();
891 if (iph2 == NULL)
892 goto end;
893
894 iph2->dst = dupsaddr(iph1->remote);
895 if (iph2->dst == NULL) {
896 delph2(iph2);
897 goto end;
898 }
899 iph2->src = dupsaddr(iph1->local);
900 if (iph2->src == NULL) {
901 delph2(iph2);
902 goto end;
903 }
904 iph2->side = INITIATOR;
905 iph2->status = PHASE2ST_START;
906 iph2->msgid = isakmp_newmsgid2(iph1);
907
908 /* get IV and HASH(1) if skeyid_a was generated. */
909 if (iph1->skeyid_a != NULL) {
910 iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
911 if (iph2->ivm == NULL) {
912 delph2(iph2);
913 goto end;
914 }
915
916 /* generate HASH(1) */
917 hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
918 if (hash == NULL) {
919 delph2(iph2);
920 goto end;
921 }
922
923 /* initialized total buffer length */
924 tlen = hash->l;
925 tlen += sizeof(*gen);
926 } else {
927 /* IKE-SA is not established */
928 hash = NULL;
929
930 /* initialized total buffer length */
931 tlen = 0;
932 }
933 if ((flags & ISAKMP_FLAG_A) == 0)
934 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
935 else
936 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
937
938 insph2(iph2);
939 bindph12(iph1, iph2);
940
941 tlen += sizeof(*isakmp) + payload->l;
942
943 /* create buffer for isakmp payload */
944 iph2->sendbuf = vmalloc(tlen);
945 if (iph2->sendbuf == NULL) {
946 plog(LLV_ERROR, LOCATION, NULL,
947 "failed to get buffer to send.\n");
948 goto err;
949 }
950
951 /* create isakmp header */
952 isakmp = (struct isakmp *)iph2->sendbuf->v;
953 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
954 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
955 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
956 isakmp->v = iph1->version;
957 isakmp->etype = ISAKMP_ETYPE_INFO;
958 isakmp->flags = iph2->flags;
959 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
960 isakmp->len = htonl(tlen);
961 p = (char *)(isakmp + 1);
962
963 /* create HASH payload */
964 if (hash != NULL) {
965 gen = (struct isakmp_gen *)p;
966 gen->np = np & 0xff;
967 gen->len = htons(sizeof(*gen) + hash->l);
968 p += sizeof(*gen);
969 memcpy(p, hash->v, hash->l);
970 p += hash->l;
971 }
972
973 /* add payload */
974 memcpy(p, payload->v, payload->l);
975 p += payload->l;
976
977 #ifdef HAVE_PRINT_ISAKMP_C
978 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
979 #endif
980
981 /* encoding */
982 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
983 vchar_t *tmp;
984
985 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
986 iph2->ivm->iv);
987 VPTRINIT(iph2->sendbuf);
988 if (tmp == NULL)
989 goto err;
990 iph2->sendbuf = tmp;
991 }
992
993 /* HDR*, HASH(1), N */
994 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
995 VPTRINIT(iph2->sendbuf);
996 goto err;
997 }
998
999 plog(LLV_DEBUG, LOCATION, NULL,
1000 "sendto Information %s.\n", s_isakmp_nptype(np));
1001
1002 /*
1003 * don't resend notify message because peer can use Acknowledged
1004 * Informational if peer requires the reply of the notify message.
1005 */
1006
1007 /* XXX If Acknowledged Informational required, don't delete ph2handle */
1008 error = 0;
1009 VPTRINIT(iph2->sendbuf);
1010 goto err; /* XXX */
1011
1012 end:
1013 if (hash)
1014 vfree(hash);
1015 return error;
1016
1017 err:
1018 remph2(iph2);
1019 delph2(iph2);
1020 goto end;
1021 }
1022
1023 /*
1024 * add a notify payload to buffer by reallocating buffer.
1025 * If buf == NULL, the function only create a notify payload.
1026 *
1027 * XXX Which is SPI to be included, inbound or outbound ?
1028 */
1029 vchar_t *
isakmp_add_pl_n(buf0,np_p,type,pr,data)1030 isakmp_add_pl_n(buf0, np_p, type, pr, data)
1031 vchar_t *buf0;
1032 u_int8_t **np_p;
1033 int type;
1034 struct saproto *pr;
1035 vchar_t *data;
1036 {
1037 vchar_t *buf = NULL;
1038 struct isakmp_pl_n *n;
1039 int tlen;
1040 int oldlen = 0;
1041
1042 if (*np_p)
1043 **np_p = ISAKMP_NPTYPE_N;
1044
1045 tlen = sizeof(*n) + pr->spisize;
1046
1047 if (data)
1048 tlen += data->l;
1049 if (buf0) {
1050 oldlen = buf0->l;
1051 buf = vrealloc(buf0, buf0->l + tlen);
1052 } else
1053 buf = vmalloc(tlen);
1054 if (!buf) {
1055 plog(LLV_ERROR, LOCATION, NULL,
1056 "failed to get a payload buffer.\n");
1057 return NULL;
1058 }
1059
1060 n = (struct isakmp_pl_n *)(buf->v + oldlen);
1061 n->h.np = ISAKMP_NPTYPE_NONE;
1062 n->h.len = htons(tlen);
1063 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
1064 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
1065 n->spi_size = pr->spisize;
1066 n->type = htons(type);
1067 *(u_int32_t *)(n + 1) = pr->spi; /* XXX */
1068 if (data)
1069 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
1070
1071 /* save the pointer of next payload type */
1072 *np_p = &n->h.np;
1073
1074 return buf;
1075 }
1076
1077 static void
purge_isakmp_spi(proto,spi,n)1078 purge_isakmp_spi(proto, spi, n)
1079 int proto;
1080 isakmp_index *spi; /*network byteorder*/
1081 size_t n;
1082 {
1083 struct ph1handle *iph1;
1084 size_t i;
1085
1086 for (i = 0; i < n; i++) {
1087 iph1 = getph1byindex(&spi[i]);
1088 if (!iph1)
1089 continue;
1090
1091 plog(LLV_INFO, LOCATION, NULL,
1092 "purged ISAKMP-SA proto_id=%s spi=%s.\n",
1093 s_ipsecdoi_proto(proto),
1094 isakmp_pindex(&spi[i], 0));
1095
1096 iph1->status = PHASE1ST_EXPIRED;
1097 isakmp_ph1delete(iph1);
1098 }
1099 }
1100
1101
1102
1103 void
purge_ipsec_spi(dst0,proto,spi,n)1104 purge_ipsec_spi(dst0, proto, spi, n)
1105 struct sockaddr *dst0;
1106 int proto;
1107 u_int32_t *spi; /*network byteorder*/
1108 size_t n;
1109 {
1110 vchar_t *buf = NULL;
1111 struct sadb_msg *msg, *next, *end;
1112 struct sadb_sa *sa;
1113 struct sadb_lifetime *lt;
1114 struct sockaddr *src, *dst;
1115 struct ph2handle *iph2;
1116 u_int64_t created;
1117 size_t i;
1118 caddr_t mhp[SADB_EXT_MAX + 1];
1119
1120 plog(LLV_DEBUG2, LOCATION, NULL,
1121 "purge_ipsec_spi:\n");
1122 plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0));
1123 plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0]));
1124
1125 buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto));
1126 if (buf == NULL) {
1127 plog(LLV_DEBUG, LOCATION, NULL,
1128 "pfkey_dump_sadb returned nothing.\n");
1129 return;
1130 }
1131
1132 msg = (struct sadb_msg *)buf->v;
1133 end = (struct sadb_msg *)(buf->v + buf->l);
1134
1135 while (msg < end) {
1136 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1137 break;
1138 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
1139 if (msg->sadb_msg_type != SADB_DUMP) {
1140 msg = next;
1141 continue;
1142 }
1143
1144 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
1145 plog(LLV_ERROR, LOCATION, NULL,
1146 "pfkey_check (%s)\n", ipsec_strerror());
1147 msg = next;
1148 continue;
1149 }
1150
1151 sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
1152 if (!sa
1153 || !mhp[SADB_EXT_ADDRESS_SRC]
1154 || !mhp[SADB_EXT_ADDRESS_DST]) {
1155 msg = next;
1156 continue;
1157 }
1158 pk_fixup_sa_addresses(mhp);
1159 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1160 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1161 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
1162 if(lt != NULL)
1163 created = lt->sadb_lifetime_addtime;
1164 else
1165 created = 0;
1166
1167 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1168 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1169 msg = next;
1170 continue;
1171 }
1172
1173 plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
1174 plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst));
1175
1176 /* XXX n^2 algorithm, inefficient */
1177
1178 /* don't delete inbound SAs at the moment */
1179 /* XXX should we remove SAs with opposite direction as well? */
1180 if (cmpsaddr(dst0, dst) != CMPSADDR_MATCH) {
1181 msg = next;
1182 continue;
1183 }
1184
1185 for (i = 0; i < n; i++) {
1186 plog(LLV_DEBUG, LOCATION, NULL,
1187 "check spi(packet)=%u spi(db)=%u.\n",
1188 ntohl(spi[i]), ntohl(sa->sadb_sa_spi));
1189 if (spi[i] != sa->sadb_sa_spi)
1190 continue;
1191
1192 pfkey_send_delete(lcconf->sock_pfkey,
1193 msg->sadb_msg_satype,
1194 IPSEC_MODE_ANY,
1195 src, dst, sa->sadb_sa_spi);
1196
1197 /*
1198 * delete a relative phase 2 handler.
1199 * continue to process if no relative phase 2 handler
1200 * exists.
1201 */
1202 iph2 = getph2bysaidx(src, dst, proto, spi[i]);
1203 if(iph2 != NULL){
1204 delete_spd(iph2, created);
1205 remph2(iph2);
1206 delph2(iph2);
1207 }
1208
1209 plog(LLV_INFO, LOCATION, NULL,
1210 "purged IPsec-SA proto_id=%s spi=%u.\n",
1211 s_ipsecdoi_proto(proto),
1212 ntohl(spi[i]));
1213 }
1214
1215 msg = next;
1216 }
1217
1218 if (buf)
1219 vfree(buf);
1220 }
1221
1222 /*
1223 * delete all phase2 sa relatived to the destination address
1224 * (except the phase2 within which the INITIAL-CONTACT was received).
1225 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
1226 * an INITIAL-CONTACT if we have contacted the peer. This matches the
1227 * Sun IKE behavior, and makes rekeying work much better when the peer
1228 * restarts.
1229 */
1230 int
isakmp_info_recv_initialcontact(iph1,protectedph2)1231 isakmp_info_recv_initialcontact(iph1, protectedph2)
1232 struct ph1handle *iph1;
1233 struct ph2handle *protectedph2;
1234 {
1235 vchar_t *buf = NULL;
1236 struct sadb_msg *msg, *next, *end;
1237 struct sadb_sa *sa;
1238 struct sockaddr *src, *dst;
1239 caddr_t mhp[SADB_EXT_MAX + 1];
1240 int proto_id, i;
1241 struct ph2handle *iph2;
1242 #if 0
1243 char *loc, *rem;
1244 #endif
1245
1246 plog(LLV_INFO, LOCATION, iph1->remote, "received INITIAL-CONTACT\n");
1247
1248 if (f_local)
1249 return 0;
1250
1251 #if 0
1252 loc = racoon_strdup(saddrwop2str(iph1->local));
1253 rem = racoon_strdup(saddrwop2str(iph1->remote));
1254 STRDUP_FATAL(loc);
1255 STRDUP_FATAL(rem);
1256
1257 /*
1258 * Purge all IPSEC-SAs for the peer. We can do this
1259 * the easy way (using a PF_KEY SADB_DELETE extension)
1260 * or we can do it the hard way.
1261 */
1262 for (i = 0; i < pfkey_nsatypes; i++) {
1263 proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype);
1264
1265 plog(LLV_INFO, LOCATION, NULL,
1266 "purging %s SAs for %s -> %s\n",
1267 pfkey_satypes[i].ps_name, loc, rem);
1268 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1269 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1270 iph1->local, iph1->remote) == -1) {
1271 plog(LLV_ERROR, LOCATION, NULL,
1272 "delete_all %s -> %s failed for %s (%s)\n",
1273 loc, rem,
1274 pfkey_satypes[i].ps_name, ipsec_strerror());
1275 goto the_hard_way;
1276 }
1277
1278 deleteallph2(iph1->local, iph1->remote, proto_id);
1279
1280 plog(LLV_INFO, LOCATION, NULL,
1281 "purging %s SAs for %s -> %s\n",
1282 pfkey_satypes[i].ps_name, rem, loc);
1283 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1284 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1285 iph1->remote, iph1->local) == -1) {
1286 plog(LLV_ERROR, LOCATION, NULL,
1287 "delete_all %s -> %s failed for %s (%s)\n",
1288 rem, loc,
1289 pfkey_satypes[i].ps_name, ipsec_strerror());
1290 goto the_hard_way;
1291 }
1292
1293 deleteallph2(iph1->remote, iph1->local, proto_id);
1294 }
1295
1296 racoon_free(loc);
1297 racoon_free(rem);
1298 return 0;
1299
1300 the_hard_way:
1301 racoon_free(loc);
1302 racoon_free(rem);
1303 #endif
1304
1305 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
1306 if (buf == NULL) {
1307 plog(LLV_DEBUG, LOCATION, NULL,
1308 "pfkey_dump_sadb returned nothing.\n");
1309 return 0;
1310 }
1311
1312 msg = (struct sadb_msg *)buf->v;
1313 end = (struct sadb_msg *)(buf->v + buf->l);
1314
1315 for (; msg < end; msg = next) {
1316 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1317 break;
1318
1319 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
1320 if (msg->sadb_msg_type != SADB_DUMP)
1321 continue;
1322
1323 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
1324 plog(LLV_ERROR, LOCATION, NULL,
1325 "pfkey_check (%s)\n", ipsec_strerror());
1326 continue;
1327 }
1328
1329 if (mhp[SADB_EXT_SA] == NULL
1330 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1331 || mhp[SADB_EXT_ADDRESS_DST] == NULL)
1332 continue;
1333
1334 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1335 pk_fixup_sa_addresses(mhp);
1336 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1337 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1338
1339 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1340 && sa->sadb_sa_state != SADB_SASTATE_DYING)
1341 continue;
1342
1343 /*
1344 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that
1345 * announces the sender of the message was rebooted.
1346 * it is interpreted to delete all SAs which source address
1347 * is the sender of the message.
1348 * racoon only deletes SA which is matched both the
1349 * source address and the destination accress.
1350 */
1351
1352 /*
1353 * Check that the IP and port match. But this is not optimal,
1354 * since NAT-T can make the peer have multiple different
1355 * ports. Correct thing to do is delete all entries with
1356 * same identity. -TT
1357 */
1358 if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH ||
1359 cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) &&
1360 (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH ||
1361 cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH))
1362 continue;
1363
1364 /*
1365 * Make sure this is an SATYPE that we manage.
1366 * This is gross; too bad we couldn't do it the
1367 * easy way.
1368 */
1369 for (i = 0; i < pfkey_nsatypes; i++) {
1370 if (pfkey_satypes[i].ps_satype ==
1371 msg->sadb_msg_satype)
1372 break;
1373 }
1374 if (i == pfkey_nsatypes)
1375 continue;
1376
1377 plog(LLV_INFO, LOCATION, NULL,
1378 "purging spi=%u.\n", ntohl(sa->sadb_sa_spi));
1379 pfkey_send_delete(lcconf->sock_pfkey,
1380 msg->sadb_msg_satype,
1381 IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi);
1382
1383 /*
1384 * delete a relative phase 2 handler.
1385 * continue to process if no relative phase 2 handler
1386 * exists.
1387 */
1388 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1389 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1390 if (iph2 && iph2 != protectedph2) {
1391 delete_spd(iph2, 0);
1392 remph2(iph2);
1393 delph2(iph2);
1394 }
1395 }
1396
1397 vfree(buf);
1398 return 0;
1399 }
1400
1401
1402 #ifdef ENABLE_DPD
1403 static int
isakmp_info_recv_r_u(iph1,ru,msgid)1404 isakmp_info_recv_r_u (iph1, ru, msgid)
1405 struct ph1handle *iph1;
1406 struct isakmp_pl_ru *ru;
1407 u_int32_t msgid;
1408 {
1409 struct isakmp_pl_ru *ru_ack;
1410 vchar_t *payload = NULL;
1411 int tlen;
1412 int error = 0;
1413
1414 plog(LLV_DEBUG, LOCATION, iph1->remote,
1415 "DPD R-U-There received\n");
1416
1417 /* XXX should compare cookies with iph1->index?
1418 Or is this already done by calling function? */
1419 tlen = sizeof(*ru_ack);
1420 payload = vmalloc(tlen);
1421 if (payload == NULL) {
1422 plog(LLV_ERROR, LOCATION, NULL,
1423 "failed to get buffer to send.\n");
1424 return errno;
1425 }
1426
1427 ru_ack = (struct isakmp_pl_ru *)payload->v;
1428 ru_ack->h.np = ISAKMP_NPTYPE_NONE;
1429 ru_ack->h.len = htons(tlen);
1430 ru_ack->doi = htonl(IPSEC_DOI);
1431 ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK);
1432 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */
1433 ru_ack->spi_size = sizeof(isakmp_index);
1434 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t));
1435 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t));
1436 ru_ack->data = ru->data;
1437
1438 /* XXX Should we do FLAG_A ? */
1439 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
1440 ISAKMP_FLAG_E);
1441 vfree(payload);
1442
1443 plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n");
1444
1445 /* Should we mark tunnel as active ? */
1446 return error;
1447 }
1448
1449 static int
isakmp_info_recv_r_u_ack(iph1,ru,msgid)1450 isakmp_info_recv_r_u_ack (iph1, ru, msgid)
1451 struct ph1handle *iph1;
1452 struct isakmp_pl_ru *ru;
1453 u_int32_t msgid;
1454 {
1455 u_int32_t seq;
1456
1457 plog(LLV_DEBUG, LOCATION, iph1->remote,
1458 "DPD R-U-There-Ack received\n");
1459
1460 seq = ntohl(ru->data);
1461 if (seq <= iph1->dpd_last_ack || seq > iph1->dpd_seq) {
1462 plog(LLV_ERROR, LOCATION, iph1->remote,
1463 "Wrong DPD sequence number (%d; last_ack=%d, seq=%d).\n",
1464 seq, iph1->dpd_last_ack, iph1->dpd_seq);
1465 return 0;
1466 }
1467
1468 if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) ||
1469 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) {
1470 plog(LLV_ERROR, LOCATION, iph1->remote,
1471 "Cookie mismatch in DPD ACK!.\n");
1472 return 0;
1473 }
1474
1475 iph1->dpd_fails = 0;
1476 iph1->dpd_last_ack = seq;
1477 sched_cancel(&iph1->dpd_r_u);
1478 isakmp_sched_r_u(iph1, 0);
1479
1480 plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
1481
1482 return 0;
1483 }
1484
1485
1486
1487
1488 /*
1489 * send DPD R-U-THERE payload in Informational exchange.
1490 */
1491 static void
isakmp_info_send_r_u(sc)1492 isakmp_info_send_r_u(sc)
1493 struct sched *sc;
1494 {
1495 struct ph1handle *iph1 = container_of(sc, struct ph1handle, dpd_r_u);
1496
1497 /* create R-U-THERE payload */
1498 struct isakmp_pl_ru *ru;
1499 vchar_t *payload = NULL;
1500 int tlen;
1501 int error = 0;
1502
1503 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n");
1504
1505 if (iph1->status == PHASE1ST_EXPIRED) {
1506 /* This can happen after removing tunnels from the
1507 * config file and then reloading.
1508 * Such iph1 have rmconf=NULL, so return before the if
1509 * block below.
1510 */
1511 return;
1512 }
1513
1514 if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
1515
1516 plog(LLV_INFO, LOCATION, iph1->remote,
1517 "DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n",
1518 isakmp_pindex(&iph1->index, 0));
1519
1520 script_hook(iph1, SCRIPT_PHASE1_DEAD);
1521 evt_phase1(iph1, EVT_PHASE1_DPD_TIMEOUT, NULL);
1522 purge_remote(iph1);
1523
1524 /* Do not reschedule here: phase1 is deleted,
1525 * DPD will be reactivated when a new ph1 will be negociated
1526 */
1527 return;
1528 }
1529
1530 /* TODO: check recent activity to avoid useless sends... */
1531
1532 tlen = sizeof(*ru);
1533 payload = vmalloc(tlen);
1534 if (payload == NULL) {
1535 plog(LLV_ERROR, LOCATION, NULL,
1536 "failed to get buffer for payload.\n");
1537 return;
1538 }
1539 ru = (struct isakmp_pl_ru *)payload->v;
1540 ru->h.np = ISAKMP_NPTYPE_NONE;
1541 ru->h.len = htons(tlen);
1542 ru->doi = htonl(IPSEC_DOI);
1543 ru->type = htons(ISAKMP_NTYPE_R_U_THERE);
1544 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/
1545 ru->spi_size = sizeof(isakmp_index);
1546
1547 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t));
1548 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t));
1549
1550 if (iph1->dpd_seq == 0) {
1551 /* generate a random seq which is not too big */
1552 iph1->dpd_seq = iph1->dpd_last_ack = rand() & 0x0fff;
1553 }
1554
1555 iph1->dpd_seq++;
1556 iph1->dpd_fails++;
1557 ru->data = htonl(iph1->dpd_seq);
1558
1559 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
1560 vfree(payload);
1561
1562 plog(LLV_DEBUG, LOCATION, iph1->remote,
1563 "DPD R-U-There sent (%d)\n", error);
1564
1565 /* Reschedule the r_u_there with a short delay,
1566 * will be deleted/rescheduled if ACK received before */
1567 isakmp_sched_r_u(iph1, 1);
1568
1569 plog(LLV_DEBUG, LOCATION, iph1->remote,
1570 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry);
1571 }
1572
1573 /* Schedule a new R-U-THERE */
1574 int
isakmp_sched_r_u(iph1,retry)1575 isakmp_sched_r_u(iph1, retry)
1576 struct ph1handle *iph1;
1577 int retry;
1578 {
1579 if(iph1 == NULL ||
1580 iph1->rmconf == NULL)
1581 return 1;
1582
1583
1584 if(iph1->dpd_support == 0 ||
1585 iph1->rmconf->dpd_interval == 0)
1586 return 0;
1587
1588 if(retry)
1589 sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_retry,
1590 isakmp_info_send_r_u);
1591 else
1592 sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_interval,
1593 isakmp_info_send_r_u);
1594
1595 return 0;
1596 }
1597 #endif
1598