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