• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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