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