]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/isakmp_cfg.c
ipsec-258.1.3.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_cfg.c
1 /* $NetBSD: isakmp_cfg.c,v 1.12.6.1 2007/06/07 20:06:34 manu Exp $ */
2
3 /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
4
5 /*
6 * Copyright (C) 2004-2006 Emmanuel Dreyfus
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 #include <sys/queue.h>
40
41 #include <utmpx.h>
42 #include <util.h>
43
44
45 #ifdef __FreeBSD__
46 # include <libutil.h>
47 #endif
48 #ifdef __NetBSD__
49 # include <util.h>
50 #endif
51
52 #include <netinet/in.h>
53 #include <arpa/inet.h>
54
55 #include <stdlib.h>
56 #include <stdio.h>
57 #include <string.h>
58 #include <errno.h>
59 #if TIME_WITH_SYS_TIME
60 # include <sys/time.h>
61 # include <time.h>
62 #else
63 # if HAVE_SYS_TIME_H
64 # include <sys/time.h>
65 # else
66 # include <time.h>
67 # endif
68 #endif
69 #include <netdb.h>
70 #ifdef HAVE_UNISTD_H
71 #include <unistd.h>
72 #endif
73 #if HAVE_STDINT_H
74 #include <stdint.h>
75 #endif
76 #include <ctype.h>
77 #include <resolv.h>
78
79 #include "var.h"
80 #include "misc.h"
81 #include "vmbuf.h"
82 #include "plog.h"
83 #include "sockmisc.h"
84 #include "schedule.h"
85 #include "debug.h"
86 #include "fsm.h"
87
88 #include "isakmp_var.h"
89 #include "isakmp.h"
90 #include "handler.h"
91 #include "throttle.h"
92 #include "remoteconf.h"
93 #include "localconf.h"
94 #include "crypto_openssl.h"
95 #include "isakmp_inf.h"
96 #include "isakmp_xauth.h"
97 #include "isakmp_unity.h"
98 #include "isakmp_cfg.h"
99 #include "strnames.h"
100 #include "vpn_control.h"
101 #include "vpn_control_var.h"
102 #include "ike_session.h"
103 #include "ipsecSessionTracer.h"
104 #include "ipsecMessageTracer.h"
105 #include "nattraversal.h"
106
107 struct isakmp_cfg_config isakmp_cfg_config;
108
109 static vchar_t *buffer_cat (vchar_t *s, vchar_t *append);
110 static vchar_t *isakmp_cfg_net (phase1_handle_t *, struct isakmp_data *);
111 #if 0
112 static vchar_t *isakmp_cfg_void (phase1_handle_t *, struct isakmp_data *);
113 #endif
114 static vchar_t *isakmp_cfg_addr4 (phase1_handle_t *,
115 struct isakmp_data *, in_addr_t *);
116 static void isakmp_cfg_getaddr4 (struct isakmp_data *, struct in_addr *);
117 static vchar_t *isakmp_cfg_addr4_list (phase1_handle_t *,
118 struct isakmp_data *, in_addr_t *, int);
119 static void isakmp_cfg_appendaddr4 (struct isakmp_data *,
120 struct in_addr *, int *, int);
121 static void isakmp_cfg_getstring (struct isakmp_data *,char *);
122 void isakmp_cfg_iplist_to_str (char *, int, void *, int);
123
124 #define ISAKMP_CFG_LOGIN 1
125 #define ISAKMP_CFG_LOGOUT 2
126
127 /*
128 * Handle an ISAKMP config mode packet
129 * We expect HDR, HASH, ATTR
130 */
131 void
132 isakmp_cfg_r(iph1, msg)
133 phase1_handle_t *iph1;
134 vchar_t *msg;
135 {
136 struct isakmp *packet;
137 struct isakmp_gen *ph;
138 int tlen;
139 char *npp;
140 int np;
141 vchar_t *dmsg;
142 struct isakmp_ivm *ivm;
143 phase2_handle_t *iph2;
144 int error = -1;
145
146 /* Check that the packet is long enough to have a header */
147 if (msg->l < sizeof(*packet)) {
148 IPSECSESSIONTRACEREVENT(iph1->parent_session,
149 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
150 CONSTSTR("MODE-Config. Unexpected short packet"),
151 CONSTSTR("Failed to process short MODE-Config packet"));
152 plog(ASL_LEVEL_ERR, "Unexpected short packet\n");
153 return;
154 }
155
156 packet = (struct isakmp *)msg->v;
157
158 /* Is it encrypted? It should be encrypted */
159 if ((packet->flags & ISAKMP_FLAG_E) == 0) {
160 IPSECSESSIONTRACEREVENT(iph1->parent_session,
161 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
162 CONSTSTR("MODE-Config. User credentials sent in cleartext"),
163 CONSTSTR("Dropped cleattext User credentials"));
164 plog(ASL_LEVEL_ERR,
165 "User credentials sent in cleartext!\n");
166 return;
167 }
168
169 /*
170 * Decrypt the packet. If this is the beginning of a new
171 * exchange, reinitialize the IV
172 */
173 if (iph1->mode_cfg->ivm == NULL ||
174 iph1->mode_cfg->last_msgid != packet->msgid )
175 iph1->mode_cfg->ivm =
176 isakmp_cfg_newiv(iph1, packet->msgid);
177 ivm = iph1->mode_cfg->ivm;
178
179 dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
180 if (dmsg == NULL) {
181 IPSECSESSIONTRACEREVENT(iph1->parent_session,
182 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
183 CONSTSTR("MODE-Config. Failed to decrypt packet"),
184 CONSTSTR("Failed to decrypt MODE-Config packet"));
185 plog(ASL_LEVEL_ERR,
186 "failed to decrypt message\n");
187 return;
188 }
189
190 plog(ASL_LEVEL_DEBUG, "MODE_CFG packet\n");
191
192 /* Now work with the decrypted packet */
193 packet = (struct isakmp *)dmsg->v;
194 tlen = dmsg->l - sizeof(*packet);
195 ph = (struct isakmp_gen *)(packet + 1);
196
197 np = packet->np;
198 while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
199 /* Check that the payload header fits in the packet */
200 if (tlen < sizeof(*ph)) {
201 plog(ASL_LEVEL_WARNING,
202 "Short payload header\n");
203 goto out;
204 }
205
206 /* Check that the payload fits in the packet */
207 if (tlen < ntohs(ph->len)) {
208 plog(ASL_LEVEL_WARNING,
209 "Short payload\n");
210 goto out;
211 }
212
213 plog(ASL_LEVEL_DEBUG, "Seen payload %d\n", np);
214
215 switch(np) {
216 case ISAKMP_NPTYPE_HASH: {
217 vchar_t *check;
218 vchar_t *payload;
219 size_t plen;
220 struct isakmp_gen *nph;
221
222 plen = ntohs(ph->len);
223 nph = (struct isakmp_gen *)((char *)ph + plen);
224 plen = ntohs(nph->len);
225 /* Check that the hash payload fits in the packet */
226 if (tlen < (plen + ntohs(ph->len))) {
227 plog(ASL_LEVEL_WARNING,
228 "Invalid Hash payload. len %d, overall-len %d\n",
229 ntohs(nph->len),
230 (int)plen);
231 goto out;
232 }
233
234 if ((payload = vmalloc(plen)) == NULL) {
235 plog(ASL_LEVEL_ERR,
236 "Cannot allocate memory\n");
237 goto out;
238 }
239 memcpy(payload->v, nph, plen);
240
241 if ((check = oakley_compute_hash1(iph1,
242 packet->msgid, payload)) == NULL) {
243 plog(ASL_LEVEL_ERR,
244 "Cannot compute hash\n");
245 vfree(payload);
246 goto out;
247 }
248
249 if (memcmp(ph + 1, check->v, check->l) != 0) {
250 plog(ASL_LEVEL_ERR,
251 "Hash verification failed\n");
252 vfree(payload);
253 vfree(check);
254 goto out;
255 }
256 vfree(payload);
257 vfree(check);
258 break;
259 }
260 case ISAKMP_NPTYPE_ATTR: {
261 struct isakmp_pl_attr *attrpl;
262
263 attrpl = (struct isakmp_pl_attr *)ph;
264 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl, msg);
265
266 break;
267 }
268 default:
269 plog(ASL_LEVEL_WARNING,
270 "Unexpected next payload %d\n", np);
271 /* Skip to the next payload */
272 break;
273 }
274
275 /* Move to the next payload */
276 np = ph->np;
277 tlen -= ntohs(ph->len);
278 npp = (char *)ph;
279 ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
280 }
281
282 error = 0;
283 /* find phase 2 in case pkt scheduled for resend */
284 iph2 = ike_session_getph2bymsgid(iph1, packet->msgid);
285 if (iph2 == NULL)
286 goto out; /* no resend scheduled */
287 SCHED_KILL(iph2->scr); /* turn off schedule */
288 ike_session_unlink_phase2(iph2);
289
290 IPSECSESSIONTRACEREVENT(iph1->parent_session,
291 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
292 CONSTSTR("MODE-Config"),
293 CONSTSTR(NULL));
294 out:
295 if (error) {
296 IPSECSESSIONTRACEREVENT(iph1->parent_session,
297 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
298 CONSTSTR("MODE-Config"),
299 CONSTSTR("Failed to process Mode-Config packet"));
300 }
301 vfree(dmsg);
302 }
303
304 int
305 isakmp_cfg_attr_r(iph1, msgid, attrpl, msg)
306 phase1_handle_t *iph1;
307 u_int32_t msgid;
308 struct isakmp_pl_attr *attrpl;
309 vchar_t *msg;
310 {
311 int type = attrpl->type;
312
313 plog(ASL_LEVEL_DEBUG,
314 "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
315 switch (type) {
316 case ISAKMP_CFG_ACK:
317 /* ignore, but this is the time to reinit the IV */
318 oakley_delivm(iph1->mode_cfg->ivm);
319 iph1->mode_cfg->ivm = NULL;
320 return 0;
321 break;
322
323 case ISAKMP_CFG_REPLY:
324 return isakmp_cfg_reply(iph1, attrpl);
325 break;
326
327 case ISAKMP_CFG_REQUEST:
328 iph1->msgid = msgid;
329 return isakmp_cfg_request(iph1, attrpl, msg);
330 break;
331
332 case ISAKMP_CFG_SET:
333 iph1->msgid = msgid;
334 return isakmp_cfg_set(iph1, attrpl, msg);
335 break;
336
337 default:
338 plog(ASL_LEVEL_WARNING,
339 "Unepected configuration exchange type %d\n", type);
340 return -1;
341 break;
342 }
343
344 return 0;
345 }
346
347 int
348 isakmp_cfg_reply(iph1, attrpl)
349 phase1_handle_t *iph1;
350 struct isakmp_pl_attr *attrpl;
351 {
352 struct isakmp_data *attr;
353 int tlen;
354 size_t alen;
355 char *npp;
356 int type;
357 int error;
358
359 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_REPLY)
360 return 0; /* already received this - duplicate packet */
361
362 tlen = ntohs(attrpl->h.len);
363 attr = (struct isakmp_data *)(attrpl + 1);
364 tlen -= sizeof(*attrpl);
365
366 while (tlen > 0) {
367 type = ntohs(attr->type);
368
369 /* Handle short attributes */
370 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
371 type &= ~ISAKMP_GEN_MASK;
372
373 plog(ASL_LEVEL_DEBUG,
374 "Short attribute %s = %d\n",
375 s_isakmp_cfg_type(type), ntohs(attr->lorv));
376
377 switch (type) {
378 case XAUTH_TYPE:
379 if ((error = xauth_attr_reply(iph1,
380 attr, ntohs(attrpl->id))) != 0)
381 return error;
382 break;
383
384 break;
385
386 default:
387 plog(ASL_LEVEL_WARNING,
388 "Ignored short attribute %s\n",
389 s_isakmp_cfg_type(type));
390 break;
391 }
392
393 tlen -= sizeof(*attr);
394 attr++;
395 continue;
396 }
397
398 type = ntohs(attr->type);
399 alen = ntohs(attr->lorv);
400
401 /* Check that the attribute fit in the packet */
402 if (tlen < alen) {
403 plog(ASL_LEVEL_ERR,
404 "Short attribute %s\n",
405 s_isakmp_cfg_type(type));
406 return -1;
407 }
408
409 plog(ASL_LEVEL_DEBUG,
410 "Attribute %s, len %zu\n",
411 s_isakmp_cfg_type(type), alen);
412
413 switch(type) {
414 case XAUTH_TYPE:
415 case XAUTH_USER_NAME:
416 case XAUTH_USER_PASSWORD:
417 case XAUTH_PASSCODE:
418 case XAUTH_MESSAGE:
419 case XAUTH_CHALLENGE:
420 case XAUTH_DOMAIN:
421 case XAUTH_STATUS:
422 case XAUTH_NEXT_PIN:
423 case XAUTH_ANSWER:
424 if ((error = xauth_attr_reply(iph1,
425 attr, ntohs(attrpl->id))) != 0)
426 return error;
427 break;
428 case INTERNAL_IP4_ADDRESS:
429 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) == 0) {
430 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
431 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
432 }
433 break;
434 case INTERNAL_IP4_NETMASK:
435 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) == 0) {
436 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
437 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
438 }
439 break;
440 case INTERNAL_IP4_DNS:
441 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) == 0) {
442 isakmp_cfg_appendaddr4(attr,
443 &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
444 &iph1->mode_cfg->dns4_index, MAXNS);
445 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
446 }
447 break;
448 case INTERNAL_IP4_NBNS:
449 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) == 0) {
450 isakmp_cfg_appendaddr4(attr,
451 &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
452 &iph1->mode_cfg->wins4_index, MAXNS);
453 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
454 }
455 break;
456 case UNITY_DEF_DOMAIN:
457 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) == 0) {
458 isakmp_cfg_getstring(attr,
459 iph1->mode_cfg->default_domain);
460 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
461 }
462 break;
463 case UNITY_SPLIT_INCLUDE:
464 case UNITY_LOCAL_LAN:
465 case UNITY_SPLITDNS_NAME:
466 case UNITY_BANNER:
467 case UNITY_SAVE_PASSWD:
468 case UNITY_NATT_PORT:
469 case UNITY_FW_TYPE:
470 case UNITY_BACKUP_SERVERS:
471 case UNITY_DDNS_HOSTNAME:
472 case APPLICATION_VERSION:
473 case UNITY_PFS:
474 isakmp_unity_reply(iph1, attr);
475 break;
476 case INTERNAL_IP4_SUBNET:
477 case INTERNAL_ADDRESS_EXPIRY:
478 if (iph1->started_by_api)
479 break; /* not actually ignored - don't fall thru */
480 // else fall thru
481 default:
482 plog(ASL_LEVEL_WARNING,
483 "Ignored attribute %s\n",
484 s_isakmp_cfg_type(type));
485 break;
486 }
487
488 npp = (char *)attr;
489 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
490 tlen -= (sizeof(*attr) + alen);
491 }
492 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_REPLY;
493
494 if (iph1->started_by_api || (iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client)) {
495 /* connection was started by API - save attr list for passing to VPN controller */
496 if (iph1->mode_cfg->attr_list != NULL) /* shouldn't happen */
497 vfree(iph1->mode_cfg->attr_list);
498 if (ntohs(attrpl->h.len) < sizeof(*attrpl)) {
499 plog(ASL_LEVEL_ERR,
500 "invalid cfg-attr-list, attr-len %d\n",
501 ntohs(attrpl->h.len));
502 return -1;
503 }
504 alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
505 if ((iph1->mode_cfg->attr_list = vmalloc(alen)) == NULL) {
506 plog(ASL_LEVEL_ERR,
507 "Cannot allocate memory for mode-cfg attribute list\n");
508 return -1;
509 }
510 memcpy(iph1->mode_cfg->attr_list->v, attrpl + 1, alen);
511 }
512
513
514 #ifdef ENABLE_VPNCONTROL_PORT
515 if (FSM_STATE_IS_ESTABLISHED(iph1->status))
516 vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
517 #endif
518
519 return 0;
520 }
521
522 int
523 isakmp_cfg_request(iph1, attrpl, msg)
524 phase1_handle_t *iph1;
525 struct isakmp_pl_attr *attrpl;
526 vchar_t *msg;
527 {
528 struct isakmp_data *attr;
529 int tlen;
530 size_t alen;
531 char *npp;
532 vchar_t *payload = NULL;
533 struct isakmp_pl_attr *reply;
534 vchar_t *reply_attr;
535 int type;
536 int error = -1;
537
538 tlen = ntohs(attrpl->h.len);
539 attr = (struct isakmp_data *)(attrpl + 1);
540 tlen -= sizeof(*attrpl);
541
542 /*
543 * if started_by_api then we are a VPN client and if we receive
544 * a mode-cfg request it needs to go to the VPN controller to
545 * retrieve the appropriate data (name, pw, pin, etc.)
546 */
547 if (iph1->started_by_api || ike_session_is_client_ph1_rekey(iph1)) {
548 /*
549 * if we already received this one - ignore it
550 * we are waiting for a reply from the vpn control socket
551 */
552 if (iph1->xauth_awaiting_userinput)
553 return 0;
554
555 /* otherwise - save the msg id and call and send the status notification */
556 iph1->pended_xauth_id = attrpl->id; /* network byte order */
557 if (vpncontrol_notify_need_authinfo(iph1, attrpl + 1, tlen))
558 goto end;
559 iph1->xauth_awaiting_userinput = 1;
560 iph1->xauth_awaiting_userinput_msg = vdup(msg); // dup the message for later
561 ike_session_start_xauth_timer(iph1);
562
563 IPSECLOGASLMSG("IPSec Extended Authentication requested.\n");
564
565 return 0;
566 }
567
568 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
569 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
570 return -1;
571 }
572 memset(payload->v, 0, sizeof(*reply));
573
574 while (tlen > 0) {
575 reply_attr = NULL;
576 type = ntohs(attr->type);
577
578 /* Handle short attributes */
579 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
580 type &= ~ISAKMP_GEN_MASK;
581
582 plog(ASL_LEVEL_DEBUG,
583 "Short attribute %s = %d\n",
584 s_isakmp_cfg_type(type), ntohs(attr->lorv));
585
586 switch (type) {
587 case XAUTH_TYPE:
588 reply_attr = isakmp_xauth_req(iph1, attr);
589 break;
590 default:
591 plog(ASL_LEVEL_WARNING,
592 "Ignored short attribute %s\n",
593 s_isakmp_cfg_type(type));
594 break;
595 }
596
597 tlen -= sizeof(*attr);
598 attr++;
599
600 if (reply_attr != NULL) {
601 payload = buffer_cat(payload, reply_attr);
602 vfree(reply_attr);
603 }
604
605 continue;
606 }
607
608 type = ntohs(attr->type);
609 alen = ntohs(attr->lorv);
610
611 /* Check that the attribute fit in the packet */
612 if (tlen < alen) {
613 plog(ASL_LEVEL_ERR,
614 "Short attribute %s\n",
615 s_isakmp_cfg_type(type));
616 goto end;
617 }
618
619 plog(ASL_LEVEL_DEBUG,
620 "Attribute %s, len %zu\n",
621 s_isakmp_cfg_type(type), alen);
622
623 switch(type) {
624 case INTERNAL_IP4_ADDRESS:
625 case INTERNAL_IP4_NETMASK:
626 case INTERNAL_IP4_DNS:
627 case INTERNAL_IP4_NBNS:
628 case INTERNAL_IP4_SUBNET:
629 reply_attr = isakmp_cfg_net(iph1, attr);
630 break;
631
632 case XAUTH_TYPE:
633 case XAUTH_USER_NAME:
634 case XAUTH_USER_PASSWORD:
635 case XAUTH_PASSCODE:
636 case XAUTH_MESSAGE:
637 case XAUTH_CHALLENGE:
638 case XAUTH_DOMAIN:
639 case XAUTH_STATUS:
640 case XAUTH_NEXT_PIN:
641 case XAUTH_ANSWER:
642 reply_attr = isakmp_xauth_req(iph1, attr);
643 break;
644
645 case APPLICATION_VERSION:
646 reply_attr = isakmp_cfg_string(iph1,
647 attr, ISAKMP_CFG_RACOON_VERSION);
648 break;
649
650 case UNITY_BANNER:
651 case UNITY_PFS:
652 case UNITY_SAVE_PASSWD:
653 case UNITY_DEF_DOMAIN:
654 case UNITY_DDNS_HOSTNAME:
655 case UNITY_FW_TYPE:
656 case UNITY_SPLITDNS_NAME:
657 case UNITY_SPLIT_INCLUDE:
658 case UNITY_LOCAL_LAN:
659 case UNITY_NATT_PORT:
660 case UNITY_BACKUP_SERVERS:
661 reply_attr = isakmp_unity_req(iph1, attr);
662 break;
663
664 case INTERNAL_ADDRESS_EXPIRY:
665 default:
666 plog(ASL_LEVEL_WARNING,
667 "Ignored attribute %s\n",
668 s_isakmp_cfg_type(type));
669 break;
670 }
671
672 npp = (char *)attr;
673 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
674 tlen -= (sizeof(*attr) + alen);
675
676 if (reply_attr != NULL) {
677 payload = buffer_cat(payload, reply_attr);
678 vfree(reply_attr);
679 }
680 }
681
682 reply = (struct isakmp_pl_attr *)payload->v;
683 reply->h.len = htons(payload->l);
684 reply->type = ISAKMP_CFG_REPLY;
685 reply->id = attrpl->id;
686
687 plog(ASL_LEVEL_DEBUG,
688 "Sending MODE_CFG REPLY\n");
689
690 error = isakmp_cfg_send(iph1, payload,
691 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
692
693
694 end:
695 vfree(payload);
696
697 return error;
698 }
699
700 int
701 isakmp_cfg_set(iph1, attrpl, msg)
702 phase1_handle_t *iph1;
703 struct isakmp_pl_attr *attrpl;
704 vchar_t *msg;
705 {
706 struct isakmp_data *attr;
707 int tlen;
708 size_t alen;
709 char *npp;
710 vchar_t *payload;
711 struct isakmp_pl_attr *reply;
712 vchar_t *reply_attr;
713 int type;
714 int error = -1;
715
716 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
717 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
718 return -1;
719 }
720 memset(payload->v, 0, sizeof(*reply));
721
722 tlen = ntohs(attrpl->h.len);
723 attr = (struct isakmp_data *)(attrpl + 1);
724 tlen -= sizeof(*attrpl);
725
726 /*
727 * We should send ack for the attributes we accepted
728 */
729 while (tlen > 0) {
730 reply_attr = NULL;
731 type = ntohs(attr->type);
732
733 plog(ASL_LEVEL_DEBUG,
734 "Attribute %s\n",
735 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
736
737 switch (type & ~ISAKMP_GEN_MASK) {
738 case XAUTH_STATUS:
739 reply_attr = isakmp_xauth_set(iph1, attr);
740 break;
741 default:
742 plog(ASL_LEVEL_DEBUG,
743 "Unexpected SET attribute %s\n",
744 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
745 break;
746 }
747
748 if (reply_attr != NULL) {
749 payload = buffer_cat(payload, reply_attr);
750 vfree(reply_attr);
751 }
752
753 /*
754 * Move to next attribute. If we run out of the packet,
755 * tlen becomes negative and we exit.
756 */
757 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
758 tlen -= sizeof(*attr);
759 attr++;
760 } else {
761 alen = ntohs(attr->lorv);
762 tlen -= (sizeof(*attr) + alen);
763 npp = (char *)attr;
764 attr = (struct isakmp_data *)
765 (npp + sizeof(*attr) + alen);
766 }
767 }
768
769 reply = (struct isakmp_pl_attr *)payload->v;
770 reply->h.len = htons(payload->l);
771 reply->type = ISAKMP_CFG_ACK;
772 reply->id = attrpl->id;
773
774 plog(ASL_LEVEL_DEBUG,
775 "Sending MODE_CFG ACK\n");
776
777 error = isakmp_cfg_send(iph1, payload,
778 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
779
780 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
781 if (FSM_STATE_IS_ESTABLISHED(iph1->status))
782 isakmp_info_send_d1(iph1);
783 isakmp_ph1expire(iph1);
784 iph1 = NULL;
785 }
786 vfree(payload);
787
788 /*
789 * If required, request ISAKMP mode config information: ignore rekeys
790 */
791 if ((iph1 != NULL) && (!iph1->is_rekey) && (iph1->rmconf->mode_cfg) && (error == 0))
792 error = isakmp_cfg_getconfig(iph1);
793
794 return error;
795 }
796
797
798 static vchar_t *
799 buffer_cat(s, append)
800 vchar_t *s;
801 vchar_t *append;
802 {
803 vchar_t *new;
804
805 new = vmalloc(s->l + append->l);
806 if (new == NULL) {
807 plog(ASL_LEVEL_ERR,
808 "Cannot allocate memory\n");
809 return s;
810 }
811
812 memcpy(new->v, s->v, s->l);
813 memcpy(new->v + s->l, append->v, append->l);
814
815 vfree(s);
816 return new;
817 }
818
819 static vchar_t *
820 isakmp_cfg_net(iph1, attr)
821 phase1_handle_t *iph1;
822 struct isakmp_data *attr;
823 {
824 int type;
825 int confsource;
826
827 type = ntohs(attr->type);
828
829 /*
830 * Don't give an address to a peer that did not succeed Xauth
831 */
832 if (xauth_check(iph1) != 0) {
833 plog(ASL_LEVEL_ERR,
834 "Attempt to start phase config whereas Xauth failed\n");
835 return NULL;
836 }
837
838 confsource = isakmp_cfg_config.confsource;
839 /*
840 * If we have to fall back to a local
841 * configuration source, we will jump
842 * back to this point.
843 */
844
845 switch(type) {
846 case INTERNAL_IP4_ADDRESS:
847 switch(confsource) {
848 case ISAKMP_CFG_CONF_LOCAL:
849 if (isakmp_cfg_getport(iph1) == -1) {
850 plog(ASL_LEVEL_ERR,
851 "Port pool depleted\n");
852 break;
853 }
854
855 iph1->mode_cfg->addr4.s_addr =
856 htonl(ntohl(isakmp_cfg_config.network4)
857 + iph1->mode_cfg->port);
858 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
859 break;
860
861 default:
862 plog(ASL_LEVEL_ERR,
863 "Unexpected confsource\n");
864 }
865
866 return isakmp_cfg_addr4(iph1,
867 attr, &iph1->mode_cfg->addr4.s_addr);
868 break;
869
870 case INTERNAL_IP4_NETMASK:
871 switch(confsource) {
872 case ISAKMP_CFG_CONF_LOCAL:
873 iph1->mode_cfg->mask4.s_addr
874 = isakmp_cfg_config.netmask4;
875 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
876 break;
877
878 default:
879 plog(ASL_LEVEL_ERR,
880 "Unexpected confsource\n");
881 }
882 return isakmp_cfg_addr4(iph1, attr,
883 &iph1->mode_cfg->mask4.s_addr);
884 break;
885
886 case INTERNAL_IP4_DNS:
887 return isakmp_cfg_addr4_list(iph1,
888 attr, &isakmp_cfg_config.dns4[0],
889 isakmp_cfg_config.dns4_index);
890 break;
891
892 case INTERNAL_IP4_NBNS:
893 return isakmp_cfg_addr4_list(iph1,
894 attr, &isakmp_cfg_config.nbns4[0],
895 isakmp_cfg_config.nbns4_index);
896 break;
897
898 case INTERNAL_IP4_SUBNET:
899 return isakmp_cfg_addr4(iph1,
900 attr, &isakmp_cfg_config.network4);
901 break;
902
903 default:
904 plog(ASL_LEVEL_ERR, "Unexpected type %d\n", type);
905 break;
906 }
907 return NULL;
908 }
909
910 #if 0
911 static vchar_t *
912 isakmp_cfg_void(iph1, attr)
913 phase1_handle_t *iph1;
914 struct isakmp_data *attr;
915 {
916 vchar_t *buffer;
917 struct isakmp_data *new;
918
919 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
920 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
921 return NULL;
922 }
923
924 new = (struct isakmp_data *)buffer->v;
925
926 new->type = attr->type;
927 new->lorv = htons(0);
928
929 return buffer;
930 }
931 #endif
932
933 vchar_t *
934 isakmp_cfg_copy(iph1, attr)
935 phase1_handle_t *iph1;
936 struct isakmp_data *attr;
937 {
938 vchar_t *buffer;
939 size_t len = 0;
940
941 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
942 len = ntohs(attr->lorv);
943
944 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
945 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
946 return NULL;
947 }
948
949 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
950
951 return buffer;
952 }
953
954 vchar_t *
955 isakmp_cfg_short(iph1, attr, value)
956 phase1_handle_t *iph1;
957 struct isakmp_data *attr;
958 int value;
959 {
960 vchar_t *buffer;
961 struct isakmp_data *new;
962 int type;
963
964 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
965 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
966 return NULL;
967 }
968
969 new = (struct isakmp_data *)buffer->v;
970 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
971
972 new->type = htons(type | ISAKMP_GEN_TV);
973 new->lorv = htons(value);
974
975 return buffer;
976 }
977
978 vchar_t *
979 isakmp_cfg_varlen(iph1, attr, string, len)
980 phase1_handle_t *iph1;
981 struct isakmp_data *attr;
982 char *string;
983 size_t len;
984 {
985 vchar_t *buffer;
986 struct isakmp_data *new;
987 char *data;
988
989 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
990 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
991 return NULL;
992 }
993
994 new = (struct isakmp_data *)buffer->v;
995
996 new->type = attr->type;
997 new->lorv = htons(len);
998 data = (char *)(new + 1);
999
1000 memcpy(data, string, len);
1001
1002 return buffer;
1003 }
1004 vchar_t *
1005 isakmp_cfg_string(iph1, attr, string)
1006 phase1_handle_t *iph1;
1007 struct isakmp_data *attr;
1008 char *string;
1009 {
1010 size_t len = strlen(string);
1011 return isakmp_cfg_varlen(iph1, attr, string, len);
1012 }
1013
1014 static vchar_t *
1015 isakmp_cfg_addr4(iph1, attr, addr)
1016 phase1_handle_t *iph1;
1017 struct isakmp_data *attr;
1018 in_addr_t *addr;
1019 {
1020 vchar_t *buffer;
1021 struct isakmp_data *new;
1022 size_t len;
1023
1024 len = sizeof(*addr);
1025 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1026 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
1027 return NULL;
1028 }
1029
1030 new = (struct isakmp_data *)buffer->v;
1031
1032 new->type = attr->type;
1033 new->lorv = htons(len);
1034 memcpy(new + 1, addr, len);
1035
1036 return buffer;
1037 }
1038
1039 static vchar_t *
1040 isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1041 phase1_handle_t *iph1;
1042 struct isakmp_data *attr;
1043 in_addr_t *addr;
1044 int nbr;
1045 {
1046 int error = -1;
1047 vchar_t *buffer = NULL;
1048 vchar_t *bufone = NULL;
1049 struct isakmp_data *new;
1050 size_t len;
1051 int i;
1052
1053 len = sizeof(*addr);
1054 if ((buffer = vmalloc(0)) == NULL) {
1055 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
1056 goto out;
1057 }
1058 for(i = 0; i < nbr; i++) {
1059 if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1060 plog(ASL_LEVEL_ERR,
1061 "Cannot allocate memory\n");
1062 goto out;
1063 }
1064 new = (struct isakmp_data *)bufone->v;
1065 new->type = attr->type;
1066 new->lorv = htons(len);
1067 memcpy(new + 1, &addr[i], len);
1068 new += (len + sizeof(*attr));
1069 buffer = buffer_cat(buffer, bufone);
1070 vfree(bufone);
1071 }
1072
1073 error = 0;
1074
1075 out:
1076 if ((error != 0) && (buffer != NULL)) {
1077 vfree(buffer);
1078 buffer = NULL;
1079 }
1080
1081 return buffer;
1082 }
1083
1084 struct isakmp_ivm *
1085 isakmp_cfg_newiv(iph1, msgid)
1086 phase1_handle_t *iph1;
1087 u_int32_t msgid;
1088 {
1089 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1090
1091 if (ics == NULL) {
1092 plog(ASL_LEVEL_ERR,
1093 "isakmp_cfg_newiv called without mode config state\n");
1094 return NULL;
1095 }
1096
1097 if (ics->ivm != NULL)
1098 oakley_delivm(ics->ivm);
1099
1100 ics->ivm = oakley_newiv2(iph1, msgid);
1101 ics->last_msgid = msgid;
1102
1103 return ics->ivm;
1104 }
1105
1106 /* Derived from isakmp_info_send_common */
1107 int
1108 isakmp_cfg_send(iph1, payload, np, flags, new_exchange, retry_count, msg)
1109 phase1_handle_t *iph1;
1110 vchar_t *payload;
1111 u_int32_t np;
1112 int flags;
1113 int new_exchange;
1114 int retry_count;
1115 vchar_t *msg;
1116 {
1117 phase2_handle_t *iph2 = NULL;
1118 vchar_t *hash = NULL;
1119 struct isakmp *isakmp;
1120 struct isakmp_gen *gen;
1121 char *p;
1122 int tlen;
1123 int error = -1;
1124 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1125
1126 /* Check if phase 1 is established */
1127 if ((!FSM_STATE_IS_ESTABLISHED(iph1->status)) ||
1128 (iph1->local == NULL) ||
1129 (iph1->remote == NULL)) {
1130 plog(ASL_LEVEL_ERR,
1131 "ISAKMP mode config exchange with immature phase 1\n");
1132 goto end;
1133 }
1134
1135 /* add new entry to isakmp status table */
1136 iph2 = ike_session_newph2(ISAKMP_VERSION_NUMBER_IKEV1, PHASE2_TYPE_CFG);
1137 if (iph2 == NULL) {
1138 plog(ASL_LEVEL_ERR,
1139 "failed to allocate ph2");
1140 goto end;
1141 }
1142
1143 iph2->dst = dupsaddr(iph1->remote);
1144 if (iph2->dst == NULL) {
1145 plog(ASL_LEVEL_ERR,
1146 "failed to duplicate remote address");
1147 ike_session_delph2(iph2);
1148 goto end;
1149 }
1150 iph2->src = dupsaddr(iph1->local);
1151 if (iph2->src == NULL) {
1152 plog(ASL_LEVEL_ERR,
1153 "failed to duplicate local address");
1154 ike_session_delph2(iph2);
1155 goto end;
1156 }
1157
1158 switch (iph1->remote->ss_family) {
1159 case AF_INET:
1160 #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1161 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1162 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1163 #endif
1164 break;
1165 #ifdef INET6
1166 case AF_INET6:
1167 #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1168 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1169 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
1170 #endif
1171 break;
1172 #endif
1173 default:
1174 plog(ASL_LEVEL_ERR,
1175 "invalid family: %d\n", iph1->remote->ss_family);
1176 ike_session_delph2(iph2);
1177 goto end;
1178 }
1179 iph2->side = INITIATOR;
1180 fsm_set_state(&iph2->status, IKEV1_STATE_INFO);
1181
1182 if (new_exchange)
1183 iph2->msgid = isakmp_newmsgid2(iph1);
1184 else
1185 iph2->msgid = iph1->msgid;
1186
1187 /* get IV and HASH(1) if skeyid_a was generated. */
1188 if (iph1->skeyid_a != NULL) {
1189 if (new_exchange) {
1190 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1191 plog(ASL_LEVEL_ERR,
1192 "failed to generate IV");
1193 ike_session_delph2(iph2);
1194 goto end;
1195 }
1196 }
1197
1198 /* generate HASH(1) */
1199 hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
1200 if (hash == NULL) {
1201 plog(ASL_LEVEL_ERR,
1202 "failed to generate HASH");
1203 ike_session_delph2(iph2);
1204 goto end;
1205 }
1206
1207 /* initialized total buffer length */
1208 tlen = hash->l;
1209 tlen += sizeof(*gen);
1210 } else {
1211 /* IKE-SA is not established */
1212 hash = NULL;
1213
1214 /* initialized total buffer length */
1215 tlen = 0;
1216 }
1217 if ((flags & ISAKMP_FLAG_A) == 0)
1218 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1219 else
1220 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1221
1222 ike_session_link_ph2_to_ph1(iph1, iph2);
1223
1224 tlen += sizeof(*isakmp) + payload->l;
1225
1226 /* create buffer for isakmp payload */
1227 iph2->sendbuf = vmalloc(tlen);
1228 if (iph2->sendbuf == NULL) {
1229 plog(ASL_LEVEL_ERR,
1230 "failed to get buffer to send.\n");
1231 goto err;
1232 }
1233
1234 /* create isakmp header */
1235 isakmp = (struct isakmp *)iph2->sendbuf->v;
1236 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1237 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1238 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1239 isakmp->v = iph1->version;
1240 isakmp->etype = ISAKMP_ETYPE_CFG;
1241 isakmp->flags = iph2->flags;
1242 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1243 isakmp->len = htonl(tlen);
1244 p = (char *)(isakmp + 1);
1245
1246 /* create HASH payload */
1247 if (hash != NULL) {
1248 gen = (struct isakmp_gen *)p;
1249 gen->np = np & 0xff;
1250 gen->len = htons(sizeof(*gen) + hash->l);
1251 p += sizeof(*gen);
1252 memcpy(p, hash->v, hash->l);
1253 p += hash->l;
1254 }
1255
1256 /* add payload */
1257 memcpy(p, payload->v, payload->l);
1258 p += payload->l;
1259
1260 #ifdef HAVE_PRINT_ISAKMP_C
1261 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1262 #endif
1263
1264 plog(ASL_LEVEL_DEBUG, "MODE_CFG packet to send\n");
1265
1266 /* encoding */
1267 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1268 vchar_t *tmp;
1269
1270 tmp = oakley_do_encrypt(iph1, iph2->sendbuf,
1271 ics->ivm->ive, ics->ivm->iv);
1272 VPTRINIT(iph2->sendbuf);
1273 if (tmp == NULL) {
1274 plog(ASL_LEVEL_ERR,
1275 "failed to encrypt packet");
1276 goto err;
1277 }
1278 iph2->sendbuf = tmp;
1279 }
1280
1281 /* HDR*, HASH(1), ATTR */
1282
1283 if (retry_count > 0) {
1284 iph2->retry_counter = retry_count;
1285 if (isakmp_ph2resend(iph2) < 0) {
1286 plog(ASL_LEVEL_ERR,
1287 "failed to resend packet");
1288 VPTRINIT(iph2->sendbuf);
1289 goto err;
1290 }
1291 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1292 IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT,
1293 CONSTSTR("Mode-Config retransmit"),
1294 CONSTSTR(NULL));
1295 error = 0;
1296 goto end;
1297 }
1298
1299 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1300 plog(ASL_LEVEL_ERR,
1301 "failed to send packet");
1302 VPTRINIT(iph2->sendbuf);
1303 goto err;
1304 }
1305 if (msg) {
1306 /* the sending message is added to the received-list. */
1307 if (ike_session_add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg,
1308 PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH1_FRAG_FLAGS(iph1)) == -1) {
1309 plog(ASL_LEVEL_ERR ,
1310 "failed to add a response packet to the tree.\n");
1311 }
1312 }
1313
1314 plog(ASL_LEVEL_DEBUG,
1315 "sendto mode config %s.\n", s_isakmp_nptype(np));
1316
1317 /*
1318 * XXX We might need to resend the message...
1319 */
1320
1321 error = 0;
1322 VPTRINIT(iph2->sendbuf);
1323
1324 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1325 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
1326 CONSTSTR("Mode-Config message"),
1327 CONSTSTR(NULL));
1328
1329 err:
1330 if (error) {
1331 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1332 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
1333 CONSTSTR("Mode-Config message"),
1334 CONSTSTR("Failed to transmit Mode-Config message"));
1335 }
1336 ike_session_unlink_phase2(iph2);
1337 end:
1338 if (hash)
1339 vfree(hash);
1340 return error;
1341 }
1342
1343
1344 void
1345 isakmp_cfg_rmstate(phase1_handle_t *iph1)
1346 {
1347 struct isakmp_cfg_state **state = &iph1->mode_cfg;
1348
1349
1350 if (*state == NULL)
1351 return;
1352
1353 if ((*state)->flags & ISAKMP_CFG_PORT_ALLOCATED)
1354 isakmp_cfg_putport(iph1, (*state)->port);
1355
1356 /* Delete the IV if it's still there */
1357 if((*state)->ivm) {
1358 oakley_delivm((*state)->ivm);
1359 (*state)->ivm = NULL;
1360 }
1361
1362 /* Free any allocated splitnet lists */
1363 if((*state)->split_include != NULL)
1364 splitnet_list_free((*state)->split_include,
1365 &(*state)->include_count);
1366 if((*state)->split_local != NULL)
1367 splitnet_list_free((*state)->split_local,
1368 &(*state)->local_count);
1369
1370 xauth_rmstate(&(*state)->xauth);
1371
1372 if ((*state)->attr_list)
1373 vfree((*state)->attr_list);
1374
1375 racoon_free((*state));
1376 (*state) = NULL;
1377
1378 return;
1379 }
1380
1381 struct isakmp_cfg_state *
1382 isakmp_cfg_mkstate(void)
1383 {
1384 struct isakmp_cfg_state *state;
1385
1386 if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1387 plog(ASL_LEVEL_ERR,
1388 "Cannot allocate memory for mode config state\n");
1389 return NULL;
1390 }
1391 memset(state, 0, sizeof(*state));
1392
1393 return state;
1394 }
1395
1396 int
1397 isakmp_cfg_getport(iph1)
1398 phase1_handle_t *iph1;
1399 {
1400 unsigned int i;
1401 size_t size = isakmp_cfg_config.pool_size;
1402
1403 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1404 return iph1->mode_cfg->port;
1405
1406 if (isakmp_cfg_config.port_pool == NULL) {
1407 plog(ASL_LEVEL_ERR,
1408 "isakmp_cfg_config.port_pool == NULL\n");
1409 return -1;
1410 }
1411
1412 for (i = 0; i < size; i++) {
1413 if (isakmp_cfg_config.port_pool[i].used == 0)
1414 break;
1415 }
1416
1417 if (i == size) {
1418 plog(ASL_LEVEL_ERR,
1419 "No more addresses available\n");
1420 return -1;
1421 }
1422
1423 isakmp_cfg_config.port_pool[i].used = 1;
1424
1425 plog(ASL_LEVEL_INFO, "Using port %d\n", i);
1426
1427 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1428 iph1->mode_cfg->port = i;
1429
1430 return i;
1431 }
1432
1433 int
1434 isakmp_cfg_putport(iph1, index)
1435 phase1_handle_t *iph1;
1436 unsigned int index;
1437 {
1438 if (isakmp_cfg_config.port_pool == NULL) {
1439 plog(ASL_LEVEL_ERR,
1440 "isakmp_cfg_config.port_pool == NULL\n");
1441 return -1;
1442 }
1443
1444 if (isakmp_cfg_config.port_pool[index].used == 0) {
1445 plog(ASL_LEVEL_ERR,
1446 "Attempt to release an unallocated address (port %d)\n",
1447 index);
1448 return -1;
1449 }
1450
1451 isakmp_cfg_config.port_pool[index].used = 0;
1452 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1453
1454 plog(ASL_LEVEL_INFO, "Released port %d\n", index);
1455
1456 return 0;
1457 }
1458
1459
1460 int
1461 isakmp_cfg_getconfig(iph1)
1462 phase1_handle_t *iph1;
1463 {
1464 vchar_t *buffer;
1465 struct isakmp_pl_attr *attrpl;
1466 struct isakmp_data *attr;
1467 size_t len;
1468 vchar_t *version = NULL;
1469 int error;
1470 int attrcount;
1471 int i;
1472 int attrlist[] = {
1473 INTERNAL_IP4_ADDRESS,
1474 INTERNAL_IP4_NETMASK,
1475 INTERNAL_IP4_DNS,
1476 INTERNAL_IP4_NBNS,
1477 INTERNAL_ADDRESS_EXPIRY,
1478 APPLICATION_VERSION,
1479 UNITY_BANNER,
1480 UNITY_DEF_DOMAIN,
1481 UNITY_SPLITDNS_NAME,
1482 UNITY_SPLIT_INCLUDE,
1483 UNITY_LOCAL_LAN,
1484 };
1485
1486 attrcount = sizeof(attrlist) / sizeof(*attrlist);
1487 len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1488
1489 if (iph1->started_by_api) {
1490 if (iph1->remote->ss_family == AF_INET) {
1491 struct vpnctl_socket_elem *sock_elem;
1492 struct bound_addr *bound_addr;
1493 u_int32_t address;
1494
1495 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
1496 LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
1497 LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
1498 if (bound_addr->address == address) {
1499 if ((version = bound_addr->version))
1500 len += bound_addr->version->l;
1501 break;
1502 }
1503 }
1504 }
1505 }
1506 }
1507
1508 if ((buffer = vmalloc(len)) == NULL) {
1509 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
1510 return -1;
1511 }
1512
1513 attrpl = (struct isakmp_pl_attr *)buffer->v;
1514 attrpl->h.len = htons(len);
1515 attrpl->type = ISAKMP_CFG_REQUEST;
1516 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1517
1518 attr = (struct isakmp_data *)(attrpl + 1);
1519
1520 for (i = 0; i < attrcount; i++) {
1521 switch (attrlist[i]) {
1522 case APPLICATION_VERSION:
1523 if (version) {
1524 attr->type = htons(attrlist[i]);
1525 attr->lorv = htons(version->l);
1526 memcpy(attr + 1, version->v, version->l);
1527 attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l);
1528 break;
1529 } else /* fall thru */;
1530 default:
1531 attr->type = htons(attrlist[i]);
1532 attr->lorv = htons(0);
1533 attr++;
1534 break;
1535 }
1536 }
1537
1538 plog(ASL_LEVEL_DEBUG,
1539 "Sending MODE_CFG REQUEST\n");
1540
1541 error = isakmp_cfg_send(iph1, buffer,
1542 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL);
1543
1544 vfree(buffer);
1545
1546 IPSECLOGASLMSG("IPSec Network Configuration requested.\n");
1547
1548 return error;
1549 }
1550
1551 static void
1552 isakmp_cfg_getaddr4(attr, ip)
1553 struct isakmp_data *attr;
1554 struct in_addr *ip;
1555 {
1556 size_t alen = ntohs(attr->lorv);
1557 in_addr_t *addr;
1558
1559 if (alen != sizeof(*ip)) {
1560 plog(ASL_LEVEL_ERR, "Bad IPv4 address len\n");
1561 return;
1562 }
1563
1564 addr = ALIGNED_CAST(in_addr_t *)(attr + 1); // Wcast-align fix (void*) - attr comes from packet data in a vchar_t
1565 ip->s_addr = *addr;
1566
1567 return;
1568 }
1569
1570 static void
1571 isakmp_cfg_appendaddr4(attr, ip, num, max)
1572 struct isakmp_data *attr;
1573 struct in_addr *ip;
1574 int *num;
1575 int max;
1576 {
1577 size_t alen = ntohs(attr->lorv);
1578 in_addr_t *addr;
1579
1580 if (alen != sizeof(*ip)) {
1581 plog(ASL_LEVEL_ERR, "Bad IPv4 address len\n");
1582 return;
1583 }
1584 if (*num == max) {
1585 plog(ASL_LEVEL_ERR, "Too many addresses given\n");
1586 return;
1587 }
1588
1589 addr = ALIGNED_CAST(in_addr_t *)(attr + 1); // Wcast-align fix (void*) - attr comes from packet data in a vchar_t
1590 ip->s_addr = *addr;
1591 (*num)++;
1592
1593 return;
1594 }
1595
1596 static void
1597 isakmp_cfg_getstring(attr, str)
1598 struct isakmp_data *attr;
1599 char *str;
1600 {
1601 size_t alen = ntohs(attr->lorv);
1602 char *src;
1603 src = (char *)(attr + 1);
1604
1605 memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
1606
1607 return;
1608 }
1609
1610 #define IP_MAX 40
1611
1612 void
1613 isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
1614 char *dest;
1615 int count;
1616 void *addr;
1617 int withmask;
1618 {
1619 int i;
1620 int p;
1621 int l;
1622 struct unity_network tmp;
1623 for(i = 0, p = 0; i < count; i++) {
1624 if(withmask == 1)
1625 l = sizeof(struct unity_network);
1626 else
1627 l = sizeof(struct in_addr);
1628 memcpy(&tmp, addr, l);
1629 addr += l;
1630 if((uint32_t)tmp.addr4.s_addr == 0)
1631 break;
1632
1633 inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
1634 p += strlen(dest + p);
1635 if(withmask == 1) {
1636 dest[p] = '/';
1637 p++;
1638 inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
1639 p += strlen(dest + p);
1640 }
1641 dest[p] = ' ';
1642 p++;
1643 }
1644 if(p > 0)
1645 dest[p-1] = '\0';
1646 else
1647 dest[0] = '\0';
1648 }
1649
1650 int
1651 isakmp_cfg_resize_pool(size)
1652 int size;
1653 {
1654 struct isakmp_cfg_port *new_pool;
1655 size_t len;
1656 int i;
1657
1658 if (size == isakmp_cfg_config.pool_size)
1659 return 0;
1660
1661 plog(ASL_LEVEL_INFO,
1662 "Resize address pool from %zu to %d\n",
1663 isakmp_cfg_config.pool_size, size);
1664
1665 /* If a pool already exists, check if we can shrink it */
1666 if ((isakmp_cfg_config.port_pool != NULL) &&
1667 (size < isakmp_cfg_config.pool_size)) {
1668 for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
1669 if (isakmp_cfg_config.port_pool[i].used) {
1670 plog(ASL_LEVEL_ERR,
1671 "resize pool from %zu to %d impossible "
1672 "port %d is in use\n",
1673 isakmp_cfg_config.pool_size, size, i);
1674 size = i;
1675 break;
1676 }
1677 }
1678 }
1679
1680 len = size * sizeof(*isakmp_cfg_config.port_pool);
1681 new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
1682 if (new_pool == NULL) {
1683 plog(ASL_LEVEL_ERR,
1684 "resize pool from %zu to %d impossible: %s",
1685 isakmp_cfg_config.pool_size, size, strerror(errno));
1686 return -1;
1687 }
1688
1689 /* If size increase, intialize correctly the new records */
1690 if (size > isakmp_cfg_config.pool_size) {
1691 size_t unit;
1692 size_t old_size;
1693
1694 unit = sizeof(*isakmp_cfg_config.port_pool);
1695 old_size = isakmp_cfg_config.pool_size;
1696
1697 bzero((char *)new_pool + (old_size * unit),
1698 (size - old_size) * unit);
1699 }
1700
1701 isakmp_cfg_config.port_pool = new_pool;
1702 isakmp_cfg_config.pool_size = size;
1703
1704 return 0;
1705 }
1706
1707 int
1708 isakmp_cfg_init(cold)
1709 int cold;
1710 {
1711 int i;
1712 #if 0
1713 int error;
1714 #endif
1715
1716 isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
1717 isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
1718 for (i = 0; i < MAXNS; i++)
1719 isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
1720 isakmp_cfg_config.dns4_index = 0;
1721 for (i = 0; i < MAXWINS; i++)
1722 isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
1723 isakmp_cfg_config.nbns4_index = 0;
1724 if (cold != ISAKMP_CFG_INIT_COLD) {
1725 if (isakmp_cfg_config.port_pool) {
1726 racoon_free(isakmp_cfg_config.port_pool);
1727 }
1728 }
1729 isakmp_cfg_config.port_pool = NULL;
1730 isakmp_cfg_config.pool_size = 0;
1731 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
1732 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
1733 if (cold != ISAKMP_CFG_INIT_COLD) {
1734 if (isakmp_cfg_config.grouplist != NULL) {
1735 for (i = 0; i < isakmp_cfg_config.groupcount; i++)
1736 racoon_free(isakmp_cfg_config.grouplist[i]);
1737 racoon_free(isakmp_cfg_config.grouplist);
1738 }
1739 }
1740 isakmp_cfg_config.grouplist = NULL;
1741 isakmp_cfg_config.groupcount = 0;
1742 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
1743 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
1744 isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
1745 strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
1746 sizeof(isakmp_cfg_config.default_domain));
1747 strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd));
1748
1749 if (cold != ISAKMP_CFG_INIT_COLD )
1750 if (isakmp_cfg_config.splitnet_list != NULL)
1751 splitnet_list_free(isakmp_cfg_config.splitnet_list,
1752 &isakmp_cfg_config.splitnet_count);
1753 isakmp_cfg_config.splitnet_list = NULL;
1754 isakmp_cfg_config.splitnet_count = 0;
1755 isakmp_cfg_config.splitnet_type = 0;
1756
1757 isakmp_cfg_config.pfs_group = 0;
1758 isakmp_cfg_config.save_passwd = 0;
1759
1760 if (cold != ISAKMP_CFG_INIT_COLD )
1761 if (isakmp_cfg_config.splitdns_list != NULL)
1762 racoon_free(isakmp_cfg_config.splitdns_list);
1763 isakmp_cfg_config.splitdns_list = NULL;
1764 isakmp_cfg_config.splitdns_len = 0;
1765
1766 #if 0
1767 if (cold == ISAKMP_CFG_INIT_COLD) {
1768 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
1769 return error;
1770 }
1771 #endif
1772
1773 return 0;
1774 }
1775