]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/isakmp_inf.c
ipsec-93.13.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_inf.c
CommitLineData
d1e348cf
A
1/* $NetBSD: isakmp_inf.c,v 1.14.4.8 2007/08/01 11:52:20 vanhu Exp $ */
2
3/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
52b7d2ce
A
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#ifdef __APPLE__
41#include <System/net/pfkeyv2.h>
42#else
43#include <net/pfkeyv2.h>
44#endif
45#include <netinet/in.h>
46#include <sys/queue.h>
47#ifndef HAVE_NETINET6_IPSEC
48#include <netinet/ipsec.h>
49#else
50#include <netinet6/ipsec.h>
51#endif
52
53#include <stdlib.h>
54#include <stdio.h>
55#include <string.h>
56#include <errno.h>
57#if TIME_WITH_SYS_TIME
58# include <sys/time.h>
59# include <time.h>
60#else
61# if HAVE_SYS_TIME_H
62# include <sys/time.h>
63# else
64# include <time.h>
65# endif
66#endif
d1e348cf
A
67#ifdef ENABLE_HYBRID
68#include <resolv.h>
69#endif
52b7d2ce
A
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 "sockmisc.h"
d1e348cf
A
84#include "handler.h"
85#include "policy.h"
86#include "proposal.h"
52b7d2ce
A
87#include "isakmp_var.h"
88#include "evt.h"
89#include "isakmp.h"
90#ifdef ENABLE_HYBRID
91#include "isakmp_xauth.h"
d1e348cf 92#include "isakmp_unity.h"
52b7d2ce
A
93#include "isakmp_cfg.h"
94#endif
95#include "isakmp_inf.h"
96#include "oakley.h"
52b7d2ce
A
97#include "ipsec_doi.h"
98#include "crypto_openssl.h"
99#include "pfkey.h"
100#include "policy.h"
101#include "algorithm.h"
102#include "proposal.h"
103#include "admin.h"
104#include "strnames.h"
105#ifdef ENABLE_NATT
106#include "nattraversal.h"
107#endif
108#include "vpn_control_var.h"
109#include "vpn_control.h"
d1e348cf
A
110#include "ike_session.h"
111#include "ipsecSessionTracer.h"
112#include "ipsecMessageTracer.h"
52b7d2ce
A
113
114/* information exchange */
d1e348cf
A
115static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int);
116static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int);
52b7d2ce
A
117
118#ifdef ENABLE_DPD
119static int isakmp_info_recv_r_u __P((struct ph1handle *,
120 struct isakmp_pl_ru *, u_int32_t));
121static int isakmp_info_recv_r_u_ack __P((struct ph1handle *,
122 struct isakmp_pl_ru *, u_int32_t));
52b7d2ce
A
123#endif
124
125#ifdef ENABLE_VPNCONTROL_PORT
126static int isakmp_info_recv_lb __P((struct ph1handle *, struct isakmp_pl_lb *lb, int));
127#endif
128
129static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
52b7d2ce
A
130static void info_recv_initialcontact __P((struct ph1handle *));
131
d1e348cf
A
132static int
133isakmp_ph1_responder_lifetime (struct ph1handle *iph1,
134 struct isakmp_pl_resp_lifetime *notify)
135{
136 char *spi;
137
138 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
139 plog(LLV_ERROR, LOCATION, iph1->remote,
140 "invalid spi_size in notification payload.\n");
141 return -1;
142 }
143 spi = val2str((char *)(notify + 1), notify->spi_size);
144
145 plog(LLV_DEBUG, LOCATION, iph1->remote,
146 "notification message ISAKMP-SA RESPONDER-LIFETIME, "
147 "doi=%d proto_id=%d spi=%s(size=%d).\n",
148 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
149
150 /* TODO */
151 #if 0
152 struct isakmp_pl_attr *attrpl;
153 int len = ntohs(notify->h.len) - (sizeof(*notify) + notify->spi_size);
154
155 attrpl = (struct isakmp_pl_attr *)((char *)(notify + 1) + notify->spi_size);
156 while (len > 0) {
157 }
158 #endif
159
160 racoon_free(spi);
161 return 0;
162}
163
164static int
165isakmp_ph2_responder_lifetime (struct ph2handle *iph2,
166 struct isakmp_pl_resp_lifetime *notify)
167{
168 char *spi;
169
170 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
171 plog(LLV_ERROR, LOCATION, iph2->dst,
172 "invalid spi_size in notification payload.\n");
173 return -1;
174 }
175 spi = val2str((char *)(notify + 1), notify->spi_size);
176
177 plog(LLV_DEBUG, LOCATION, iph2->dst,
178 "notification message IPSEC-SA RESPONDER-LIFETIME, "
179 "doi=%d proto_id=%d spi=%s(size=%d).\n",
180 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
181
182 /* TODO */
183
184 racoon_free(spi);
185 return 0;
186}
187
52b7d2ce
A
188/* \f%%%
189 * Information Exchange
190 */
191/*
192 * receive Information
193 */
194int
195isakmp_info_recv(iph1, msg0)
196 struct ph1handle *iph1;
197 vchar_t *msg0;
198{
199 vchar_t *msg = NULL;
d1e348cf
A
200 vchar_t *pbuf = NULL;
201 u_int32_t msgid = 0;
52b7d2ce
A
202 int error = -1;
203 struct isakmp *isakmp;
204 struct isakmp_gen *gen;
d1e348cf 205 struct isakmp_parse_t *pa, *pap;
52b7d2ce
A
206 void *p;
207 vchar_t *hash, *payload;
208 struct isakmp_gen *nd;
209 u_int8_t np;
210 int encrypted;
d1e348cf 211 int flag;
52b7d2ce
A
212
213 plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n");
214
215 encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
d1e348cf 216 msgid = ((struct isakmp *)msg0->v)->msgid;
52b7d2ce
A
217
218 /* Use new IV to decrypt Informational message. */
219 if (encrypted) {
52b7d2ce
A
220 struct isakmp_ivm *ivm;
221
d1e348cf
A
222 if (iph1->ivm == NULL) {
223 plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n");
224 IPSECSESSIONTRACEREVENT(iph1->parent_session,
225 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
226 CONSTSTR("Information message"),
227 CONSTSTR("Failed to process Information Message (no IV)"));
228 return -1;
229 }
230
52b7d2ce
A
231 /* compute IV */
232 ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
d1e348cf
A
233 if (ivm == NULL) {
234 plog(LLV_ERROR, LOCATION, NULL,
235 "failed to compute IV");
236 IPSECSESSIONTRACEREVENT(iph1->parent_session,
237 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
238 CONSTSTR("Information message"),
239 CONSTSTR("Failed to process Information Message (can't compute IV)"));
52b7d2ce 240 return -1;
d1e348cf 241 }
52b7d2ce
A
242
243 msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
244 oakley_delivm(ivm);
d1e348cf
A
245 if (msg == NULL) {
246 plog(LLV_ERROR, LOCATION, NULL,
247 "failed to decrypt packet");
248 IPSECSESSIONTRACEREVENT(iph1->parent_session,
249 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
250 CONSTSTR("Information message"),
251 CONSTSTR("Failed to decrypt Information message"));
52b7d2ce 252 return -1;
d1e348cf 253 }
52b7d2ce
A
254
255 } else
256 msg = vdup(msg0);
257
258 /* Safety check */
259 if (msg->l < sizeof(*isakmp) + sizeof(*gen)) {
260 plog(LLV_ERROR, LOCATION, NULL,
261 "ignore information because the "
262 "message is way too short\n");
263 goto end;
264 }
265
266 isakmp = (struct isakmp *)msg->v;
267 gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
268 np = gen->np;
269
270 if (encrypted) {
271 if (isakmp->np != ISAKMP_NPTYPE_HASH) {
272 plog(LLV_ERROR, LOCATION, NULL,
273 "ignore information because the "
274 "message has no hash payload.\n");
275 goto end;
276 }
277
d1e348cf
A
278 if (iph1->status != PHASE1ST_ESTABLISHED &&
279 (!iph1->approval || !iph1->skeyid_a)) {
52b7d2ce
A
280 plog(LLV_ERROR, LOCATION, NULL,
281 "ignore information because ISAKMP-SA "
282 "has not been established yet.\n");
283 goto end;
284 }
285
286 /* Safety check */
287 if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) {
288 plog(LLV_ERROR, LOCATION, NULL,
289 "ignore information because the "
290 "message is too short\n");
291 goto end;
292 }
293
294 p = (caddr_t) gen + sizeof(struct isakmp_gen);
295 nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len));
296
297 /* nd length check */
298 if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) +
299 ntohs(gen->len))) {
300 plog(LLV_ERROR, LOCATION, NULL,
301 "too long payload length (broken message?)\n");
302 goto end;
303 }
304
305 if (ntohs(nd->len) < sizeof(*nd)) {
306 plog(LLV_ERROR, LOCATION, NULL,
307 "too short payload length (broken message?)\n");
308 goto end;
309 }
310
311 payload = vmalloc(ntohs(nd->len));
312 if (payload == NULL) {
313 plog(LLV_ERROR, LOCATION, NULL,
314 "cannot allocate memory\n");
315 goto end;
316 }
317
318 memcpy(payload->v, (caddr_t) nd, ntohs(nd->len));
319
320 /* compute HASH */
321 hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
322 if (hash == NULL) {
323 plog(LLV_ERROR, LOCATION, NULL,
324 "cannot compute hash\n");
325
326 vfree(payload);
327 goto end;
328 }
329
330 if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) {
331 plog(LLV_ERROR, LOCATION, NULL,
332 "ignore information due to hash length mismatch\n");
333
334 vfree(hash);
335 vfree(payload);
336 goto end;
337 }
338
339 if (memcmp(p, hash->v, hash->l) != 0) {
340 plog(LLV_ERROR, LOCATION, NULL,
341 "ignore information due to hash mismatch\n");
342
343 vfree(hash);
344 vfree(payload);
345 goto end;
346 }
347
348 plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n");
349
350 vfree(hash);
351 vfree(payload);
352 } else {
d1e348cf 353 /* make sure the packet was encrypted after the beginning of phase 1. */
52b7d2ce
A
354 switch (iph1->etype) {
355 case ISAKMP_ETYPE_AGG:
356 case ISAKMP_ETYPE_BASE:
357 case ISAKMP_ETYPE_IDENT:
358 if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT)
359 || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) {
360 break;
361 }
362 /*FALLTHRU*/
363 default:
364 plog(LLV_ERROR, LOCATION, iph1->remote,
365 "%s message must be encrypted\n",
366 s_isakmp_nptype(np));
d1e348cf 367 error = 0;
52b7d2ce
A
368 goto end;
369 }
370 }
371
d1e348cf
A
372 if (!(pbuf = isakmp_parse(msg))) {
373 plog(LLV_ERROR, LOCATION, NULL,
374 "failed to parse msg");
375 error = -1;
376 goto end;
377 }
378
379 error = 0;
380 for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) {
381 switch (pa->type) {
382 case ISAKMP_NPTYPE_HASH:
383 /* Handled above */
384 break;
385 case ISAKMP_NPTYPE_N:
386 error = isakmp_info_recv_n(iph1,
387 (struct isakmp_pl_n *)pa->ptr,
388 msgid, encrypted);
389 break;
390 case ISAKMP_NPTYPE_D:
391 error = isakmp_info_recv_d(iph1,
392 (struct isakmp_pl_d *)pa->ptr,
393 msgid, encrypted);
394 break;
395 case ISAKMP_NPTYPE_NONCE:
396 /* XXX to be 6.4.2 ike-01.txt */
397 /* XXX IV is to be synchronized. */
398 plog(LLV_ERROR, LOCATION, iph1->remote,
399 "ignore Acknowledged Informational\n");
400 break;
401 default:
402 /* don't send information, see isakmp_ident_r1() */
403 error = 0;
404 plog(LLV_ERROR, LOCATION, iph1->remote,
405 "reject the packet, "
406 "received unexpected payload type %s.\n",
407 s_isakmp_nptype(gen->np));
408 }
409 if(error < 0) {
410 break;
411 } else {
412 flag |= error;
413 }
414 }
415 IPSECSESSIONTRACEREVENT(iph1->parent_session,
416 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
417 CONSTSTR("Information message"),
418 CONSTSTR(NULL));
419
420end:
421 if (error) {
422 IPSECSESSIONTRACEREVENT(iph1->parent_session,
423 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
424 CONSTSTR("Information message"),
425 CONSTSTR("Failed to process Information Message"));
426 }
427 if (msg != NULL)
428 vfree(msg);
429 if (pbuf != NULL)
430 vfree(pbuf);
431 return error;
432}
433
434/*
435 * handling of Notification payload
436 */
437static int
438isakmp_info_recv_n(iph1, notify, msgid, encrypted)
439 struct ph1handle *iph1;
440 struct isakmp_pl_n *notify;
441 u_int32_t msgid;
442 int encrypted;
443{
444 u_int type;
445 vchar_t *pbuf;
446 vchar_t *ndata;
447 char *nraw;
448 size_t l;
449 char *spi;
450
451 type = ntohs(notify->type);
452
453 switch (type) {
454 case ISAKMP_NTYPE_CONNECTED:
455 case ISAKMP_NTYPE_REPLAY_STATUS:
456#ifdef ENABLE_HYBRID
457 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
458#endif
459 /* do something */
52b7d2ce 460 break;
d1e348cf
A
461 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
462 if (encrypted) {
463 return(isakmp_ph1_responder_lifetime(iph1,
464 (struct isakmp_pl_resp_lifetime *)notify));
465 }
466 break;
467 case ISAKMP_NTYPE_INITIAL_CONTACT:
52b7d2ce 468 if (encrypted)
d1e348cf
A
469 info_recv_initialcontact(iph1);
470 return 0;
52b7d2ce 471 break;
d1e348cf
A
472#ifdef ENABLE_DPD
473 case ISAKMP_NTYPE_R_U_THERE:
474 if (encrypted)
475 return isakmp_info_recv_r_u(iph1,
476 (struct isakmp_pl_ru *)notify, msgid);
477 break;
478 case ISAKMP_NTYPE_R_U_THERE_ACK:
479 if (encrypted)
480 return isakmp_info_recv_r_u_ack(iph1,
481 (struct isakmp_pl_ru *)notify, msgid);
52b7d2ce 482 break;
d1e348cf
A
483#endif
484#ifdef ENABLE_VPNCONTROL_PORT
485 case ISAKMP_NTYPE_LOAD_BALANCE:
486 isakmp_info_recv_lb(iph1, (struct isakmp_pl_lb *)notify, encrypted);
487 break;
488#endif
489
52b7d2ce 490 default:
d1e348cf
A
491 {
492 /* XXX there is a potential of dos attack. */
493 if(type >= ISAKMP_NTYPE_MINERROR &&
494 type <= ISAKMP_NTYPE_MAXERROR) {
495 if (msgid == 0) {
496 /* don't think this realy deletes ph1 ? */
497 plog(LLV_ERROR, LOCATION, iph1->remote,
498 "delete phase1 handle.\n");
499 return -1;
500 } else {
501 if (getph2bymsgid(iph1, msgid) == NULL) {
502 plog(LLV_ERROR, LOCATION, iph1->remote,
503 "fatal %s notify messsage, "
504 "phase1 should be deleted.\n",
505 s_isakmp_notify_msg(type));
506 } else {
507 plog(LLV_ERROR, LOCATION, iph1->remote,
508 "fatal %s notify messsage, "
509 "phase2 should be deleted.\n",
510 s_isakmp_notify_msg(type));
511 }
512 }
513 } else {
514 plog(LLV_ERROR, LOCATION, iph1->remote,
515 "unhandled notify message %s, "
516 "no phase2 handle found.\n",
517 s_isakmp_notify_msg(type));
518 }
519 }
520 break;
521 }
522
523 /* get spi if specified and allocate */
524 if(notify->spi_size > 0) {
525 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
526 plog(LLV_ERROR, LOCATION, iph1->remote,
527 "invalid spi_size in notification payload.\n");
528 return -1;
529 }
530 spi = val2str((char *)(notify + 1), notify->spi_size);
531
532 plog(LLV_DEBUG, LOCATION, iph1->remote,
533 "notification message %d:%s, "
534 "doi=%d proto_id=%d spi=%s(size=%d).\n",
535 type, s_isakmp_notify_msg(type),
536 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
537
538 racoon_free(spi);
539 }
540
541 /* Send the message data to the logs */
542 if(type >= ISAKMP_NTYPE_MINERROR &&
543 type <= ISAKMP_NTYPE_MAXERROR) {
544 l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
545 if (l > 0) {
546 nraw = (char*)notify;
547 nraw += sizeof(*notify) + notify->spi_size;
548 if ((ndata = vmalloc(l)) != NULL) {
549 memcpy(ndata->v, nraw, ndata->l);
550 plog(LLV_ERROR, LOCATION, iph1->remote,
551 "Message: '%s'.\n",
552 binsanitize(ndata->v, ndata->l));
553 vfree(ndata);
554 } else {
555 plog(LLV_ERROR, LOCATION, iph1->remote,
556 "Cannot allocate memory\n");
557 }
558 }
559 }
560 return 0;
561}
562
563/*
564 * handling of Deletion payload
565 */
566static int
567isakmp_info_recv_d(iph1, delete, msgid, encrypted)
568 struct ph1handle *iph1;
569 struct isakmp_pl_d *delete;
570 u_int32_t msgid;
571 int encrypted;
572{
573 int tlen, num_spi;
574 vchar_t *pbuf;
575 int protected = 0;
576 struct ph1handle *del_ph1;
577 struct ph2handle *iph2;
578 union {
579 u_int32_t spi32;
580 u_int16_t spi16[2];
581 } spi;
582
583 if (ntohl(delete->doi) != IPSEC_DOI) {
52b7d2ce 584 plog(LLV_ERROR, LOCATION, iph1->remote,
d1e348cf
A
585 "delete payload with invalid doi:%d.\n",
586 ntohl(delete->doi));
587#ifdef ENABLE_HYBRID
588 /*
589 * At deconnexion time, Cisco VPN client does this
590 * with a zero DOI. Don't give up in that situation.
591 */
592 if (((iph1->mode_cfg->flags &
593 ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0))
594 return 0;
595#else
596 return 0;
597#endif
598 }
599
600 num_spi = ntohs(delete->num_spi);
601 tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d);
602
603 if (tlen != num_spi * delete->spi_size) {
604 plog(LLV_ERROR, LOCATION, iph1->remote,
605 "deletion payload with invalid length.\n");
606 return 0;
607 }
608
609 plog(LLV_DEBUG, LOCATION, iph1->remote,
610 "delete payload for protocol %s\n",
611 s_ipsecdoi_proto(delete->proto_id));
612
613 if(!iph1->rmconf->weak_phase1_check && !encrypted) {
614 plog(LLV_WARNING, LOCATION, iph1->remote,
615 "Ignoring unencrypted delete payload "
616 "(check the weak_phase1_check option)\n");
617 return 0;
618 }
619
620 switch (delete->proto_id) {
621 case IPSECDOI_PROTO_ISAKMP:
622 if (delete->spi_size != sizeof(isakmp_index)) {
623 plog(LLV_ERROR, LOCATION, iph1->remote,
624 "delete payload with strange spi "
625 "size %d(proto_id:%d)\n",
626 delete->spi_size, delete->proto_id);
627 return 0;
628 }
629
630 del_ph1=getph1byindex((isakmp_index *)(delete + 1));
631 if(del_ph1 != NULL){
632
633 // hack: start a rekey now, if one was pending (only for client).
634 if (del_ph1->sce_rekey &&
635 del_ph1->parent_session &&
636 del_ph1->parent_session->is_client &&
637 del_ph1->parent_session->established) {
fce29cd9 638 isakmp_ph1rekeyexpire(del_ph1, FALSE);
d1e348cf
A
639 }
640
641 EVT_PUSH(del_ph1->local, del_ph1->remote,
642 EVTT_PEERPH1_NOPROP, NULL);
643 if (del_ph1->scr)
644 SCHED_KILL(del_ph1->scr);
645
646 /*
647 * Do not delete IPsec SAs when receiving an IKE delete notification.
648 * Just delete the IKE SA.
649 */
650#ifdef ENABLE_VPNCONTROL_PORT
651
652 if (del_ph1->started_by_api)
653 if (islast_ph1(del_ph1)) {
654 u_int32_t address;
655
656 /* notify the API that we have received the delete */
657 if (iph1->remote->sa_family == AF_INET)
658 address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr;
659 else
660 address = 0;
fce29cd9
A
661 if (iph1->cert && IS_CERT_STATUS_ERROR(iph1->cert->status)) {
662 vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE_CERT_ERROR + iph1->cert->status, FROM_REMOTE, address, 0, NULL);
663 } else {
664 vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE, FROM_REMOTE, address, 0, NULL);
665 }
d1e348cf
A
666 }
667#endif
668 isakmp_ph1expire(del_ph1);
669 }
670 break;
671
672 case IPSECDOI_PROTO_IPSEC_AH:
673 case IPSECDOI_PROTO_IPSEC_ESP:
674 if (delete->spi_size != sizeof(u_int32_t)) {
675 plog(LLV_ERROR, LOCATION, iph1->remote,
676 "delete payload with strange spi "
677 "size %d(proto_id:%d)\n",
678 delete->spi_size, delete->proto_id);
679 return 0;
680 }
681 EVT_PUSH(iph1->local, iph1->remote,
682 EVTT_PEER_DELETE, NULL);
683 purge_ipsec_spi(iph1->remote, delete->proto_id,
684 (u_int32_t *)(delete + 1), num_spi);
52b7d2ce 685 break;
d1e348cf
A
686
687 case IPSECDOI_PROTO_IPCOMP:
688 /* need to handle both 16bit/32bit SPI */
689 memset(&spi, 0, sizeof(spi));
690 if (delete->spi_size == sizeof(spi.spi16[1])) {
691 memcpy(&spi.spi16[1], delete + 1,
692 sizeof(spi.spi16[1]));
693 } else if (delete->spi_size == sizeof(spi.spi32))
694 memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32));
695 else {
696 plog(LLV_ERROR, LOCATION, iph1->remote,
697 "delete payload with strange spi "
698 "size %d(proto_id:%d)\n",
699 delete->spi_size, delete->proto_id);
700 return 0;
701 }
702 purge_ipsec_spi(iph1->remote, delete->proto_id,
703 &spi.spi32, num_spi);
704 break;
705
706 default:
707 plog(LLV_ERROR, LOCATION, iph1->remote,
708 "deletion message received, "
709 "invalid proto_id: %d\n",
710 delete->proto_id);
711 return 0;
52b7d2ce
A
712 }
713
d1e348cf 714 plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n");
52b7d2ce
A
715
716 return 0;
717}
718
719/*
720 * send Delete payload (for ISAKMP SA) in Informational exchange.
721 */
722int
723isakmp_info_send_d1(iph1)
724 struct ph1handle *iph1;
725{
726 struct isakmp_pl_d *d;
727 vchar_t *payload = NULL;
728 int tlen;
729 int error = 0;
730
731 if (iph1->status != PHASE2ST_ESTABLISHED)
732 return 0;
733
734 /* create delete payload */
735
736 /* send SPIs of inbound SAs. */
737 /* XXX should send outbound SAs's ? */
738 tlen = sizeof(*d) + sizeof(isakmp_index);
739 payload = vmalloc(tlen);
740 if (payload == NULL) {
741 plog(LLV_ERROR, LOCATION, NULL,
742 "failed to get buffer for payload.\n");
743 return errno;
744 }
745
746 d = (struct isakmp_pl_d *)payload->v;
747 d->h.np = ISAKMP_NPTYPE_NONE;
748 d->h.len = htons(tlen);
749 d->doi = htonl(IPSEC_DOI);
750 d->proto_id = IPSECDOI_PROTO_ISAKMP;
751 d->spi_size = sizeof(isakmp_index);
752 d->num_spi = htons(1);
753 memcpy(d + 1, &iph1->index, sizeof(isakmp_index));
754
755 error = isakmp_info_send_common(iph1, payload,
756 ISAKMP_NPTYPE_D, 0);
757 vfree(payload);
d1e348cf
A
758 if (error) {
759 IPSECSESSIONTRACEREVENT(iph1->parent_session,
760 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
761 CONSTSTR("Delete ISAKMP-SA"),
762 CONSTSTR("Failed to transmit Delete-ISAKMP-SA message"));
763 } else {
764 IPSECSESSIONTRACEREVENT(iph1->parent_session,
765 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
766 CONSTSTR("Delete ISAKMP-SA"),
767 CONSTSTR(NULL));
768 }
52b7d2ce
A
769
770 return error;
771}
772
773/*
774 * send Delete payload (for IPsec SA) in Informational exchange, based on
775 * pfkey msg. It sends always single SPI.
776 */
777int
778isakmp_info_send_d2(iph2)
779 struct ph2handle *iph2;
780{
781 struct ph1handle *iph1;
782 struct saproto *pr;
783 struct isakmp_pl_d *d;
784 vchar_t *payload = NULL;
785 int tlen;
786 int error = 0;
787 u_int8_t *spi;
788
789 if (iph2->status != PHASE2ST_ESTABLISHED)
790 return 0;
791
792 /*
793 * don't send delete information if there is no phase 1 handler.
794 * It's nonsensical to negotiate phase 1 to send the information.
795 */
d1e348cf
A
796 iph1 = ike_session_get_established_ph1(iph2->parent_session);
797 if (!iph1) {
798 iph1 = getph1byaddr(iph2->src, iph2->dst);
799 }
800 if (iph1 == NULL){
801 IPSECSESSIONTRACEREVENT(iph2->parent_session,
802 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
803 CONSTSTR("Information message"),
804 CONSTSTR("Failed to transmit Information message"));
805 IPSECSESSIONTRACEREVENT(iph2->parent_session,
806 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
807 CONSTSTR("Delete IPSEC-SA"),
808 CONSTSTR("Failed to transmit Delete-IPSEC-SA message"));
809 plog(LLV_DEBUG2, LOCATION, NULL,
810 "No ph1 handler found, could not send DELETE_SA\n");
52b7d2ce 811 return 0;
d1e348cf 812 }
52b7d2ce
A
813
814 /* create delete payload */
815 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
816
817 /* send SPIs of inbound SAs. */
818 /*
819 * XXX should I send outbound SAs's ?
820 * I send inbound SAs's SPI only at the moment because I can't
821 * decode any more if peer send encoded packet without aware of
822 * deletion of SA. Outbound SAs don't come under the situation.
823 */
824 tlen = sizeof(*d) + pr->spisize;
825 payload = vmalloc(tlen);
826 if (payload == NULL) {
d1e348cf
A
827 IPSECSESSIONTRACEREVENT(iph2->parent_session,
828 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
829 CONSTSTR("Information message"),
830 CONSTSTR("Failed to transmit Information message"));
831 IPSECSESSIONTRACEREVENT(iph2->parent_session,
832 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
833 CONSTSTR("Delete IPSEC-SA"),
834 CONSTSTR("Failed to transmit Delete-IPSEC-SA message"));
52b7d2ce
A
835 plog(LLV_ERROR, LOCATION, NULL,
836 "failed to get buffer for payload.\n");
837 return errno;
838 }
839
840 d = (struct isakmp_pl_d *)payload->v;
841 d->h.np = ISAKMP_NPTYPE_NONE;
842 d->h.len = htons(tlen);
843 d->doi = htonl(IPSEC_DOI);
844 d->proto_id = pr->proto_id;
845 d->spi_size = pr->spisize;
846 d->num_spi = htons(1);
847 /*
848 * XXX SPI bits are left-filled, for use with IPComp.
849 * we should be switching to variable-length spi field...
850 */
851 spi = (u_int8_t *)&pr->spi;
852 spi += sizeof(pr->spi);
853 spi -= pr->spisize;
854 memcpy(d + 1, spi, pr->spisize);
855
856 error = isakmp_info_send_common(iph1, payload,
857 ISAKMP_NPTYPE_D, 0);
858 vfree(payload);
d1e348cf
A
859 if (error) {
860 IPSECSESSIONTRACEREVENT(iph2->parent_session,
861 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
862 CONSTSTR("Delete IPSEC-SA"),
863 CONSTSTR("Failed to transmit Delete-IPSEC-SA"));
864 } else {
865 IPSECSESSIONTRACEREVENT(iph2->parent_session,
866 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
867 CONSTSTR("Delete IPSEC-SA"),
868 CONSTSTR(NULL));
869 }
52b7d2ce
A
870 }
871
872 return error;
873}
874
875/*
876 * send Notification payload (for without ISAKMP SA) in Informational exchange
877 */
878int
879isakmp_info_send_nx(isakmp, remote, local, type, data)
880 struct isakmp *isakmp;
881 struct sockaddr *remote, *local;
882 int type;
883 vchar_t *data;
884{
885 struct ph1handle *iph1 = NULL;
886 struct remoteconf *rmconf;
887 vchar_t *payload = NULL;
888 int tlen;
889 int error = -1;
890 struct isakmp_pl_n *n;
891 int spisiz = 0; /* see below */
d1e348cf 892 ike_session_t *sess = ike_session_get_session(local, remote, FALSE);
52b7d2ce
A
893
894 /* search appropreate configuration */
895 rmconf = getrmconf(remote);
896 if (rmconf == NULL) {
d1e348cf
A
897 IPSECSESSIONTRACEREVENT(sess,
898 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
899 CONSTSTR("Information message"),
900 CONSTSTR("Failed to transmit Information message (no remote configuration)"));
52b7d2ce
A
901 plog(LLV_ERROR, LOCATION, remote,
902 "no configuration found for peer address.\n");
903 goto end;
904 }
905
906 /* add new entry to isakmp status table. */
907 iph1 = newph1();
d1e348cf
A
908 if (iph1 == NULL) {
909 IPSECSESSIONTRACEREVENT(sess,
910 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
911 CONSTSTR("Information message"),
912 CONSTSTR("Failed to transmit Information message (no new phase1)"));
913 plog(LLV_ERROR, LOCATION, NULL,
914 "failed to allocate ph1");
52b7d2ce 915 return -1;
d1e348cf 916 }
52b7d2ce
A
917
918 memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
919 isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
920 iph1->status = PHASE1ST_START;
921 iph1->rmconf = rmconf;
d1e348cf
A
922#ifdef __APPLE__
923 if (link_rmconf_to_ph1(rmconf) < 0) {
924 IPSECSESSIONTRACEREVENT(sess,
925 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
926 CONSTSTR("Information message"),
927 CONSTSTR("Failed to transmit Information message (can't link remote configuration to phase1)"));
928 plog(LLV_ERROR, LOCATION, remote,
929 "couldn't link "
930 "configuration.\n");
931 iph1->rmconf = NULL;
932 error = -1;
933 goto end;
934 }
935#endif
52b7d2ce
A
936 iph1->side = INITIATOR;
937 iph1->version = isakmp->v;
938 iph1->flags = 0;
939 iph1->msgid = 0; /* XXX */
940#ifdef ENABLE_HYBRID
d1e348cf
A
941 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
942 error = -1;
943 goto end;
944 }
52b7d2ce
A
945#endif
946#ifdef ENABLE_FRAG
947 iph1->frag = 0;
948 iph1->frag_chain = NULL;
949#endif
950
951 /* copy remote address */
d1e348cf
A
952 if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
953 IPSECSESSIONTRACEREVENT(sess,
954 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
955 CONSTSTR("Information message"),
956 CONSTSTR("Failed to transmit Information Message (can't copy phase1 addresses)"));
957 plog(LLV_ERROR, LOCATION, NULL,
958 "failed to copy ph1 addresses");
959 error = -1;
47612122 960 iph1 = NULL; /* deleted in copy_ph1addresses */
d1e348cf
A
961 goto end;
962 }
52b7d2ce
A
963
964 tlen = sizeof(*n) + spisiz;
965 if (data)
966 tlen += data->l;
967 payload = vmalloc(tlen);
968 if (payload == NULL) {
d1e348cf
A
969 IPSECSESSIONTRACEREVENT(sess,
970 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
971 CONSTSTR("Information message"),
972 CONSTSTR("Failed to transmit Information Message (can't allocate payload)"));
52b7d2ce
A
973 plog(LLV_ERROR, LOCATION, NULL,
974 "failed to get buffer to send.\n");
d1e348cf 975 error = -1;
52b7d2ce
A
976 goto end;
977 }
978
979 n = (struct isakmp_pl_n *)payload->v;
980 n->h.np = ISAKMP_NPTYPE_NONE;
981 n->h.len = htons(tlen);
982 n->doi = htonl(IPSEC_DOI);
983 n->proto_id = IPSECDOI_KEY_IKE;
984 n->spi_size = spisiz;
985 n->type = htons(type);
986 if (spisiz)
d1e348cf 987 memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */
52b7d2ce
A
988 if (data)
989 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
990
991#ifdef ENABLE_VPNCONTROL_PORT
992 {
993 u_int32_t address;
994 if (type == ISAKMP_INTERNAL_ERROR ||
995 type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) {
996 if (remote->sa_family == AF_INET)
997 address = ((struct sockaddr_in *)remote)->sin_addr.s_addr;
998 else
999 address = 0;
1000 (void)vpncontrol_notify_ike_failed(type, FROM_LOCAL, address,
1001 (data ? data->l : 0), (data ? data->v : NULL));
1002 }
1003 }
1004#endif
1005
1006 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
1007 vfree(payload);
d1e348cf
A
1008 if (error) {
1009 IPSECSESSIONTRACEREVENT(sess,
1010 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
1011 CONSTSTR("Without ISAKMP-SA"),
1012 CONSTSTR("Failed to transmit Without-ISAKMP-SA message"));
1013 } else {
1014 IPSECSESSIONTRACEREVENT(sess,
1015 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
1016 CONSTSTR("Without ISAKMP-SA"),
1017 CONSTSTR(NULL));
1018 }
1019
52b7d2ce
A
1020 end:
1021 if (iph1 != NULL)
1022 delph1(iph1);
1023
1024 return error;
1025}
1026
1027/*
1028 * send Notification payload (for ISAKMP SA) in Informational exchange
1029 */
1030int
1031isakmp_info_send_n1(iph1, type, data)
1032 struct ph1handle *iph1;
1033 int type;
1034 vchar_t *data;
1035{
1036 vchar_t *payload = NULL;
1037 int tlen;
1038 int error = 0;
1039 struct isakmp_pl_n *n;
1040 int spisiz;
1041
1042 /*
1043 * note on SPI size: which description is correct? I have chosen
1044 * this to be 0.
1045 *
1046 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by
1047 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0.
1048 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified
1049 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
1050 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
1051 */
1052 if (type == ISAKMP_NTYPE_INITIAL_CONTACT ||
1053 type == ISAKMP_NTYPE_LOAD_BALANCE)
1054 spisiz = sizeof(isakmp_index);
1055 else
1056 spisiz = 0;
1057
1058 tlen = sizeof(*n) + spisiz;
1059 if (data)
1060 tlen += data->l;
1061 payload = vmalloc(tlen);
1062 if (payload == NULL) {
d1e348cf
A
1063 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1064 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
1065 CONSTSTR("ISAKMP-SA"),
1066 CONSTSTR("Failed to transmit ISAKMP-SA message (can't allocate payload)"));
52b7d2ce
A
1067 plog(LLV_ERROR, LOCATION, NULL,
1068 "failed to get buffer to send.\n");
1069 return errno;
1070 }
1071
1072 n = (struct isakmp_pl_n *)payload->v;
1073 n->h.np = ISAKMP_NPTYPE_NONE;
1074 n->h.len = htons(tlen);
1075 n->doi = htonl(iph1->rmconf->doitype);
1076 n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */
1077 n->spi_size = spisiz;
1078 n->type = htons(type);
1079 if (spisiz)
1080 memcpy(n + 1, &iph1->index, sizeof(isakmp_index));
1081 if (data)
1082 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
1083
1084#ifdef ENABLE_VPNCONTROL_PORT
1085 {
1086 u_int32_t address;
1087
1088 if (type == ISAKMP_INTERNAL_ERROR ||
1089 type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) {
1090 if (iph1->remote->sa_family == AF_INET)
1091 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
1092 else
1093 address = 0;
1094 (void)vpncontrol_notify_ike_failed(type, FROM_LOCAL, address,
1095 (data ? data->l : 0), (data ? data->v : NULL));
1096 }
1097 }
1098#endif
1099
1100 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
1101 vfree(payload);
d1e348cf
A
1102 if (error) {
1103 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1104 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
1105 CONSTSTR("ISAKMP-SA"),
1106 CONSTSTR("Can't transmit ISAKMP-SA message"));
1107 } else {
1108 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1109 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
1110 CONSTSTR("ISAKMP-SA"),
1111 CONSTSTR(NULL));
1112 }
52b7d2ce
A
1113
1114 return error;
1115}
1116
1117/*
1118 * send Notification payload (for IPsec SA) in Informational exchange
1119 */
1120int
1121isakmp_info_send_n2(iph2, type, data)
1122 struct ph2handle *iph2;
1123 int type;
1124 vchar_t *data;
1125{
1126 struct ph1handle *iph1 = iph2->ph1;
1127 vchar_t *payload = NULL;
1128 int tlen;
1129 int error = 0;
1130 struct isakmp_pl_n *n;
1131 struct saproto *pr;
1132
1133 if (!iph2->approval)
1134 return EINVAL;
1135
1136 pr = iph2->approval->head;
1137
1138 /* XXX must be get proper spi */
1139 tlen = sizeof(*n) + pr->spisize;
1140 if (data)
1141 tlen += data->l;
1142 payload = vmalloc(tlen);
1143 if (payload == NULL) {
d1e348cf
A
1144 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1145 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
1146 CONSTSTR("IPSEC-SA"),
1147 CONSTSTR("Failed to transmit IPSEC-SA message (can't allocate payload)"));
52b7d2ce
A
1148 plog(LLV_ERROR, LOCATION, NULL,
1149 "failed to get buffer to send.\n");
1150 return errno;
1151 }
1152
1153 n = (struct isakmp_pl_n *)payload->v;
1154 n->h.np = ISAKMP_NPTYPE_NONE;
1155 n->h.len = htons(tlen);
1156 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
1157 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
1158 n->spi_size = pr->spisize;
1159 n->type = htons(type);
1160 *(u_int32_t *)(n + 1) = pr->spi;
1161 if (data)
1162 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
1163
1164 iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */
1165 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
1166 vfree(payload);
d1e348cf
A
1167 if (error) {
1168 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1169 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
1170 CONSTSTR("IPSEC-SA"),
1171 CONSTSTR("Failed to transmit IPSEC-SA message"));
1172 } else {
1173 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1174 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
1175 CONSTSTR("IPSEC-SA"),
1176 CONSTSTR(NULL));
1177 }
1178
52b7d2ce
A
1179 return error;
1180}
1181
1182/*
1183 * send Information
1184 * When ph1->skeyid_a == NULL, send message without encoding.
1185 */
1186int
1187isakmp_info_send_common(iph1, payload, np, flags)
1188 struct ph1handle *iph1;
1189 vchar_t *payload;
1190 u_int32_t np;
1191 int flags;
1192{
1193 struct ph2handle *iph2 = NULL;
1194 vchar_t *hash = NULL;
1195 struct isakmp *isakmp;
1196 struct isakmp_gen *gen;
1197 char *p;
1198 int tlen;
1199 int error = -1;
1200
1201 /* add new entry to isakmp status table */
1202 iph2 = newph2();
d1e348cf
A
1203 if (iph2 == NULL) {
1204 plog(LLV_ERROR, LOCATION, NULL,
1205 "failed to allocate ph2");
52b7d2ce 1206 goto end;
d1e348cf 1207 }
52b7d2ce
A
1208
1209 iph2->dst = dupsaddr(iph1->remote);
d1e348cf
A
1210 if (iph2->dst == NULL) {
1211 plog(LLV_ERROR, LOCATION, NULL,
1212 "failed to duplicate remote address");
1213 delph2(iph2);
1214 goto end;
1215 }
52b7d2ce 1216 iph2->src = dupsaddr(iph1->local);
d1e348cf
A
1217 if (iph2->src == NULL) {
1218 plog(LLV_ERROR, LOCATION, NULL,
1219 "failed to duplicate local address");
1220 delph2(iph2);
1221 goto end;
1222 }
52b7d2ce
A
1223 switch (iph1->remote->sa_family) {
1224 case AF_INET:
d1e348cf 1225#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
52b7d2ce
A
1226 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1227 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1228#endif
1229 break;
1230#ifdef INET6
1231 case AF_INET6:
d1e348cf 1232#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
52b7d2ce
A
1233 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1234 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
d1e348cf 1235#endif
52b7d2ce
A
1236 break;
1237#endif
1238 default:
1239 plog(LLV_ERROR, LOCATION, NULL,
1240 "invalid family: %d\n", iph1->remote->sa_family);
1241 delph2(iph2);
1242 goto end;
1243 }
1244 iph2->ph1 = iph1;
1245 iph2->side = INITIATOR;
1246 iph2->status = PHASE2ST_START;
1247 iph2->msgid = isakmp_newmsgid2(iph1);
1248
1249 /* get IV and HASH(1) if skeyid_a was generated. */
1250 if (iph1->skeyid_a != NULL) {
1251 iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
1252 if (iph2->ivm == NULL) {
d1e348cf
A
1253 plog(LLV_ERROR, LOCATION, NULL,
1254 "failed to generate IV");
52b7d2ce
A
1255 delph2(iph2);
1256 goto end;
1257 }
1258
1259 /* generate HASH(1) */
1260 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
1261 if (hash == NULL) {
d1e348cf
A
1262 plog(LLV_ERROR, LOCATION, NULL,
1263 "failed to generate HASH");
52b7d2ce
A
1264 delph2(iph2);
1265 goto end;
1266 }
1267
1268 /* initialized total buffer length */
1269 tlen = hash->l;
1270 tlen += sizeof(*gen);
1271 } else {
1272 /* IKE-SA is not established */
1273 hash = NULL;
1274
1275 /* initialized total buffer length */
1276 tlen = 0;
1277 }
1278 if ((flags & ISAKMP_FLAG_A) == 0)
1279 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1280 else
1281 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1282
1283 insph2(iph2);
1284 bindph12(iph1, iph2);
1285
1286 tlen += sizeof(*isakmp) + payload->l;
1287
1288 /* create buffer for isakmp payload */
1289 iph2->sendbuf = vmalloc(tlen);
1290 if (iph2->sendbuf == NULL) {
1291 plog(LLV_ERROR, LOCATION, NULL,
1292 "failed to get buffer to send.\n");
1293 goto err;
1294 }
1295
1296 /* create isakmp header */
1297 isakmp = (struct isakmp *)iph2->sendbuf->v;
1298 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1299 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1300 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1301 isakmp->v = iph1->version;
1302 isakmp->etype = ISAKMP_ETYPE_INFO;
1303 isakmp->flags = iph2->flags;
1304 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1305 isakmp->len = htonl(tlen);
1306 p = (char *)(isakmp + 1);
1307
1308 /* create HASH payload */
1309 if (hash != NULL) {
1310 gen = (struct isakmp_gen *)p;
1311 gen->np = np & 0xff;
1312 gen->len = htons(sizeof(*gen) + hash->l);
1313 p += sizeof(*gen);
1314 memcpy(p, hash->v, hash->l);
1315 p += hash->l;
1316 }
1317
1318 /* add payload */
1319 memcpy(p, payload->v, payload->l);
1320 p += payload->l;
1321
1322#ifdef HAVE_PRINT_ISAKMP_C
1323 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1324#endif
1325
1326 /* encoding */
1327 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1328 vchar_t *tmp;
1329
1330 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
1331 iph2->ivm->iv);
1332 VPTRINIT(iph2->sendbuf);
d1e348cf
A
1333 if (tmp == NULL) {
1334 plog(LLV_ERROR, LOCATION, NULL,
1335 "failed to encrypt packet");
52b7d2ce 1336 goto err;
d1e348cf 1337 }
52b7d2ce
A
1338 iph2->sendbuf = tmp;
1339 }
1340
1341 /* HDR*, HASH(1), N */
1342 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
d1e348cf
A
1343 plog(LLV_ERROR, LOCATION, NULL,
1344 "failed to send packet");
52b7d2ce
A
1345 VPTRINIT(iph2->sendbuf);
1346 goto err;
1347 }
1348
1349 plog(LLV_DEBUG, LOCATION, NULL,
1350 "sendto Information %s.\n", s_isakmp_nptype(np));
1351
1352 /*
1353 * don't resend notify message because peer can use Acknowledged
1354 * Informational if peer requires the reply of the notify message.
1355 */
1356
1357 /* XXX If Acknowledged Informational required, don't delete ph2handle */
1358 error = 0;
1359 VPTRINIT(iph2->sendbuf);
d1e348cf
A
1360 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1361 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
1362 CONSTSTR("Information message"),
1363 CONSTSTR(NULL));
1364
52b7d2ce
A
1365 goto err; /* XXX */
1366
1367end:
d1e348cf
A
1368 if (error) {
1369 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1370 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
1371 CONSTSTR("Information message"),
1372 CONSTSTR("Failed to transmit Information message"));
1373 }
52b7d2ce
A
1374 if (hash)
1375 vfree(hash);
1376 return error;
1377
1378err:
1379 unbindph12(iph2);
1380 remph2(iph2);
1381 delph2(iph2);
1382 goto end;
1383}
1384
1385/*
1386 * add a notify payload to buffer by reallocating buffer.
1387 * If buf == NULL, the function only create a notify payload.
1388 *
1389 * XXX Which is SPI to be included, inbound or outbound ?
1390 */
1391vchar_t *
1392isakmp_add_pl_n(buf0, np_p, type, pr, data)
1393 vchar_t *buf0;
1394 u_int8_t **np_p;
1395 int type;
1396 struct saproto *pr;
1397 vchar_t *data;
1398{
1399 vchar_t *buf = NULL;
1400 struct isakmp_pl_n *n;
1401 int tlen;
1402 int oldlen = 0;
1403
1404 if (*np_p)
1405 **np_p = ISAKMP_NPTYPE_N;
1406
1407 tlen = sizeof(*n) + pr->spisize;
1408
1409 if (data)
1410 tlen += data->l;
1411 if (buf0) {
1412 oldlen = buf0->l;
1413 buf = vrealloc(buf0, buf0->l + tlen);
1414 } else
1415 buf = vmalloc(tlen);
1416 if (!buf) {
1417 plog(LLV_ERROR, LOCATION, NULL,
1418 "failed to get a payload buffer.\n");
1419 return NULL;
1420 }
1421
1422 n = (struct isakmp_pl_n *)(buf->v + oldlen);
1423 n->h.np = ISAKMP_NPTYPE_NONE;
1424 n->h.len = htons(tlen);
1425 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */
1426 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/
1427 n->spi_size = pr->spisize;
1428 n->type = htons(type);
1429 *(u_int32_t *)(n + 1) = pr->spi; /* XXX */
1430 if (data)
1431 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
1432
1433 /* save the pointer of next payload type */
1434 *np_p = &n->h.np;
1435
1436 return buf;
1437}
1438
d1e348cf 1439static void
52b7d2ce
A
1440purge_isakmp_spi(proto, spi, n)
1441 int proto;
1442 isakmp_index *spi; /*network byteorder*/
1443 size_t n;
1444{
1445 struct ph1handle *iph1;
1446 size_t i;
1447
1448 for (i = 0; i < n; i++) {
1449 iph1 = getph1byindex(&spi[i]);
80318cb7 1450 if (!iph1 || iph1->is_dying || iph1->status == PHASE1ST_EXPIRED)
52b7d2ce
A
1451 continue;
1452
1453 plog(LLV_INFO, LOCATION, NULL,
1454 "purged ISAKMP-SA proto_id=%s spi=%s.\n",
1455 s_ipsecdoi_proto(proto),
1456 isakmp_pindex(&spi[i], 0));
1457
d1e348cf
A
1458 SCHED_KILL(iph1->sce);
1459 SCHED_KILL(iph1->sce_rekey);
52b7d2ce 1460 iph1->status = PHASE1ST_EXPIRED;
d1e348cf 1461 ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1
52b7d2ce
A
1462 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
1463 }
1464}
1465
d1e348cf
A
1466
1467
1468void
52b7d2ce
A
1469purge_ipsec_spi(dst0, proto, spi, n)
1470 struct sockaddr *dst0;
1471 int proto;
1472 u_int32_t *spi; /*network byteorder*/
1473 size_t n;
1474{
1475 vchar_t *buf = NULL;
1476 struct sadb_msg *msg, *next, *end;
1477 struct sadb_sa *sa;
d1e348cf 1478 struct sadb_lifetime *lt;
52b7d2ce
A
1479 struct sockaddr *src, *dst;
1480 struct ph2handle *iph2;
d1e348cf 1481 u_int64_t created;
52b7d2ce
A
1482 size_t i;
1483 caddr_t mhp[SADB_EXT_MAX + 1];
1484
d1e348cf
A
1485 plog(LLV_DEBUG2, LOCATION, NULL,
1486 "purge_ipsec_spi:\n");
1487 plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0));
1488 plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0]));
1489
52b7d2ce
A
1490 buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto));
1491 if (buf == NULL) {
1492 plog(LLV_DEBUG, LOCATION, NULL,
1493 "pfkey_dump_sadb returned nothing.\n");
1494 return;
1495 }
1496
1497 msg = (struct sadb_msg *)buf->v;
1498 end = (struct sadb_msg *)(buf->v + buf->l);
1499
1500 while (msg < end) {
1501 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1502 break;
1503 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
1504 if (msg->sadb_msg_type != SADB_DUMP) {
1505 msg = next;
1506 continue;
1507 }
1508
1509 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
1510 plog(LLV_ERROR, LOCATION, NULL,
1511 "pfkey_check (%s)\n", ipsec_strerror());
1512 msg = next;
1513 continue;
1514 }
1515
1516 sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
1517 if (!sa
1518 || !mhp[SADB_EXT_ADDRESS_SRC]
1519 || !mhp[SADB_EXT_ADDRESS_DST]) {
1520 msg = next;
1521 continue;
1522 }
1523 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1524 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
d1e348cf
A
1525 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
1526 if(lt != NULL)
1527 created = lt->sadb_lifetime_addtime;
1528 else
1529 created = 0;
52b7d2ce
A
1530
1531 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1532 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1533 msg = next;
1534 continue;
1535 }
d1e348cf
A
1536 plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
1537 plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst));
1538
1539
52b7d2ce
A
1540
1541 /* XXX n^2 algorithm, inefficient */
1542
1543 /* don't delete inbound SAs at the moment */
1544 /* XXX should we remove SAs with opposite direction as well? */
d1e348cf 1545 if (CMPSADDR2(dst0, dst)) {
52b7d2ce
A
1546 msg = next;
1547 continue;
1548 }
1549
1550 for (i = 0; i < n; i++) {
1551 plog(LLV_DEBUG, LOCATION, NULL,
1552 "check spi(packet)=%u spi(db)=%u.\n",
1553 ntohl(spi[i]), ntohl(sa->sadb_sa_spi));
1554 if (spi[i] != sa->sadb_sa_spi)
1555 continue;
1556
1557 pfkey_send_delete(lcconf->sock_pfkey,
1558 msg->sadb_msg_satype,
1559 IPSEC_MODE_ANY,
1560 src, dst, sa->sadb_sa_spi);
1561
1562 /*
1563 * delete a relative phase 2 handler.
1564 * continue to process if no relative phase 2 handler
1565 * exists.
1566 */
1567 iph2 = getph2bysaidx(src, dst, proto, spi[i]);
d1e348cf 1568 if(iph2 != NULL){
52b7d2ce
A
1569 delete_spd(iph2);
1570 unbindph12(iph2);
1571 remph2(iph2);
1572 delph2(iph2);
1573 }
1574
1575 plog(LLV_INFO, LOCATION, NULL,
1576 "purged IPsec-SA proto_id=%s spi=%u.\n",
1577 s_ipsecdoi_proto(proto),
1578 ntohl(spi[i]));
1579 }
1580
1581 msg = next;
1582 }
1583
1584 if (buf)
1585 vfree(buf);
1586}
1587
1588/*
1589 * delete all phase2 sa relatived to the destination address.
1590 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
1591 * an INITIAL-CONTACT if we have contacted the peer. This matches the
1592 * Sun IKE behavior, and makes rekeying work much better when the peer
1593 * restarts.
1594 */
1595static void
1596info_recv_initialcontact(iph1)
1597 struct ph1handle *iph1;
1598{
1599 vchar_t *buf = NULL;
1600 struct sadb_msg *msg, *next, *end;
1601 struct sadb_sa *sa;
1602 struct sockaddr *src, *dst;
1603 caddr_t mhp[SADB_EXT_MAX + 1];
1604 int proto_id, i;
1605 struct ph2handle *iph2;
1606#if 0
1607 char *loc, *rem;
1608#endif
1609
1610 if (f_local)
1611 return;
1612
d1e348cf 1613 // TODO: make sure that is_rekey is cleared for this. and session indicates the same
52b7d2ce 1614#if 0
d1e348cf
A
1615 loc = racoon_strdup(saddrwop2str(iph1->local));
1616 rem = racoon_strdup(saddrwop2str(iph1->remote));
1617 STRDUP_FATAL(loc);
1618 STRDUP_FATAL(rem);
52b7d2ce
A
1619
1620 /*
1621 * Purge all IPSEC-SAs for the peer. We can do this
1622 * the easy way (using a PF_KEY SADB_DELETE extension)
1623 * or we can do it the hard way.
1624 */
1625 for (i = 0; i < pfkey_nsatypes; i++) {
1626 proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype);
1627
1628 plog(LLV_INFO, LOCATION, NULL,
1629 "purging %s SAs for %s -> %s\n",
1630 pfkey_satypes[i].ps_name, loc, rem);
1631 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1632 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1633 iph1->local, iph1->remote) == -1) {
1634 plog(LLV_ERROR, LOCATION, NULL,
1635 "delete_all %s -> %s failed for %s (%s)\n",
1636 loc, rem,
1637 pfkey_satypes[i].ps_name, ipsec_strerror());
1638 goto the_hard_way;
1639 }
1640
1641 deleteallph2(iph1->local, iph1->remote, proto_id);
1642
1643 plog(LLV_INFO, LOCATION, NULL,
1644 "purging %s SAs for %s -> %s\n",
1645 pfkey_satypes[i].ps_name, rem, loc);
1646 if (pfkey_send_delete_all(lcconf->sock_pfkey,
1647 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1648 iph1->remote, iph1->local) == -1) {
1649 plog(LLV_ERROR, LOCATION, NULL,
1650 "delete_all %s -> %s failed for %s (%s)\n",
1651 rem, loc,
1652 pfkey_satypes[i].ps_name, ipsec_strerror());
1653 goto the_hard_way;
1654 }
1655
1656 deleteallph2(iph1->remote, iph1->local, proto_id);
1657 }
1658
1659 racoon_free(loc);
1660 racoon_free(rem);
1661 return;
1662
1663 the_hard_way:
1664 racoon_free(loc);
1665 racoon_free(rem);
1666#endif
1667
1668 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
1669 if (buf == NULL) {
1670 plog(LLV_DEBUG, LOCATION, NULL,
1671 "pfkey_dump_sadb returned nothing.\n");
1672 return;
1673 }
1674
1675 msg = (struct sadb_msg *)buf->v;
1676 end = (struct sadb_msg *)(buf->v + buf->l);
1677
1678 while (msg < end) {
1679 if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1680 break;
1681 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
1682 if (msg->sadb_msg_type != SADB_DUMP) {
1683 msg = next;
1684 continue;
1685 }
1686
1687 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
1688 plog(LLV_ERROR, LOCATION, NULL,
1689 "pfkey_check (%s)\n", ipsec_strerror());
1690 msg = next;
1691 continue;
1692 }
1693
1694 if (mhp[SADB_EXT_SA] == NULL
1695 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1696 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1697 msg = next;
1698 continue;
1699 }
1700 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1701 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1702 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1703
1704 if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1705 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1706 msg = next;
1707 continue;
1708 }
1709
1710 /*
1711 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that
1712 * announces the sender of the message was rebooted.
1713 * it is interpreted to delete all SAs which source address
1714 * is the sender of the message.
1715 * racoon only deletes SA which is matched both the
1716 * source address and the destination accress.
1717 */
1718#ifdef ENABLE_NATT
1719 /*
1720 * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs
1721 * from this peer !
1722 */
1723 if(iph1->natt_flags & NAT_DETECTED){
1724 if (CMPSADDR(iph1->local, src) == 0 &&
1725 CMPSADDR(iph1->remote, dst) == 0)
1726 ;
1727 else if (CMPSADDR(iph1->remote, src) == 0 &&
1728 CMPSADDR(iph1->local, dst) == 0)
1729 ;
1730 else {
1731 msg = next;
1732 continue;
1733 }
1734 } else
1735#endif
1736 /* If there is no NAT-T, we don't have to check addr + port...
1737 * XXX what about a configuration with a remote peers which is not
1738 * NATed, but which NATs some other peers ?
1739 * Here, the INITIAl-CONTACT would also flush all those NATed peers !!
1740 */
1741 if (cmpsaddrwop(iph1->local, src) == 0 &&
1742 cmpsaddrwop(iph1->remote, dst) == 0)
1743 ;
1744 else if (cmpsaddrwop(iph1->remote, src) == 0 &&
1745 cmpsaddrwop(iph1->local, dst) == 0)
1746 ;
1747 else {
1748 msg = next;
1749 continue;
1750 }
1751
1752 /*
1753 * Make sure this is an SATYPE that we manage.
1754 * This is gross; too bad we couldn't do it the
1755 * easy way.
1756 */
1757 for (i = 0; i < pfkey_nsatypes; i++) {
1758 if (pfkey_satypes[i].ps_satype ==
1759 msg->sadb_msg_satype)
1760 break;
1761 }
1762 if (i == pfkey_nsatypes) {
1763 msg = next;
1764 continue;
1765 }
1766
1767 plog(LLV_INFO, LOCATION, NULL,
1768 "purging spi=%u.\n", ntohl(sa->sadb_sa_spi));
1769 pfkey_send_delete(lcconf->sock_pfkey,
1770 msg->sadb_msg_satype,
1771 IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi);
1772
1773 /*
1774 * delete a relative phase 2 handler.
1775 * continue to process if no relative phase 2 handler
1776 * exists.
1777 */
1778 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1779 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1780 if (iph2) {
1781 delete_spd(iph2);
1782 unbindph12(iph2);
1783 remph2(iph2);
1784 delph2(iph2);
1785 }
1786
1787 msg = next;
1788 }
1789
1790 vfree(buf);
1791}
1792
52b7d2ce
A
1793void
1794isakmp_check_notify(gen, iph1)
1795 struct isakmp_gen *gen; /* points to Notify payload */
1796 struct ph1handle *iph1;
1797{
1798 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
1799
1800 plog(LLV_DEBUG, LOCATION, iph1->remote,
1801 "Notify Message received\n");
1802
1803 switch (ntohs(notify->type)) {
1804 case ISAKMP_NTYPE_CONNECTED:
52b7d2ce 1805 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
52b7d2ce 1806 case ISAKMP_NTYPE_REPLAY_STATUS:
d1e348cf
A
1807 case ISAKMP_NTYPE_HEARTBEAT:
1808#ifdef ENABLE_HYBRID
1809 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
1810#endif
52b7d2ce 1811 plog(LLV_WARNING, LOCATION, iph1->remote,
d1e348cf
A
1812 "ignore %s notification.\n",
1813 s_isakmp_notify_msg(ntohs(notify->type)));
52b7d2ce
A
1814 break;
1815 case ISAKMP_NTYPE_INITIAL_CONTACT:
1816 plog(LLV_WARNING, LOCATION, iph1->remote,
1817 "ignore INITIAL-CONTACT notification, "
1818 "because it is only accepted after phase1.\n");
1819 break;
1820 case ISAKMP_NTYPE_LOAD_BALANCE:
1821 plog(LLV_WARNING, LOCATION, iph1->remote,
1822 "ignore LOAD-BALANCE notification, "
1823 "because it is only accepted after phase1.\n");
1824 break;
52b7d2ce
A
1825 default:
1826 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
1827 plog(LLV_ERROR, LOCATION, iph1->remote,
d1e348cf
A
1828 "received unknown notification type %s.\n",
1829 s_isakmp_notify_msg(ntohs(notify->type)));
52b7d2ce
A
1830 }
1831
1832 return;
1833}
1834
d1e348cf
A
1835void
1836isakmp_check_ph2_notify(gen, iph2)
1837struct isakmp_gen *gen; /* points to Notify payload */
1838struct ph2handle *iph2;
1839{
1840 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
1841
1842 plog(LLV_DEBUG, LOCATION, iph2->dst,
1843 "Phase2 Notify Message received\n");
1844
1845 switch (ntohs(notify->type)) {
1846 case ISAKMP_NTYPE_RESPONDER_LIFETIME:
1847 return((void)isakmp_ph2_responder_lifetime(iph2,
1848 (struct isakmp_pl_resp_lifetime *)notify));
1849 break;
1850 case ISAKMP_NTYPE_CONNECTED:
1851 case ISAKMP_NTYPE_REPLAY_STATUS:
1852 case ISAKMP_NTYPE_HEARTBEAT:
1853#ifdef ENABLE_HYBRID
1854 case ISAKMP_NTYPE_UNITY_HEARTBEAT:
1855#endif
1856 plog(LLV_WARNING, LOCATION, iph2->dst,
1857 "ignore %s notification.\n",
1858 s_isakmp_notify_msg(ntohs(notify->type)));
1859 break;
1860 case ISAKMP_NTYPE_INITIAL_CONTACT:
1861 plog(LLV_WARNING, LOCATION, iph2->dst,
1862 "ignore INITIAL-CONTACT notification, "
1863 "because it is only accepted after phase1.\n");
1864 break;
1865 case ISAKMP_NTYPE_LOAD_BALANCE:
1866 plog(LLV_WARNING, LOCATION, iph2->dst,
1867 "ignore LOAD-BALANCE notification, "
1868 "because it is only accepted after phase1.\n");
1869 break;
1870 default:
1871 isakmp_info_send_n1(iph2->ph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
1872 plog(LLV_ERROR, LOCATION, iph2->dst,
1873 "received unknown notification type %s.\n",
1874 s_isakmp_notify_msg(ntohs(notify->type)));
1875 }
1876
1877 return;
1878}
1879
52b7d2ce
A
1880#ifdef ENABLE_VPNCONTROL_PORT
1881static int
1882isakmp_info_recv_lb(iph1, n, encrypted)
1883 struct ph1handle *iph1;
1884 struct isakmp_pl_lb *n;
1885 int encrypted;
1886{
1887
1888 if (iph1->side != INITIATOR)
1889 {
1890 plog(LLV_DEBUG, LOCATION, NULL,
1891 "LOAD-BALANCE notification ignored - we are not the initiator.\n");
1892 return 0;
1893 }
1894 if (iph1->remote->sa_family != AF_INET) {
1895 plog(LLV_DEBUG, LOCATION, NULL,
1896 "LOAD-BALANCE notification ignored - only supported for IPv4.\n");
1897 return 0;
1898 }
1899 if (!encrypted) {
1900 plog(LLV_DEBUG, LOCATION, NULL,
1901 "LOAD-BALANCE notification ignored - not protected.\n");
1902 return 0;
1903 }
1904 if (ntohs(n->h.len) != sizeof(struct isakmp_pl_lb)) {
1905 plog(LLV_DEBUG, LOCATION, NULL,
1906 "Invalid length of payload\n");
1907 return -1;
1908 }
1909 vpncontrol_notify_ike_failed(ISAKMP_NTYPE_LOAD_BALANCE, FROM_REMOTE,
1910 ((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr, 4, (u_int8_t*)(&(n->address)));
1911
1912 plog(LLV_DEBUG, LOCATION, iph1->remote,
1913 "received LOAD_BALANCE notification - redirect address=%x.\n",
1914 ntohl(n->address));
1915
d1e348cf
A
1916 if (((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr != ntohl(n->address)) {
1917 plog(LLV_DEBUG, LOCATION, iph1->remote,
1918 "deleting old phase1 because of LOAD_BALANCE notification - redirect address=%x.\n",
1919 ntohl(n->address));
1920
1921 if (iph1->status == PHASE1ST_ESTABLISHED) {
1922 isakmp_info_send_d1(iph1);
1923 }
1924 isakmp_ph1expire(iph1);
1925 }
1926
52b7d2ce
A
1927 return 0;
1928}
1929#endif
1930
1931#ifdef ENABLE_DPD
1932static int
1933isakmp_info_recv_r_u (iph1, ru, msgid)
1934 struct ph1handle *iph1;
1935 struct isakmp_pl_ru *ru;
1936 u_int32_t msgid;
1937{
1938 struct isakmp_pl_ru *ru_ack;
1939 vchar_t *payload = NULL;
1940 int tlen;
1941 int error = 0;
1942
1943 plog(LLV_DEBUG, LOCATION, iph1->remote,
1944 "DPD R-U-There received\n");
1945
1946 /* XXX should compare cookies with iph1->index?
1947 Or is this already done by calling function? */
1948 tlen = sizeof(*ru_ack);
1949 payload = vmalloc(tlen);
1950 if (payload == NULL) {
d1e348cf
A
1951 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1952 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
1953 CONSTSTR("R-U-THERE? ACK"),
1954 CONSTSTR("Failed to transmit DPD response"));
52b7d2ce
A
1955 plog(LLV_ERROR, LOCATION, NULL,
1956 "failed to get buffer to send.\n");
1957 return errno;
1958 }
1959
1960 ru_ack = (struct isakmp_pl_ru *)payload->v;
1961 ru_ack->h.np = ISAKMP_NPTYPE_NONE;
1962 ru_ack->h.len = htons(tlen);
1963 ru_ack->doi = htonl(IPSEC_DOI);
1964 ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK);
1965 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */
1966 ru_ack->spi_size = sizeof(isakmp_index);
1967 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t));
1968 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t));
1969 ru_ack->data = ru->data;
1970
1971 /* XXX Should we do FLAG_A ? */
1972 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
1973 ISAKMP_FLAG_E);
1974 vfree(payload);
d1e348cf
A
1975 if (error) {
1976 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1977 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
1978 CONSTSTR("R-U-THERE? ACK"),
1979 CONSTSTR("Failed to transmit DPD ack"));
1980 } else {
1981 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1982 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
1983 CONSTSTR("R-U-THERE? ACK"),
1984 CONSTSTR(NULL));
1985 }
52b7d2ce
A
1986
1987 plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n");
1988
1989 /* Should we mark tunnel as active ? */
1990 return error;
1991}
1992
1993static int
1994isakmp_info_recv_r_u_ack (iph1, ru, msgid)
1995 struct ph1handle *iph1;
1996 struct isakmp_pl_ru *ru;
1997 u_int32_t msgid;
1998{
1999
2000 plog(LLV_DEBUG, LOCATION, iph1->remote,
2001 "DPD R-U-There-Ack received\n");
2002
2003 /* XXX Maintain window of acceptable sequence numbers ?
2004 * => ru->data <= iph2->dpd_seq &&
2005 * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */
d1e348cf 2006 if (ntohl(ru->data) != iph1->dpd_seq) {
52b7d2ce
A
2007 plog(LLV_ERROR, LOCATION, iph1->remote,
2008 "Wrong DPD sequence number (%d, %d expected).\n",
d1e348cf 2009 ntohl(ru->data), iph1->dpd_seq);
52b7d2ce
A
2010 return 0;
2011 }
2012
2013 if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) ||
2014 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) {
2015 plog(LLV_ERROR, LOCATION, iph1->remote,
2016 "Cookie mismatch in DPD ACK!.\n");
2017 return 0;
2018 }
2019
2020 iph1->dpd_fails = 0;
2021
d1e348cf
A
2022 iph1->dpd_seq++;
2023
52b7d2ce
A
2024 /* Useless ??? */
2025 iph1->dpd_lastack = time(NULL);
2026
d1e348cf 2027 SCHED_KILL(iph1->dpd_r_u);
52b7d2ce
A
2028
2029 isakmp_sched_r_u(iph1, 0);
2030
d1e348cf
A
2031 if (iph1->side == INITIATOR) {
2032 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2033 IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RESP,
2034 CONSTSTR("Initiator DPD Response"),
2035 CONSTSTR(NULL));
2036 } else {
2037 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2038 IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RESP,
2039 CONSTSTR("Responder DPD Response"),
2040 CONSTSTR(NULL));
2041 }
52b7d2ce
A
2042 plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
2043
2044 return 0;
2045}
2046
2047
2048/*
2049 * send Delete payload (for ISAKMP SA) in Informational exchange.
2050 */
d1e348cf 2051void
52b7d2ce
A
2052isakmp_info_send_r_u(arg)
2053 void *arg;
2054{
2055 struct ph1handle *iph1 = arg;
2056
2057 /* create R-U-THERE payload */
2058 struct isakmp_pl_ru *ru;
2059 vchar_t *payload = NULL;
2060 int tlen;
2061 int error = 0;
2062
d1e348cf
A
2063 if (iph1->status != PHASE1ST_ESTABLISHED) {
2064 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD r-u send aborted, invalid phase1 status %d....\n",
2065 iph1->status);
2066 return;
2067 }
52b7d2ce
A
2068
2069 if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
d1e348cf
A
2070 u_int32_t address;
2071
2072 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2073 IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT,
2074 CONSTSTR("DPD maximum retransmits"),
2075 CONSTSTR("maxed-out of DPD requests without receiving an ack"));
2076
52b7d2ce 2077 EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL);
d1e348cf
A
2078 if (iph1->remote->sa_family == AF_INET)
2079 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
2080 else
2081 address = 0;
2082 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PEER_DEAD, FROM_LOCAL, address, 0, NULL);
2083
52b7d2ce
A
2084 purge_remote(iph1);
2085 plog(LLV_DEBUG, LOCATION, iph1->remote,
2086 "DPD: remote seems to be dead\n");
2087
2088 /* Do not reschedule here: phase1 is deleted,
2089 * DPD will be reactivated when a new ph1 will be negociated
2090 */
2091 return;
2092 }
2093
52b7d2ce
A
2094 tlen = sizeof(*ru);
2095 payload = vmalloc(tlen);
2096 if (payload == NULL) {
d1e348cf
A
2097 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2098 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
2099 CONSTSTR("R-U-THERE?"),
2100 CONSTSTR("Failed to transmit DPD request"));
52b7d2ce
A
2101 plog(LLV_ERROR, LOCATION, NULL,
2102 "failed to get buffer for payload.\n");
2103 return;
2104 }
2105 ru = (struct isakmp_pl_ru *)payload->v;
2106 ru->h.np = ISAKMP_NPTYPE_NONE;
2107 ru->h.len = htons(tlen);
2108 ru->doi = htonl(IPSEC_DOI);
2109 ru->type = htons(ISAKMP_NTYPE_R_U_THERE);
2110 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/
2111 ru->spi_size = sizeof(isakmp_index);
2112
2113 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t));
2114 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t));
2115
2116 if (iph1->dpd_seq == 0){
2117 /* generate a random seq which is not too big */
2118 srand(time(NULL));
2119 iph1->dpd_seq = rand() & 0x0fff;
2120 }
2121
2122 ru->data = htonl(iph1->dpd_seq);
2123
2124 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
2125 vfree(payload);
d1e348cf
A
2126 if (error) {
2127 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2128 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL,
2129 CONSTSTR("R-U-THERE?"),
2130 CONSTSTR("Failed to transmit DPD request"));
2131 } else {
2132 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2133 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC,
2134 CONSTSTR("R-U-THERE?"),
2135 CONSTSTR(NULL));
2136 }
52b7d2ce 2137
d1e348cf
A
2138 if (iph1->side == INITIATOR) {
2139 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2140 iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ,
2141 CONSTSTR("Initiator DPD Request"),
2142 CONSTSTR(NULL));
2143 } else {
2144 IPSECSESSIONTRACEREVENT(iph1->parent_session,
2145 iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ,
2146 CONSTSTR("Responder DPD Request"),
2147 CONSTSTR(NULL));
2148 }
52b7d2ce
A
2149 plog(LLV_DEBUG, LOCATION, iph1->remote,
2150 "DPD R-U-There sent (%d)\n", error);
2151
2152 /* will be decreased if ACK received... */
2153 iph1->dpd_fails++;
2154
52b7d2ce
A
2155 /* Reschedule the r_u_there with a short delay,
2156 * will be deleted/rescheduled if ACK received before */
2157 isakmp_sched_r_u(iph1, 1);
2158
2159 plog(LLV_DEBUG, LOCATION, iph1->remote,
2160 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry);
2161}
2162
d1e348cf
A
2163/*
2164 * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange.
2165 */
2166static void
2167isakmp_info_monitor_r_u_algo_inbound_detect (struct ph1handle *iph1)
2168{
2169 if (iph1->status != PHASE1ST_ESTABLISHED) {
2170 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) aborted, invalid phase1 status %d....\n",
2171 iph1->status);
2172 return;
2173 }
2174
2175 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) ....\n");
2176
2177 // check phase1 for ike packets received from peer
2178 if (iph1->peer_sent_ike) {
2179 // yes, reshedule check
2180 iph1->peer_sent_ike = 0;
2181
2182 /* ike packets received from peer... reschedule dpd */
2183 isakmp_sched_r_u(iph1, 0);
2184
2185 plog(LLV_DEBUG, LOCATION, iph1->remote,
2186 "ike packets received from peer... reschedule monitor.\n");
2187
2188 return;
2189 }
2190
2191 // after ike packets, next we check if any data was received
2192 if (!iph1->parent_session->peer_sent_data_sc_dpd) {
2193 isakmp_info_send_r_u(iph1);
2194 } else {
2195 isakmp_sched_r_u(iph1, 0);
2196
2197 plog(LLV_DEBUG, LOCATION, iph1->remote,
2198 "rescheduling DPD monitoring (for ALGORITHM_INBOUND_DETECT).\n");
2199 }
2200 iph1->parent_session->peer_sent_data_sc_dpd = 0;
2201}
2202
2203/*
2204 * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange.
2205 */
2206static void
2207isakmp_info_monitor_r_u_algo_blackhole_detect (struct ph1handle *iph1)
2208{
2209 if (iph1->status != PHASE1ST_ESTABLISHED) {
2210 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) aborted, invalid phase1 status %d....\n",
2211 iph1->status);
2212 return;
2213 }
2214
2215 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) ....\n");
2216
2217 // check if data was sent but none was received
2218 if (iph1->parent_session->i_sent_data_sc_dpd &&
2219 !iph1->parent_session->peer_sent_data_sc_dpd) {
2220 isakmp_info_send_r_u(iph1);
2221 } else {
2222 isakmp_sched_r_u(iph1, 0);
2223
2224 plog(LLV_DEBUG, LOCATION, iph1->remote,
2225 "rescheduling DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) i = %d, peer %d.\n",
2226 iph1->parent_session->i_sent_data_sc_dpd,
2227 iph1->parent_session->peer_sent_data_sc_dpd);
2228 }
2229 iph1->parent_session->i_sent_data_sc_dpd = 0;
2230 iph1->parent_session->peer_sent_data_sc_dpd = 0;
2231}
2232
2233/*
2234 * monitor DPD Informational exchange.
2235 */
2236static void
2237isakmp_info_monitor_r_u(arg)
2238void *arg;
2239{
2240 struct ph1handle *iph1 = arg;
2241
2242 if (iph1 && iph1->rmconf) {
2243 if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT) {
2244 isakmp_info_monitor_r_u_algo_inbound_detect(iph1);
2245 } else if (iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) {
2246 isakmp_info_monitor_r_u_algo_blackhole_detect(iph1);
2247 } else {
2248 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring aborted, invalid algorithm %d....\n",
2249 iph1->rmconf->dpd_algo);
2250 }
2251 }
2252}
2253
52b7d2ce
A
2254/* Schedule a new R-U-THERE */
2255int
2256isakmp_sched_r_u(iph1, retry)
2257 struct ph1handle *iph1;
2258 int retry;
2259{
2260 if(iph1 == NULL ||
2261 iph1->rmconf == NULL)
2262 return 1;
2263
2264
2265 if(iph1->dpd_support == 0 ||
2266 iph1->rmconf->dpd_interval == 0)
2267 return 0;
2268
d1e348cf 2269 if(retry) {
52b7d2ce 2270 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry,
d1e348cf
A
2271 isakmp_info_send_r_u, iph1);
2272 } else {
2273 if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT ||
2274 iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) {
2275 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
2276 isakmp_info_monitor_r_u, iph1);
2277 } else {
2278 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
2279 isakmp_info_send_r_u, iph1);
2280 }
2281 }
52b7d2ce
A
2282
2283 return 0;
2284}
d1e348cf
A
2285
2286/*
2287 * punts dpd for later because of some activity that:
2288 * 1) implicitly does dpd (e.g. phase2 exchanges), or
2289 * 2) indicates liveness (e.g. received ike packets).
2290 */
2291void
2292isakmp_reschedule_info_monitor_if_pending (struct ph1handle *iph1,
2293 char *reason)
2294{
2295 if (!iph1 ||
2296 iph1->status != PHASE1ST_ESTABLISHED ||
2297 !iph1->dpd_support ||
2298 !iph1->rmconf->dpd_interval ||
2299 iph1->rmconf->dpd_algo == DPD_ALGO_DEFAULT) {
2300 return;
2301 }
2302
2303 if (!iph1->peer_sent_ike) {
2304 SCHED_KILL(iph1->dpd_r_u);
2305
2306 isakmp_sched_r_u(iph1, 0);
2307
2308 plog(LLV_DEBUG, LOCATION, iph1->remote,
2309 "%s... rescheduling send_r_u.\n",
2310 reason);
2311 }
2312 iph1->peer_sent_ike++;
2313}
52b7d2ce 2314#endif