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