1 /* $Id: isakmp_inf.c,v 1.18 2008/07/07 09:36:08 fukumoto 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 #include <netinet/in.h>
39 #include <sys/queue.h>
40
41 #ifdef HAVE_NETINET6_IPSEC_H
42 # include <netinet6/ipsec.h>
43 #else
44 # ifdef HAVE_NETIPSEC_IPSEC_H
45 # include <netipsec/ipsec.h>
46 # else
47 # include <linux/ipsec.h>
48 # endif
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 #ifdef ENABLE_HYBRID
66 #include <resolv.h>
67 #endif
68
69 #include "racoon.h"
70
71 /* #include "libpfkey.h" */
72
73 #include "var.h"
74 /* #include "vmbuf.h" */
75 /* #include "schedule.h" */
76 #include "str2val.h"
77 /* #include "misc.h" */
78 #include "plog.h"
79 #include "debug.h"
80
81 /* #include "localconf.h" */
82 #include "remoteconf.h"
83 #include "proposal.h"
84 #include "sockmisc.h"
85 #include "evt.h"
86 #include "isakmp.h"
87 #include "isakmp_var.h"
88 #include "isakmp_impl.h"
89 #include "ikev1_impl.h"
90 #ifdef ENABLE_HYBRID
91 #include "isakmp_xauth.h"
92 #include "isakmp_unity.h"
93 #include "isakmp_cfg.h"
94 #endif
95 #include "isakmp_inf.h"
96 #include "oakley.h"
97 #include "ipsec_doi.h"
98 #include "handler.h"
99 #include "crypto_impl.h"
100 #include "pfkey.h"
101 /* #include "policy.h" */
102 #include "algorithm.h"
103 /* #include "admin.h" */
104 #include "strnames.h"
105 #ifdef ENABLE_NATT
106 #include "ikev1_natt.h"
107 #endif
108
109 #include "ike_conf.h"
110
111 /* information exchange */
112 static int isakmp_info_recv_n (struct ph1handle *, rc_vchar_t *);
113 static int isakmp_info_recv_d (struct ph1handle *, rc_vchar_t *);
114
115
116 static int isakmp_info_recv_r_u (struct ph1handle *,
117 struct isakmp_pl_ru *, uint32_t);
118 static int isakmp_info_recv_r_u_ack (struct ph1handle *,
119 struct isakmp_pl_ru *, uint32_t);
120 static void isakmp_info_send_r_u (void *);
121
122 /* static void purge_isakmp_spi (int, isakmp_index_t *, size_t); */
123 static void info_recv_initialcontact (struct ph1handle *);
124
125 /* %%%
126 * Information Exchange
127 */
128 /*
129 * receive Information
130 */
131 int
132 isakmp_info_recv(struct ph1handle *iph1, rc_vchar_t *msg0)
133 {
134 rc_vchar_t *msg = NULL;
135 struct isakmp *isakmp;
136 struct isakmp_gen *gen;
137 void *p;
138 rc_vchar_t *hash, *payload;
139 struct isakmp_gen *nd;
140 uint8_t np;
141 int encrypted;
142
143 plog(PLOG_DEBUG, PLOGLOC, NULL, "receive Information.\n");
144
145 encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
146
147 /* Use new IV to decrypt Informational message. */
148 if (encrypted) {
149 struct isakmp_ivm *ivm;
150
151 if (iph1->ivm == NULL) {
152 plog(PLOG_INTERR, PLOGLOC, NULL, "iph1->ivm == NULL\n");
153 return -1;
154 }
155
156 /* compute IV */
157 ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
158 if (ivm == NULL)
159 return -1;
160
161 msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
162 oakley_delivm(ivm);
163 if (msg == NULL)
164 return -1;
165
166 } else
167 msg = rc_vdup(msg0);
168
169 /* Safety check */
170 if (msg->l < sizeof(*isakmp) + sizeof(*gen)) {
171 plog(PLOG_PROTOERR, PLOGLOC, NULL,
172 "ignore information because the "
173 "message is way too short\n");
174 goto end;
175 }
176
177 isakmp = (struct isakmp *)msg->v;
178 gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
179 np = gen->np;
180
181 if (encrypted) {
182 if (isakmp->np != ISAKMP_NPTYPE_HASH) {
183 plog(PLOG_PROTOERR, PLOGLOC, NULL,
184 "ignore information because the "
185 "message has no hash payload.\n");
186 goto end;
187 }
188
189 if (iph1->status != PHASE1ST_ESTABLISHED) {
190 plog(PLOG_PROTOERR, PLOGLOC, NULL,
191 "ignore information because ISAKMP-SA "
192 "has not been established yet.\n");
193 goto end;
194 }
195
196 /* Safety check */
197 if (msg->l < sizeof(*isakmp) + get_uint16(&gen->len) + sizeof(*nd)) {
198 plog(PLOG_PROTOERR, PLOGLOC, NULL,
199 "ignore information because the "
200 "message is too short\n");
201 goto end;
202 }
203
204 p = (caddr_t) gen + sizeof(struct isakmp_gen);
205 nd = (struct isakmp_gen *) ((caddr_t) gen + get_uint16(&gen->len));
206
207 /* nd length check */
208 if (get_uint16(&nd->len) > msg->l - (sizeof(struct isakmp) +
209 get_uint16(&gen->len))) {
210 plog(PLOG_PROTOERR, PLOGLOC, NULL,
211 "too long payload length (broken message?)\n");
212 goto end;
213 }
214
215 if (get_uint16(&nd->len) < sizeof(*nd)) {
216 plog(PLOG_PROTOERR, PLOGLOC, NULL,
217 "too short payload length (broken message?)\n");
218 goto end;
219 }
220
221 payload = rc_vmalloc(get_uint16(&nd->len));
222 if (payload == NULL) {
223 plog(PLOG_INTERR, PLOGLOC, NULL,
224 "cannot allocate memory\n");
225 goto end;
226 }
227
228 memcpy(payload->v, (caddr_t) nd, get_uint16(&nd->len));
229
230 /* compute HASH */
231 hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
232 if (hash == NULL) {
233 plog(PLOG_INTERR, PLOGLOC, NULL,
234 "cannot compute hash\n");
235
236 rc_vfree(payload);
237 goto end;
238 }
239
240 if (get_uint16(&gen->len) - sizeof(struct isakmp_gen) != hash->l) {
241 plog(PLOG_PROTOERR, PLOGLOC, NULL,
242 "ignore information due to hash length mismatch\n");
243
244 rc_vfree(hash);
245 rc_vfree(payload);
246 goto end;
247 }
248
249 if (memcmp(p, hash->v, hash->l) != 0) {
250 plog(PLOG_PROTOERR, PLOGLOC, NULL,
251 "ignore information due to hash mismatch\n");
252
253 rc_vfree(hash);
254 rc_vfree(payload);
255 goto end;
256 }
257
258 plog(PLOG_DEBUG, PLOGLOC, NULL, "hash validated.\n");
259
260 rc_vfree(hash);
261 rc_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(PLOG_PROTOERR, PLOGLOC, 0,
275 "received %s payload is not encrypted\n",
276 s_isakmp_nptype(isakmp->np));
277 goto end;
278 }
279 }
280
281 switch (np) {
282 case ISAKMP_NPTYPE_N:
283 if ( encrypted )
284 isakmp_info_recv_n(iph1, msg);
285 else
286 plog(PLOG_PROTOWARN, PLOGLOC, 0,
287 "received unencrypted Notify payload, ignored\n");
288 break;
289 case ISAKMP_NPTYPE_D:
290 if ( encrypted )
291 isakmp_info_recv_d(iph1, msg);
292 else
293 plog(PLOG_PROTOWARN, PLOGLOC, 0,
294 "received unencrypted Delete payload, ignored\n");
295 break;
296 case ISAKMP_NPTYPE_NONCE:
297 /* XXX to be 6.4.2 ike-01.txt */
298 /* XXX IV is to be synchronized. */
299 plog(PLOG_PROTOERR, PLOGLOC, 0,
300 "ignore Acknowledged Informational\n");
301 break;
302 default:
303 /* don't send information, see isakmp_ident_r1() */
304 plog(PLOG_PROTOERR, PLOGLOC, 0,
305 "reject the packet, "
306 "received unexpected payload type %s.\n",
307 s_isakmp_nptype(gen->np));
308 goto end;
309 }
310
311 end:
312 if (msg != NULL)
313 rc_vfree(msg);
314 return 0;
315 }
316
317 /*
318 * send Delete payload (for ISAKMP SA) in Informational exchange.
319 */
320 int
321 isakmp_info_send_d1(struct ph1handle *iph1)
322 {
323 struct isakmp_pl_d *d;
324 rc_vchar_t *payload = NULL;
325 int tlen;
326 int error = 0;
327
328 if (iph1->status != PHASE2ST_ESTABLISHED)
329 return 0;
330
331 /* create delete payload */
332
333 /* send SPIs of inbound SAs. */
334 /* XXX should send outbound SAs's ? */
335 tlen = sizeof(*d) + sizeof(isakmp_index_t);
336 payload = rc_vmalloc(tlen);
337 if (payload == NULL) {
338 plog(PLOG_INTERR, PLOGLOC, NULL,
339 "failed to get buffer for payload.\n");
340 return errno;
341 }
342
343 d = (struct isakmp_pl_d *)payload->v;
344 d->h.np = ISAKMP_NPTYPE_NONE;
345 put_uint16(&d->h.len, tlen);
346 put_uint32(&d->doi, IPSEC_DOI);
347 d->proto_id = IPSECDOI_PROTO_ISAKMP;
348 d->spi_size = sizeof(isakmp_index_t);
349 put_uint16(&d->num_spi, 1);
350 memcpy(d + 1, &iph1->index, sizeof(isakmp_index_t));
351
352 error = isakmp_info_send_common(iph1, payload,
353 ISAKMP_NPTYPE_D, 0);
354 rc_vfree(payload);
355
356 return error;
357 }
358
359 /*
360 * send Delete payload (for IPsec SA) in Informational exchange, based on
361 * pfkey msg. It sends always single SPI.
362 */
363 int
364 isakmp_info_send_d2(struct ph2handle *iph2)
365 {
366 struct ph1handle *iph1;
367 struct saproto *pr;
368 struct isakmp_pl_d *d;
369 rc_vchar_t *payload = NULL;
370 int tlen;
371 int error = 0;
372 uint8_t *spi;
373
374 if (iph2->status != PHASE2ST_ESTABLISHED)
375 return 0;
376
377 /*
378 * don't send delete information if there is no phase 1 handler.
379 * It's nonsensical to negotiate phase 1 to send the information.
380 */
381 iph1 = getph1byaddr(iph2->src, iph2->dst);
382 if (iph1 == NULL)
383 return 0;
384
385 /* create delete payload */
386 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
387
388 /* send SPIs of inbound SAs. */
389 /*
390 * XXX should I send outbound SAs's ?
391 * I send inbound SAs's SPI only at the moment because I can't
392 * decode any more if peer send encoded packet without aware of
393 * deletion of SA. Outbound SAs don't come under the situation.
394 */
395 tlen = sizeof(*d) + pr->spisize;
396 payload = rc_vmalloc(tlen);
397 if (payload == NULL) {
398 plog(PLOG_INTERR, PLOGLOC, NULL,
399 "failed to get buffer for payload.\n");
400 return errno;
401 }
402
403 d = (struct isakmp_pl_d *)payload->v;
404 d->h.np = ISAKMP_NPTYPE_NONE;
405 put_uint16(&d->h.len, tlen);
406 put_uint32(&d->doi, IPSEC_DOI);
407 d->proto_id = pr->proto_id;
408 d->spi_size = pr->spisize;
409 put_uint16(&d->num_spi, 1);
410 /*
411 * XXX SPI bits are left-filled, for use with IPComp.
412 * we should be switching to variable-length spi field...
413 */
414 spi = (uint8_t *)&pr->spi;
415 spi += sizeof(pr->spi);
416 spi -= pr->spisize;
417 memcpy(d + 1, spi, pr->spisize);
418
419 error = isakmp_info_send_common(iph1, payload,
420 ISAKMP_NPTYPE_D, 0);
421 rc_vfree(payload);
422 }
423
424 return error;
425 }
426
427 /*
428 * send Notification payload (for without ISAKMP SA) in Informational exchange
429 */
430 int
431 isakmp_info_send_nx(struct isakmp *isakmp, struct sockaddr *remote, struct sockaddr *local,
432 int type, rc_vchar_t *data)
433 {
434 struct ph1handle *iph1 = NULL;
435 struct rcf_remote *rmconf;
436 rc_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(PLOG_INTERR, PLOGLOC, 0,
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(isakmp_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 error = -1;
466 goto end;
467 }
468 #endif
469 #ifdef ENABLE_FRAG
470 iph1->frag = 0;
471 iph1->frag_chain = NULL;
472 #endif
473 iph1->proposal = ikev1_conf_to_isakmpsa(rmconf);
474
475 /* copy remote address */
476 if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
477 error = -1;
478 goto end;
479 }
480
481 tlen = sizeof(*n) + spisiz;
482 if (data)
483 tlen += data->l;
484 payload = rc_vmalloc(tlen);
485 if (payload == NULL) {
486 plog(PLOG_INTERR, PLOGLOC, NULL,
487 "failed to get buffer to send.\n");
488 error = -1;
489 goto end;
490 }
491
492 n = (struct isakmp_pl_n *)payload->v;
493 n->h.np = ISAKMP_NPTYPE_NONE;
494 put_uint16(&n->h.len, tlen);
495 put_uint32(&n->doi, IPSEC_DOI);
496 n->proto_id = IPSECDOI_KEY_IKE;
497 n->spi_size = spisiz;
498 put_uint16(&n->type, type);
499 if (spisiz)
500 memset(n + 1, 0, spisiz); /*XXX*/
501 if (data)
502 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
503
504 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
505 rc_vfree(payload);
506
507 end:
508 if (iph1 != NULL)
509 delph1(iph1);
510
511 return error;
512 }
513
514 /*
515 * send Notification payload (for ISAKMP SA) in Informational exchange
516 */
517 int
518 isakmp_info_send_n1(struct ph1handle *iph1, int type, rc_vchar_t *data)
519 {
520 rc_vchar_t *payload = NULL;
521 int tlen;
522 int error = 0;
523 struct isakmp_pl_n *n;
524 int spisiz;
525
526 /*
527 * note on SPI size: which description is correct? I have chosen
528 * this to be 0.
529 *
530 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by
531 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0.
532 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified
533 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
534 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
535 */
536 if (type == ISAKMP_NTYPE_INITIAL_CONTACT)
537 spisiz = sizeof(isakmp_index_t);
538 else
539 spisiz = 0;
540
541 tlen = sizeof(*n) + spisiz;
542 if (data)
543 tlen += data->l;
544 payload = rc_vmalloc(tlen);
545 if (payload == NULL) {
546 plog(PLOG_INTERR, PLOGLOC, NULL,
547 "failed to get buffer to send.\n");
548 return errno;
549 }
550
551 n = (struct isakmp_pl_n *)payload->v;
552 n->h.np = ISAKMP_NPTYPE_NONE;
553 put_uint16(&n->h.len, tlen);
554 put_uint32(&n->doi, ikev1_doitype(iph1->rmconf));
555 n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */
556 n->spi_size = spisiz;
557 put_uint16(&n->type, type);
558 if (spisiz)
559 memcpy(n + 1, &iph1->index, sizeof(isakmp_index_t));
560 if (data)
561 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
562
563 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
564 rc_vfree(payload);
565
566 return error;
567 }
568
569 /*
570 * send Notification payload (for IPsec SA) in Informational exchange
571 */
572 int
573 isakmp_info_send_n2(struct ph2handle *iph2, int type, rc_vchar_t *data)
574 {
575 struct ph1handle *iph1 = iph2->ph1;
576 rc_vchar_t *payload = NULL;
577 int tlen;
578 int error = 0;
579 struct isakmp_pl_n *n;
580 struct saproto *pr;
581
582 if (!iph2->approval)
583 return EINVAL;
584
585 pr = iph2->approval->head;
586
587 /* XXX must be get proper spi */
588 tlen = sizeof(*n) + pr->spisize;
589 if (data)
590 tlen += data->l;
591 payload = rc_vmalloc(tlen);
592 if (payload == NULL) {
593 plog(PLOG_INTERR, PLOGLOC, NULL,
594 "failed to get buffer to send.\n");
595 return errno;
596 }
597
598 n = (struct isakmp_pl_n *)payload->v;
599 n->h.np = ISAKMP_NPTYPE_NONE;
600 put_uint16(&n->h.len, tlen);
601 put_uint32(&n->doi, IPSEC_DOI); /* IPSEC DOI (1) */
602 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
603 n->spi_size = pr->spisize;
604 put_uint16(&n->type, type);
605 memcpy((uint8_t *)(n + 1), &pr->spi, pr->spisize);
606 if (data)
607 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
608
609 iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */
610 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
611 rc_vfree(payload);
612
613 return error;
614 }
615
616 /*
617 * send Information
618 * When ph1->skeyid_a == NULL, send message without encoding.
619 */
620 int
621 isakmp_info_send_common(struct ph1handle *iph1, rc_vchar_t *payload, uint32_t np, int flags)
622 {
623 struct ph2handle *iph2 = NULL;
624 rc_vchar_t *hash = NULL;
625 struct isakmp *isakmp;
626 struct isakmp_gen *gen;
627 char *p;
628 int tlen;
629 int error = -1;
630
631 /* add new entry to isakmp status table */
632 iph2 = newph2();
633 if (iph2 == NULL)
634 goto end;
635
636 iph2->dst = rcs_sadup(iph1->remote);
637 if (iph2->dst == NULL) {
638 delph2(iph2);
639 goto end;
640 }
641
642 iph2->src = rcs_sadup(iph1->local);
643 if (iph2->src == NULL) {
644 delph2(iph2);
645 goto end;
646 }
647
648 iph2->ph1 = iph1;
649 iph2->side = INITIATOR;
650 iph2->status = PHASE2ST_START;
651 iph2->msgid = isakmp_newmsgid2(iph1);
652
653 /* get IV and HASH(1) if skeyid_a was generated. */
654 if (iph1->skeyid_a != NULL) {
655 iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
656 if (iph2->ivm == NULL) {
657 delph2(iph2);
658 goto end;
659 }
660
661 /* generate HASH(1) */
662 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
663 if (hash == NULL) {
664 delph2(iph2);
665 goto end;
666 }
667
668 /* initialized total buffer length */
669 tlen = hash->l;
670 tlen += sizeof(*gen);
671 } else {
672 /* IKE-SA is not established */
673 hash = NULL;
674
675 /* initialized total buffer length */
676 tlen = 0;
677 }
678 if ((flags & ISAKMP_FLAG_A) == 0)
679 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
680 else
681 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
682
683 insph2(iph2);
684 bindph12(iph1, iph2);
685
686 tlen += sizeof(*isakmp) + payload->l;
687
688 /* create buffer for isakmp payload */
689 iph2->sendbuf = rc_vmalloc(tlen);
690 if (iph2->sendbuf == NULL) {
691 plog(PLOG_INTERR, PLOGLOC, NULL,
692 "failed to get buffer to send.\n");
693 goto err;
694 }
695
696 /* create isakmp header */
697 isakmp = (struct isakmp *)iph2->sendbuf->v;
698 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(isakmp_cookie_t));
699 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(isakmp_cookie_t));
700 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
701 isakmp->v = iph1->version;
702 isakmp->etype = ISAKMP_ETYPE_INFO;
703 isakmp->flags = iph2->flags;
704 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
705 put_uint32(&isakmp->len, tlen);
706 p = (char *)(isakmp + 1);
707
708 /* create HASH payload */
709 if (hash != NULL) {
710 gen = (struct isakmp_gen *)p;
711 gen->np = np & 0xff;
712 put_uint16(&gen->len, sizeof(*gen) + hash->l);
713 p += sizeof(*gen);
714 memcpy(p, hash->v, hash->l);
715 p += hash->l;
716 }
717
718 /* add payload */
719 memcpy(p, payload->v, payload->l);
720 p += payload->l;
721
722 #ifdef HAVE_PRINT_ISAKMP_C
723 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
724 #endif
725
726 /* encoding */
727 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
728 rc_vchar_t *tmp;
729
730 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
731 iph2->ivm->iv);
732 VPTRINIT(iph2->sendbuf);
733 if (tmp == NULL)
734 goto err;
735 iph2->sendbuf = tmp;
736 }
737
738 /* HDR*, HASH(1), N */
739 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
740 VPTRINIT(iph2->sendbuf);
741 goto err;
742 }
743
744 plog(PLOG_DEBUG, PLOGLOC, NULL,
745 "sendto Information %s.\n", s_isakmp_nptype(np));
746
747 /*
748 * don't resend notify message because peer can use Acknowledged
749 * Informational if peer requires the reply of the notify message.
750 */
751
752 /* XXX If Acknowledged Informational required, don't delete ph2handle */
753 error = 0;
754 VPTRINIT(iph2->sendbuf);
755 goto err; /* XXX */
756
757 end:
758 if (hash)
759 rc_vfree(hash);
760 return error;
761
762 err:
763 unbindph12(iph2);
764 remph2(iph2);
765 delph2(iph2);
766 goto end;
767 }
768
769 /*
770 * add a notify payload to buffer by reallocating buffer.
771 * If buf == NULL, the function only create a notify payload.
772 *
773 * XXX Which is SPI to be included, inbound or outbound ?
774 */
775 rc_vchar_t *
776 isakmp_add_pl_n(rc_vchar_t *buf0, uint8_t **np_p, int type,
777 struct saproto *pr, rc_vchar_t *data)
778 {
779 rc_vchar_t *buf = NULL;
780 struct isakmp_pl_n *n;
781 int tlen;
782 int oldlen = 0;
783
784 if (*np_p)
785 **np_p = ISAKMP_NPTYPE_N;
786
787 tlen = sizeof(*n) + pr->spisize;
788
789 if (data)
790 tlen += data->l;
791 if (buf0) {
792 oldlen = buf0->l;
793 buf = rc_vrealloc(buf0, buf0->l + tlen);
794 } else
795 buf = rc_vmalloc(tlen);
796 if (!buf) {
797 plog(PLOG_INTERR, PLOGLOC, NULL,
798 "failed to get a payload buffer.\n");
799 return NULL;
800 }
801
802 n = (struct isakmp_pl_n *)(buf->v + oldlen);
803 n->h.np = ISAKMP_NPTYPE_NONE;
804 put_uint16(&n->h.len, tlen);
805 put_uint32(&n->doi, IPSEC_DOI); /* IPSEC DOI (1) */
806 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
807 n->spi_size = pr->spisize;
808 put_uint16(&n->type, type);
809 memcpy((uint8_t *)(n + 1), &pr->spi, pr->spisize);
810 if (data)
811 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
812
813 /* save the pointer of next payload type */
814 *np_p = &n->h.np;
815
816 return buf;
817 }
818
819 /*
820 * handling to receive Notification payload
821 */
822 static int
823 isakmp_info_recv_n(struct ph1handle *iph1, rc_vchar_t *msg)
824 {
825 struct isakmp_pl_n *n = NULL;
826 unsigned int type;
827 rc_vchar_t *pbuf;
828 struct isakmp_parse_t *pa, *pap;
829 char *spi;
830
831 if (!(pbuf = isakmp_parse(msg)))
832 return -1;
833 pa = (struct isakmp_parse_t *)pbuf->v;
834 for (pap = pa; pap->type; pap++) {
835 switch (pap->type) {
836 case ISAKMP_NPTYPE_HASH:
837 /* do something here */
838 break;
839 case ISAKMP_NPTYPE_NONCE:
840 /* send to ack */
841 break;
842 case ISAKMP_NPTYPE_N:
843 n = (struct isakmp_pl_n *)pap->ptr;
844 break;
845 default:
846 rc_vfree(pbuf);
847 return -1;
848 }
849 }
850 rc_vfree(pbuf);
851 if (!n)
852 return -1;
853
854 type = get_uint16(&n->type);
855
856 switch (type) {
857 case ISAKMP_NTYPE_CONNECTED:
858 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
859 case ISAKMP_NTYPE_REPLAY_STATUS:
860 /* do something */
861 break;
862 case ISAKMP_NTYPE_INITIAL_CONTACT:
863 info_recv_initialcontact(iph1);
864 break;
865 case ISAKMP_NTYPE_R_U_THERE:
866 isakmp_info_recv_r_u(iph1, (struct isakmp_pl_ru *)n,
867 ((struct isakmp *)msg->v)->msgid);
868 break;
869 case ISAKMP_NTYPE_R_U_THERE_ACK:
870 isakmp_info_recv_r_u_ack(iph1, (struct isakmp_pl_ru *)n,
871 ((struct isakmp *)msg->v)->msgid);
872 break;
873
874 default:
875 {
876 uint32_t msgid = ((struct isakmp *)msg->v)->msgid;
877 struct ph2handle *iph2;
878
879 /* XXX there is a potential of dos attack. */
880 if (msgid == 0) {
881 /* delete ph1 */
882 plog(PLOG_PROTOERR, PLOGLOC, 0,
883 "delete phase1 handle.\n");
884 return -1;
885 } else {
886 iph2 = getph2bymsgid(iph1, msgid);
887 if (iph2 == NULL) {
888 plog(PLOG_PROTOERR, PLOGLOC, 0,
889 "unknown notify message, "
890 "no phase2 handle found.\n");
891 } else {
892 /* delete ph2 */
893 unbindph12(iph2);
894 remph2(iph2);
895 delph2(iph2);
896 }
897 }
898 }
899 break;
900 }
901
902 /* get spi and allocate */
903 if (get_uint16(&n->h.len) < sizeof(*n) + n->spi_size) {
904 plog(PLOG_PROTOERR, PLOGLOC, 0,
905 "invalid spi_size in notification payload.\n");
906 return -1;
907 }
908 spi = val2str((char *)(n + 1), n->spi_size);
909
910 plog(PLOG_DEBUG, PLOGLOC, 0,
911 "notification message %d:%s, "
912 "doi=%d proto_id=%d spi=%s(size=%d).\n",
913 type, s_isakmp_notify_msg(type),
914 get_uint32(&n->doi), n->proto_id, spi, n->spi_size);
915
916 racoon_free(spi);
917
918 return(0);
919 }
920
921 #if 0
922 static void
923 purge_isakmp_spi(proto, spi, n)
924 int proto;
925 isakmp_index_t *spi; /*network byteorder*/
926 size_t n;
927 {
928 struct ph1handle *iph1;
929 size_t i;
930
931 for (i = 0; i < n; i++) {
932 iph1 = getph1byindex(&spi[i]);
933 if (!iph1)
934 continue;
935
936 plog(PLOG_INFO, PLOGLOC, NULL,
937 "purged ISAKMP-SA proto_id=%s spi=%s.\n",
938 s_ipsecdoi_proto(proto),
939 isakmp_pindex(&spi[i], 0));
940
941 if (iph1->sce)
942 SCHED_KILL(iph1->sce);
943 iph1->status = PHASE1ST_EXPIRED;
944 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
945 }
946 }
947 #endif
948
949
950 /*
951 * delete all phase2 sa relatived to the destination address.
952 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
953 * an INITIAL-CONTACT if we have contacted the peer. This matches the
954 * Sun IKE behavior, and makes rekeying work much better when the peer
955 * restarts.
956 */
957 static void
958 info_recv_initialcontact(struct ph1handle *iph1)
959 {
960 plog(PLOG_INFO, PLOGLOC, 0,
961 "INITIALCONTACT processing unimplemented");
962
963 #ifdef notyet
964 struct ph2handle *ph2;
965 struct ph2handle *next_ph2;
966 struct saprop *pp;
967 struct saproto *pr;
968
969 plog(PLOG_INFO, PLOGLOC, 0,
970 "processing INITIALCONTACT for %s->%s\n",
971 rcs_sa2str(iph1->local), rcs_sa2str(iph1->remote));
972
973 for (ph2 = LIST_FIRST(&ph2tree); ph2; ph2 = next_ph2) {
974 next_ph2 = LIST_NEXT(ph2, chain);
975
976 #ifdef ENABLE_NATT
977 /*
978 * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs
979 * from this peer !
980 */
981 if(iph1->natt_flags & NAT_DETECTED){
982 if (CMPSADDR(iph1->local, ph2->src) == 0 &&
983 CMPSADDR(iph1->remote, ph2->dst) == 0)
984 ;
985 else if (CMPSADDR(iph1->remote, ph2->src) == 0 &&
986 CMPSADDR(iph1->local, ph2->dst) == 0)
987 ;
988 else
989 continue;
990 } else
991 #endif
992 /* If there is no NAT-T, we don't have to check addr + port...
993 * XXX what about a configuration with a remote peers which is not
994 * NATed, but which NATs some other peers ?
995 * Here, the INITIAl-CONTACT would also flush all those NATed peers !!
996 */
997 if (rcs_cmpsa_wop(iph1->local, ph2->src) == 0 &&
998 rcs_cmpsa_wop(iph1->remote, ph2->dst) == 0)
999 ;
1000 else if (rcs_cmpsa_wop(iph1->remote, ph2->src) == 0 &&
1001 rcs_cmpsa_wop(iph1->local, ph2->dst) == 0)
1002 ;
1003 else
1004 continue;
1005
1006 pp = ph2->approval;
1007 if (! pp) {
1008 TRACE((PLOGLOC, "no negotiated protocols, skipping\n"));
1009 continue;
1010 }
1011
1012 for (pr = pp->head; pr; pr = pr->next) {
1013 plog(PLOG_INFO, PLOGLOC, NULL,
1014 "purging proto=%d spi=%lu outbound.\n",
1015 pr->proto_id, ntohl(pr->spi_p));
1016 delete_ipsec_sa(&ph2->sadb_request,
1017 ph2->src, ph2->dst,
1018 pr->proto_id, pr->spi_p);
1019 plog(PLOG_INFO, PLOGLOC, NULL,
1020 "purging proto=%d spi=%lu inbound.\n",
1021 pr->proto_id, ntohl(pr->spi));
1022 delete_ipsec_sa(&ph2->sadb_request,
1023 ph2->dst, ph2->src,
1024 pr->proto_id, pr->spi);
1025 }
1026
1027 destroy_ph2(ph2);
1028 }
1029 #endif
1030 }
1031
1032 /*
1033 * handling to receive Deletion payload
1034 */
1035 static int
1036 isakmp_info_recv_d(struct ph1handle *iph1, rc_vchar_t *msg)
1037 {
1038 struct isakmp_pl_d *d;
1039 int tlen, num_spi;
1040 rc_vchar_t *pbuf;
1041 struct isakmp_parse_t *pa, *pap;
1042 int protected = 0;
1043 union {
1044 uint32_t spi32;
1045 uint16_t spi16[2];
1046 } spi;
1047
1048 /* validate the type of next payload */
1049 if (!(pbuf = isakmp_parse(msg)))
1050 return -1;
1051 pa = (struct isakmp_parse_t *)pbuf->v;
1052 for (pap = pa; pap->type; pap++) {
1053 switch (pap->type) {
1054 case ISAKMP_NPTYPE_D:
1055 break;
1056 case ISAKMP_NPTYPE_HASH:
1057 if (pap == pa) {
1058 protected++;
1059 break;
1060 }
1061 plog(PLOG_PROTOERR, PLOGLOC, 0,
1062 "received next payload type %d "
1063 "in wrong place (must be the first payload).\n",
1064 pap->type);
1065 rc_vfree(pbuf);
1066 return -1;
1067 default:
1068 /* don't send information, see isakmp_ident_r1() */
1069 plog(PLOG_PROTOERR, PLOGLOC, 0,
1070 "reject the packet, "
1071 "received unexpecting payload type %d.\n",
1072 pap->type);
1073 rc_vfree(pbuf);
1074 return 0;
1075 }
1076 }
1077
1078 if (!protected) {
1079 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1080 "delete payload is not proteted, "
1081 "ignored.\n");
1082 rc_vfree(pbuf);
1083 return -1;
1084 }
1085
1086 /* process a delete payload */
1087 for (pap = pa; pap->type; pap++) {
1088 if (pap->type != ISAKMP_NPTYPE_D)
1089 continue;
1090
1091 d = (struct isakmp_pl_d *)pap->ptr;
1092
1093 if (get_uint32(&d->doi) != IPSEC_DOI) {
1094 plog(PLOG_PROTOERR, PLOGLOC, 0,
1095 "delete payload with invalid doi:%d.\n",
1096 get_uint32(&d->doi));
1097 #ifdef ENABLE_HYBRID
1098 /*
1099 * At deconnexion time, Cisco VPN client does this
1100 * with a zero DOI. Don't give up in that situation.
1101 */
1102 if (((iph1->mode_cfg->flags &
1103 ISAKMP_CFG_VENDORID_UNITY) == 0) || (d->doi != 0))
1104 continue;
1105 #else
1106 continue;
1107 #endif
1108 }
1109
1110 num_spi = get_uint16(&d->num_spi);
1111 tlen = get_uint16(&d->h.len) - sizeof(struct isakmp_pl_d);
1112
1113 if (tlen != num_spi * d->spi_size) {
1114 plog(PLOG_PROTOERR, PLOGLOC, 0,
1115 "deletion payload with invalid length.\n");
1116 rc_vfree(pbuf);
1117 return -1;
1118 }
1119
1120 switch (d->proto_id) {
1121 case IPSECDOI_PROTO_ISAKMP:
1122 if (d->spi_size != sizeof(isakmp_index_t)) {
1123 plog(PLOG_PROTOERR, PLOGLOC, 0,
1124 "delete payload with strange spi "
1125 "size %d(proto_id:%d)\n",
1126 d->spi_size, d->proto_id);
1127 continue;
1128 }
1129
1130 if (iph1->scr)
1131 SCHED_KILL(iph1->scr);
1132
1133 purge_remote(iph1);
1134 break;
1135
1136 case IPSECDOI_PROTO_IPSEC_AH:
1137 case IPSECDOI_PROTO_IPSEC_ESP:
1138 if (d->spi_size != sizeof(uint32_t)) {
1139 plog(PLOG_PROTOERR, PLOGLOC, 0,
1140 "delete payload with strange spi "
1141 "size %d(proto_id:%d)\n",
1142 d->spi_size, d->proto_id);
1143 continue;
1144 }
1145 EVT_PUSH(iph1->local, iph1->remote,
1146 EVTT_PEER_DELETE, NULL);
1147 purge_ipsec_spi(iph1, iph1->remote, d->proto_id,
1148 (uint32_t *)(d + 1), num_spi);
1149 break;
1150
1151 case IPSECDOI_PROTO_IPCOMP:
1152 /* need to handle both 16bit/32bit SPI */
1153 memset(&spi, 0, sizeof(spi));
1154 if (d->spi_size == sizeof(spi.spi16[1])) {
1155 memcpy(&spi.spi16[1], d + 1,
1156 sizeof(spi.spi16[1]));
1157 } else if (d->spi_size == sizeof(spi.spi32))
1158 memcpy(&spi.spi32, d + 1, sizeof(spi.spi32));
1159 else {
1160 plog(PLOG_PROTOERR, PLOGLOC, 0,
1161 "delete payload with strange spi "
1162 "size %d(proto_id:%d)\n",
1163 d->spi_size, d->proto_id);
1164 continue;
1165 }
1166 purge_ipsec_spi(iph1, iph1->remote, d->proto_id,
1167 &spi.spi32, num_spi);
1168 break;
1169
1170 default:
1171 plog(PLOG_PROTOERR, PLOGLOC, 0,
1172 "deletion message received, "
1173 "invalid proto_id: %d\n",
1174 d->proto_id);
1175 continue;
1176 }
1177
1178 plog(PLOG_DEBUG, PLOGLOC, NULL, "purged SAs.\n");
1179 }
1180
1181 rc_vfree(pbuf);
1182
1183 return 0;
1184 }
1185
1186 void
1187 isakmp_check_notify(struct isakmp_gen *gen, /* points to Notify payload */
1188 struct ph1handle *iph1)
1189 {
1190 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
1191
1192 plog(PLOG_DEBUG, PLOGLOC, 0,
1193 "Notify Message received\n");
1194
1195 switch (get_uint16(¬ify->type)) {
1196 case ISAKMP_NTYPE_CONNECTED:
1197 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
1198 case ISAKMP_NTYPE_REPLAY_STATUS:
1199 case ISAKMP_NTYPE_HEARTBEAT:
1200 #ifdef ENABLE_HYBRID
1201 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
1202 #endif
1203 plog(PLOG_PROTOWARN, PLOGLOC, 0,
1204 "ignore %s notification.\n",
1205 s_isakmp_notify_msg(get_uint16(¬ify->type)));
1206 break;
1207 case ISAKMP_NTYPE_INITIAL_CONTACT:
1208 plog(PLOG_PROTOWARN, PLOGLOC, 0,
1209 "ignore INITIAL-CONTACT notification, "
1210 "because it is only accepted after phase1.\n");
1211 break;
1212 default:
1213 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
1214 plog(PLOG_PROTOERR, PLOGLOC, 0,
1215 "received unknown notification type %s.\n",
1216 s_isakmp_notify_msg(get_uint16(¬ify->type)));
1217 }
1218
1219 return;
1220 }
1221
1222
1223 static int
1224 isakmp_info_recv_r_u (struct ph1handle *iph1, struct isakmp_pl_ru *ru, uint32_t msgid)
1225 {
1226 struct isakmp_pl_ru *ru_ack;
1227 rc_vchar_t *payload = NULL;
1228 int tlen;
1229 int error = 0;
1230
1231 plog(PLOG_DEBUG, PLOGLOC, 0,
1232 "DPD R-U-There received\n");
1233
1234 /* XXX should compare cookies with iph1->index?
1235 Or is this already done by calling function? */
1236 tlen = sizeof(*ru_ack);
1237 payload = rc_vmalloc(tlen);
1238 if (payload == NULL) {
1239 plog(PLOG_INTERR, PLOGLOC, NULL,
1240 "failed to get buffer to send.\n");
1241 return errno;
1242 }
1243
1244 ru_ack = (struct isakmp_pl_ru *)payload->v;
1245 ru_ack->h.np = ISAKMP_NPTYPE_NONE;
1246 put_uint16(&ru_ack->h.len, tlen);
1247 put_uint32(&ru_ack->doi, IPSEC_DOI);
1248 put_uint16(&ru_ack->type, ISAKMP_NTYPE_R_U_THERE_ACK);
1249 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */
1250 ru_ack->spi_size = sizeof(isakmp_index_t);
1251 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(isakmp_cookie_t));
1252 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(isakmp_cookie_t));
1253 ru_ack->data = ru->data;
1254
1255 /* XXX Should we do FLAG_A ? */
1256 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
1257 ISAKMP_FLAG_E);
1258 rc_vfree(payload);
1259
1260 plog(PLOG_DEBUG, PLOGLOC, NULL, "received a valid R-U-THERE, ACK sent\n");
1261
1262 /* Should we mark tunnel as active ? */
1263 return error;
1264 }
1265
1266 static int
1267 isakmp_info_recv_r_u_ack (struct ph1handle *iph1,
1268 struct isakmp_pl_ru *ru, uint32_t msgid)
1269 {
1270
1271 plog(PLOG_DEBUG, PLOGLOC, 0,
1272 "DPD R-U-There-Ack received\n");
1273
1274 /* XXX Maintain window of acceptable sequence numbers ?
1275 * => ru->data <= iph2->dpd_seq &&
1276 * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */
1277 if (get_uint32(&ru->data) != iph1->dpd_seq-1) {
1278 plog(PLOG_PROTOERR, PLOGLOC, 0,
1279 "Wrong DPD sequence number (%d, %d expected).\n",
1280 get_uint32(&ru->data), iph1->dpd_seq-1);
1281 return 0;
1282 }
1283
1284 if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(isakmp_cookie_t)) ||
1285 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(isakmp_cookie_t))) {
1286 plog(PLOG_PROTOERR, PLOGLOC, 0,
1287 "Cookie mismatch in DPD ACK!.\n");
1288 return 0;
1289 }
1290
1291 iph1->dpd_fails = 0;
1292
1293 /* Useless ??? */
1294 iph1->dpd_lastack = time(NULL);
1295 plog(PLOG_DEBUG, PLOGLOC, NULL, "received an R-U-THERE-ACK\n");
1296
1297 return 0;
1298 }
1299
1300
1301
1302
1303 /*
1304 * send Delete payload (for ISAKMP SA) in Informational exchange.
1305 */
1306 static void
1307 isakmp_info_send_r_u(void *arg)
1308 {
1309 struct ph2handle *iph2 = arg;
1310 struct ph1handle *iph1;
1311
1312 /* create R-U-THERE payload */
1313 struct isakmp_pl_ru *ru;
1314 rc_vchar_t *payload = NULL;
1315 int tlen;
1316 int error = 0;
1317
1318 plog(PLOG_DEBUG, PLOGLOC, 0, "DPD monitoring....\n");
1319
1320 iph1 = getph1byaddr(iph2->src, iph2->dst);
1321 if (!iph1) {
1322 plog(PLOG_DEBUG, PLOGLOC, 0, "can't find iph1\n");
1323 return;
1324 }
1325 SCHED_KILL(iph1->dpd_r_u);
1326
1327 if (iph1->dpd_fails >= ikev1_dpd_maxfails(iph1->rmconf)) {
1328 EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL);
1329 purge_remote(iph1);
1330 plog(PLOG_DEBUG, PLOGLOC, 0,
1331 "DPD: remote seems to be dead\n");
1332
1333 /* Do not reschedule here: phase1 is deleted,
1334 * DPD will be reactivated when a new ph1 will be negociated
1335 */
1336 return;
1337 }
1338
1339 /* Check recent activity to avoid useless sends... */
1340 if (iph2->status != PHASE2ST_ESTABLISHED)
1341 return;
1342
1343 /*
1344 * DPD is necessary only when peer is idle AND
1345 * self has packets to send
1346 */
1347 if (iph2->prev_peercount != iph2->cur_peercount ||
1348 iph2->prev_selfcount == iph2->cur_selfcount) {
1349 isakmp_sched_r_u(iph2, 0);
1350 return;
1351 }
1352
1353 /* XXX: why do we have a NULL LIST_FIRST even when a Phase2 exists ??? */
1354 #if 0
1355 if (LIST_FIRST(&iph1->ph2tree) == NULL){
1356 /* XXX: No Ph2 => no need to test ph1 ?
1357 */
1358 /* Reschedule the r_u_there....
1359 XXX: reschedule when a new ph2 ?
1360 */
1361 isakmp_sched_r_u(iph2, 0);
1362 plog(PLOG_DEBUG, PLOGLOC, 0,
1363 "no phase2 handler, rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_interval);
1364 return 0;
1365 }
1366 #endif
1367
1368 tlen = sizeof(*ru);
1369 payload = rc_vmalloc(tlen);
1370 if (payload == NULL) {
1371 plog(PLOG_INTERR, PLOGLOC, NULL,
1372 "failed to get buffer for payload.\n");
1373 return;
1374 }
1375 ru = (struct isakmp_pl_ru *)payload->v;
1376 ru->h.np = ISAKMP_NPTYPE_NONE;
1377 put_uint16(&ru->h.len, tlen);
1378 put_uint32(&ru->doi, IPSEC_DOI);
1379 put_uint16(&ru->type, ISAKMP_NTYPE_R_U_THERE);
1380 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/
1381 ru->spi_size = sizeof(isakmp_index_t);
1382
1383 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(isakmp_cookie_t));
1384 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(isakmp_cookie_t));
1385
1386 if (iph1->dpd_seq == 0){
1387 /* generate a random seq which is not too big */
1388 iph1->dpd_seq = eay_random_uint32() & 0x0fff;
1389 }
1390
1391 put_uint32(&ru->data, iph1->dpd_seq);
1392
1393 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
1394 rc_vfree(payload);
1395
1396 plog(PLOG_DEBUG, PLOGLOC, 0,
1397 "DPD R-U-There sent (%d)\n", error);
1398
1399 /* will be decreased if ACK received... */
1400 iph1->dpd_fails++;
1401
1402 /* XXX should be increased only when ACKed ? */
1403 iph1->dpd_seq++;
1404
1405 /* Reschedule the r_u_there with a short delay,
1406 * will be deleted/rescheduled if ACK received before */
1407 if (iph1->dpd_lastack < time(NULL) - ikev1_dpd_interval(iph1->rmconf)) {
1408 isakmp_sched_r_u(iph2, 1);
1409 } else {
1410 isakmp_sched_r_u(iph2, 0);
1411 }
1412
1413 plog(PLOG_DEBUG, PLOGLOC, 0,
1414 "rescheduling send_r_u (%d).\n", ikev1_dpd_retry(iph1->rmconf));
1415 }
1416
1417 /* Schedule a new R-U-THERE */
1418 int
1419 isakmp_sched_r_u(struct ph2handle *iph2, int retry)
1420 {
1421 struct ph1handle *iph1;
1422
1423 if(iph2 == NULL)
1424 return 1;
1425 iph1 = getph1byaddr(iph2->src, iph2->dst);
1426 if (!iph1 || !iph1->rmconf)
1427 return 1;
1428
1429 if (iph2->status != PHASE2ST_ESTABLISHED) {
1430 return 0;
1431 }
1432
1433 if(iph1->dpd_support == 0 ||
1434 ikev1_dpd_interval(iph1->rmconf) == 0)
1435 return 0;
1436
1437 pk_sendget(iph2, 0);
1438 pk_sendget(iph2, 1);
1439
1440 if(retry)
1441 iph1->dpd_r_u = sched_new(ikev1_dpd_retry(iph1->rmconf),
1442 isakmp_info_send_r_u, iph2);
1443 else
1444 sched_new(ikev1_dpd_interval(iph1->rmconf),
1445 isakmp_info_send_r_u, iph2);
1446
1447 return 0;
1448 }