]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/isakmp_cfg.c
ipsec-332.100.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 "nattraversal.h"
103
104 struct isakmp_cfg_config isakmp_cfg_config;
105
106 static vchar_t *buffer_cat (vchar_t *s, vchar_t *append);
107 static vchar_t *isakmp_cfg_net (phase1_handle_t *, struct isakmp_data *);
108 #if 0
109 static vchar_t *isakmp_cfg_void (phase1_handle_t *, struct isakmp_data *);
110 #endif
111 static vchar_t *isakmp_cfg_addr4 (phase1_handle_t *,
112 struct isakmp_data *, in_addr_t *);
113 static void isakmp_cfg_getaddr4 (struct isakmp_data *, struct in_addr *);
114 static vchar_t *isakmp_cfg_addr4_list (phase1_handle_t *,
115 struct isakmp_data *, in_addr_t *, int);
116 static void isakmp_cfg_appendaddr4 (struct isakmp_data *,
117 struct in_addr *, int *, int);
118 static void isakmp_cfg_getstring (struct isakmp_data *,char *);
119 void isakmp_cfg_iplist_to_str (char *, int, void *, int);
120
121 #define ISAKMP_CFG_LOGIN 1
122 #define ISAKMP_CFG_LOGOUT 2
123
124 /*
125 * Handle an ISAKMP config mode packet
126 * We expect HDR, HASH, ATTR
127 */
128 void
129 isakmp_cfg_r(iph1, msg)
130 phase1_handle_t *iph1;
131 vchar_t *msg;
132 {
133 struct isakmp *packet;
134 struct isakmp_gen *ph;
135 int tlen;
136 char *npp;
137 int np;
138 vchar_t *dmsg;
139 struct isakmp_ivm *ivm;
140 phase2_handle_t *iph2;
141 int error = -1;
142
143 /* Check that the packet is long enough to have a header */
144 if (msg->l < sizeof(*packet)) {
145 plog(ASL_LEVEL_ERR, "Unexpected short packet\n");
146 return;
147 }
148
149 packet = (struct isakmp *)msg->v;
150
151 /* Is it encrypted? It should be encrypted */
152 if ((packet->flags & ISAKMP_FLAG_E) == 0) {
153 plog(ASL_LEVEL_ERR,
154 "User credentials sent in cleartext!\n");
155 return;
156 }
157
158 /*
159 * Decrypt the packet. If this is the beginning of a new
160 * exchange, reinitialize the IV
161 */
162 if (iph1->mode_cfg->ivm == NULL ||
163 iph1->mode_cfg->last_msgid != packet->msgid )
164 iph1->mode_cfg->ivm =
165 isakmp_cfg_newiv(iph1, packet->msgid);
166 ivm = iph1->mode_cfg->ivm;
167
168 dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
169 if (dmsg == NULL) {
170 plog(ASL_LEVEL_ERR,
171 "failed to decrypt message\n");
172 return;
173 }
174
175 plog(ASL_LEVEL_NOTICE, "MODE_CFG packet\n");
176
177 /* Now work with the decrypted packet */
178 packet = (struct isakmp *)dmsg->v;
179 tlen = dmsg->l - sizeof(*packet);
180 ph = (struct isakmp_gen *)(packet + 1);
181
182 np = packet->np;
183 while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
184 /* Check that the payload header fits in the packet */
185 if (tlen < sizeof(*ph)) {
186 plog(ASL_LEVEL_WARNING,
187 "Short payload header\n");
188 goto out;
189 }
190
191 /* Check that the payload fits in the packet */
192 if (tlen < ntohs(ph->len)) {
193 plog(ASL_LEVEL_WARNING,
194 "Short payload\n");
195 goto out;
196 }
197
198 plog(ASL_LEVEL_DEBUG, "Seen payload %d\n", np);
199
200 switch(np) {
201 case ISAKMP_NPTYPE_HASH: {
202 vchar_t *check;
203 vchar_t *payload;
204 size_t plen;
205 struct isakmp_gen *nph;
206
207 plen = ntohs(ph->len);
208 nph = (struct isakmp_gen *)((char *)ph + plen);
209 plen = ntohs(nph->len);
210 /* Check that the hash payload fits in the packet */
211 if (tlen < (plen + ntohs(ph->len))) {
212 plog(ASL_LEVEL_WARNING,
213 "Invalid Hash payload. len %d, overall-len %d\n",
214 ntohs(nph->len),
215 (int)plen);
216 goto out;
217 }
218
219 if ((payload = vmalloc(plen)) == NULL) {
220 plog(ASL_LEVEL_ERR,
221 "Cannot allocate memory\n");
222 goto out;
223 }
224 memcpy(payload->v, nph, plen);
225
226 if ((check = oakley_compute_hash1(iph1,
227 packet->msgid, payload)) == NULL) {
228 plog(ASL_LEVEL_ERR,
229 "Cannot compute hash\n");
230 vfree(payload);
231 goto out;
232 }
233
234 if (timingsafe_bcmp(ph + 1, check->v, check->l) != 0) {
235 plog(ASL_LEVEL_ERR,
236 "Hash verification failed\n");
237 vfree(payload);
238 vfree(check);
239 goto out;
240 }
241 vfree(payload);
242 vfree(check);
243 break;
244 }
245 case ISAKMP_NPTYPE_ATTR: {
246 struct isakmp_pl_attr *attrpl;
247
248 attrpl = (struct isakmp_pl_attr *)ph;
249 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl, msg);
250
251 break;
252 }
253 default:
254 plog(ASL_LEVEL_WARNING,
255 "Unexpected next payload %d\n", np);
256 /* Skip to the next payload */
257 break;
258 }
259
260 /* Move to the next payload */
261 np = ph->np;
262 tlen -= ntohs(ph->len);
263 npp = (char *)ph;
264 ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
265 }
266
267 error = 0;
268 /* find phase 2 in case pkt scheduled for resend */
269 iph2 = ike_session_getph2bymsgid(iph1, packet->msgid);
270 if (iph2 == NULL)
271 goto out; /* no resend scheduled */
272 SCHED_KILL(iph2->scr); /* turn off schedule */
273 ike_session_unlink_phase2(iph2);
274 out:
275 vfree(dmsg);
276 }
277
278 int
279 isakmp_cfg_attr_r(iph1, msgid, attrpl, msg)
280 phase1_handle_t *iph1;
281 u_int32_t msgid;
282 struct isakmp_pl_attr *attrpl;
283 vchar_t *msg;
284 {
285 int type = attrpl->type;
286
287 plog(ASL_LEVEL_NOTICE,
288 "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
289 switch (type) {
290 case ISAKMP_CFG_ACK:
291 /* ignore, but this is the time to reinit the IV */
292 oakley_delivm(iph1->mode_cfg->ivm);
293 iph1->mode_cfg->ivm = NULL;
294 return 0;
295 break;
296
297 case ISAKMP_CFG_REPLY:
298 return isakmp_cfg_reply(iph1, attrpl);
299 break;
300
301 case ISAKMP_CFG_REQUEST:
302 iph1->msgid = msgid;
303 return isakmp_cfg_request(iph1, attrpl, msg);
304 break;
305
306 case ISAKMP_CFG_SET:
307 iph1->msgid = msgid;
308 return isakmp_cfg_set(iph1, attrpl, msg);
309 break;
310
311 default:
312 plog(ASL_LEVEL_WARNING,
313 "Unepected configuration exchange type %d\n", type);
314 return -1;
315 break;
316 }
317
318 return 0;
319 }
320
321 int
322 isakmp_cfg_reply(iph1, attrpl)
323 phase1_handle_t *iph1;
324 struct isakmp_pl_attr *attrpl;
325 {
326 struct isakmp_data *attr;
327 int tlen;
328 size_t alen;
329 char *npp;
330 int type;
331 int error;
332
333 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_REPLY)
334 return 0; /* already received this - duplicate packet */
335
336 tlen = ntohs(attrpl->h.len);
337 attr = (struct isakmp_data *)(attrpl + 1);
338 tlen -= sizeof(*attrpl);
339
340 while (tlen > 0) {
341 if (tlen < sizeof(struct isakmp_data)) {
342 plog(ASL_LEVEL_ERR,
343 "isakmp_cfg_reply invalid length of isakmp data, expected %zu actual %d\n",
344 sizeof(struct isakmp_data), tlen);
345 return -1;
346 }
347 type = ntohs(attr->type);
348
349 /* Handle short attributes */
350 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
351 type &= ~ISAKMP_GEN_MASK;
352
353 plog(ASL_LEVEL_DEBUG,
354 "Short attribute %s = %d\n",
355 s_isakmp_cfg_type(type), ntohs(attr->lorv));
356
357 switch (type) {
358 case XAUTH_TYPE:
359 if ((error = xauth_attr_reply(iph1,
360 attr, ntohs(attrpl->id))) != 0)
361 return error;
362 break;
363
364 break;
365
366 default:
367 plog(ASL_LEVEL_WARNING,
368 "Ignored short attribute %s\n",
369 s_isakmp_cfg_type(type));
370 break;
371 }
372
373 tlen -= sizeof(*attr);
374 attr++;
375 continue;
376 }
377
378 type = ntohs(attr->type);
379 alen = ntohs(attr->lorv);
380
381 /* Check that the attribute fit in the packet */
382 if (tlen < (alen + sizeof(struct isakmp_data))) {
383 plog(ASL_LEVEL_ERR,
384 "Short attribute %s len %zu\n",
385 s_isakmp_cfg_type(type), alen);
386 return -1;
387 }
388
389 plog(ASL_LEVEL_DEBUG,
390 "Attribute %s, len %zu\n",
391 s_isakmp_cfg_type(type), alen);
392
393 switch(type) {
394 case XAUTH_TYPE:
395 case XAUTH_USER_NAME:
396 case XAUTH_USER_PASSWORD:
397 case XAUTH_PASSCODE:
398 case XAUTH_MESSAGE:
399 case XAUTH_CHALLENGE:
400 case XAUTH_DOMAIN:
401 case XAUTH_STATUS:
402 case XAUTH_NEXT_PIN:
403 case XAUTH_ANSWER:
404 if ((error = xauth_attr_reply(iph1,
405 attr, ntohs(attrpl->id))) != 0)
406 return error;
407 break;
408 case INTERNAL_IP4_ADDRESS:
409 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) == 0) {
410 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
411 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
412 }
413 break;
414 case INTERNAL_IP4_NETMASK:
415 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) == 0) {
416 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
417 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
418 }
419 break;
420 case INTERNAL_IP4_DNS:
421 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) == 0) {
422 isakmp_cfg_appendaddr4(attr,
423 &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
424 &iph1->mode_cfg->dns4_index, MAXNS);
425 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
426 }
427 break;
428 case INTERNAL_IP4_NBNS:
429 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) == 0) {
430 isakmp_cfg_appendaddr4(attr,
431 &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
432 &iph1->mode_cfg->wins4_index, MAXNS);
433 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
434 }
435 break;
436 case UNITY_DEF_DOMAIN:
437 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) == 0) {
438 isakmp_cfg_getstring(attr,
439 iph1->mode_cfg->default_domain);
440 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
441 }
442 break;
443 case UNITY_SPLIT_INCLUDE:
444 case UNITY_LOCAL_LAN:
445 case UNITY_SPLITDNS_NAME:
446 case UNITY_BANNER:
447 case UNITY_SAVE_PASSWD:
448 case UNITY_NATT_PORT:
449 case UNITY_FW_TYPE:
450 case UNITY_BACKUP_SERVERS:
451 case UNITY_DDNS_HOSTNAME:
452 case APPLICATION_VERSION:
453 case UNITY_PFS:
454 isakmp_unity_reply(iph1, attr);
455 break;
456 case INTERNAL_IP4_SUBNET:
457 case INTERNAL_ADDRESS_EXPIRY:
458 if (iph1->started_by_api)
459 break; /* not actually ignored - don't fall thru */
460 // else fall thru
461 default:
462 plog(ASL_LEVEL_WARNING,
463 "Ignored attribute %s\n",
464 s_isakmp_cfg_type(type));
465 break;
466 }
467
468 npp = (char *)attr;
469 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
470 tlen -= (sizeof(*attr) + alen);
471 }
472 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_REPLY;
473
474 if (iph1->started_by_api || (iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client)) {
475 /* connection was started by API - save attr list for passing to VPN controller */
476 if (iph1->mode_cfg->attr_list != NULL) /* shouldn't happen */
477 vfree(iph1->mode_cfg->attr_list);
478 if (ntohs(attrpl->h.len) < sizeof(*attrpl)) {
479 plog(ASL_LEVEL_ERR,
480 "invalid cfg-attr-list, attr-len %d\n",
481 ntohs(attrpl->h.len));
482 return -1;
483 }
484 alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
485 if ((iph1->mode_cfg->attr_list = vmalloc(alen)) == NULL) {
486 plog(ASL_LEVEL_ERR,
487 "Cannot allocate memory for mode-cfg attribute list\n");
488 return -1;
489 }
490 memcpy(iph1->mode_cfg->attr_list->v, attrpl + 1, alen);
491 }
492
493
494 #ifdef ENABLE_VPNCONTROL_PORT
495 if (FSM_STATE_IS_ESTABLISHED(iph1->status))
496 vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
497 #endif
498
499 return 0;
500 }
501
502 int
503 isakmp_cfg_request(iph1, attrpl, msg)
504 phase1_handle_t *iph1;
505 struct isakmp_pl_attr *attrpl;
506 vchar_t *msg;
507 {
508 struct isakmp_data *attr;
509 int tlen;
510 size_t alen;
511 char *npp;
512 vchar_t *payload = NULL;
513 struct isakmp_pl_attr *reply;
514 vchar_t *reply_attr;
515 int type;
516 int error = -1;
517
518 tlen = ntohs(attrpl->h.len);
519 attr = (struct isakmp_data *)(attrpl + 1);
520 tlen -= sizeof(*attrpl);
521
522 /*
523 * if started_by_api then we are a VPN client and if we receive
524 * a mode-cfg request it needs to go to the VPN controller to
525 * retrieve the appropriate data (name, pw, pin, etc.)
526 */
527 if (iph1->started_by_api || ike_session_is_client_ph1_rekey(iph1)) {
528 /*
529 * if we already received this one - ignore it
530 * we are waiting for a reply from the vpn control socket
531 */
532 if (iph1->xauth_awaiting_userinput)
533 return 0;
534
535 /* otherwise - save the msg id and call and send the status notification */
536 iph1->pended_xauth_id = attrpl->id; /* network byte order */
537 if (vpncontrol_notify_need_authinfo(iph1, attrpl + 1, tlen))
538 goto end;
539 iph1->xauth_awaiting_userinput = 1;
540 iph1->xauth_awaiting_userinput_msg = vdup(msg); // dup the message for later
541 ike_session_start_xauth_timer(iph1);
542
543 IPSECLOGASLMSG("IPSec Extended Authentication requested.\n");
544
545 return 0;
546 }
547
548 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
549 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
550 return -1;
551 }
552 memset(payload->v, 0, sizeof(*reply));
553
554 while (tlen > 0) {
555 if (tlen < sizeof(struct isakmp_data)) {
556 plog(ASL_LEVEL_ERR,
557 "isakmp_cfg_request invalid length of isakmp data, expected %zu actual %d\n",
558 sizeof(struct isakmp_data), tlen);
559 goto end;
560 }
561 reply_attr = NULL;
562 type = ntohs(attr->type);
563
564 /* Handle short attributes */
565 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
566 type &= ~ISAKMP_GEN_MASK;
567
568 plog(ASL_LEVEL_DEBUG,
569 "Short attribute %s = %d\n",
570 s_isakmp_cfg_type(type), ntohs(attr->lorv));
571
572 switch (type) {
573 case XAUTH_TYPE:
574 reply_attr = isakmp_xauth_req(iph1, attr);
575 break;
576 default:
577 plog(ASL_LEVEL_WARNING,
578 "Ignored short attribute %s\n",
579 s_isakmp_cfg_type(type));
580 break;
581 }
582
583 tlen -= sizeof(*attr);
584 attr++;
585
586 if (reply_attr != NULL) {
587 payload = buffer_cat(payload, reply_attr);
588 vfree(reply_attr);
589 }
590
591 continue;
592 }
593
594 type = ntohs(attr->type);
595 alen = ntohs(attr->lorv);
596
597 /* Check that the attribute fit in the packet */
598 if (tlen < (sizeof(struct isakmp_data) + alen)) {
599 plog(ASL_LEVEL_ERR,
600 "Short attribute %s len %zu\n",
601 s_isakmp_cfg_type(type), alen);
602 goto end;
603 }
604
605 plog(ASL_LEVEL_DEBUG,
606 "Attribute %s, len %zu\n",
607 s_isakmp_cfg_type(type), alen);
608
609 switch(type) {
610 case INTERNAL_IP4_ADDRESS:
611 case INTERNAL_IP4_NETMASK:
612 case INTERNAL_IP4_DNS:
613 case INTERNAL_IP4_NBNS:
614 case INTERNAL_IP4_SUBNET:
615 reply_attr = isakmp_cfg_net(iph1, attr);
616 break;
617
618 case XAUTH_TYPE:
619 case XAUTH_USER_NAME:
620 case XAUTH_USER_PASSWORD:
621 case XAUTH_PASSCODE:
622 case XAUTH_MESSAGE:
623 case XAUTH_CHALLENGE:
624 case XAUTH_DOMAIN:
625 case XAUTH_STATUS:
626 case XAUTH_NEXT_PIN:
627 case XAUTH_ANSWER:
628 reply_attr = isakmp_xauth_req(iph1, attr);
629 break;
630
631 case APPLICATION_VERSION:
632 reply_attr = isakmp_cfg_string(iph1,
633 attr, ISAKMP_CFG_RACOON_VERSION);
634 break;
635
636 case UNITY_BANNER:
637 case UNITY_PFS:
638 case UNITY_SAVE_PASSWD:
639 case UNITY_DEF_DOMAIN:
640 case UNITY_DDNS_HOSTNAME:
641 case UNITY_FW_TYPE:
642 case UNITY_SPLITDNS_NAME:
643 case UNITY_SPLIT_INCLUDE:
644 case UNITY_LOCAL_LAN:
645 case UNITY_NATT_PORT:
646 case UNITY_BACKUP_SERVERS:
647 reply_attr = isakmp_unity_req(iph1, attr);
648 break;
649
650 case INTERNAL_ADDRESS_EXPIRY:
651 default:
652 plog(ASL_LEVEL_WARNING,
653 "Ignored attribute %s\n",
654 s_isakmp_cfg_type(type));
655 break;
656 }
657
658 npp = (char *)attr;
659 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
660 tlen -= (sizeof(*attr) + alen);
661
662 if (reply_attr != NULL) {
663 payload = buffer_cat(payload, reply_attr);
664 vfree(reply_attr);
665 }
666 }
667
668 reply = (struct isakmp_pl_attr *)payload->v;
669 reply->h.len = htons(payload->l);
670 reply->type = ISAKMP_CFG_REPLY;
671 reply->id = attrpl->id;
672
673 plog(ASL_LEVEL_NOTICE,
674 "Sending MODE_CFG REPLY\n");
675
676 error = isakmp_cfg_send(iph1, payload,
677 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
678
679
680 end:
681 vfree(payload);
682
683 return error;
684 }
685
686 int
687 isakmp_cfg_set(iph1, attrpl, msg)
688 phase1_handle_t *iph1;
689 struct isakmp_pl_attr *attrpl;
690 vchar_t *msg;
691 {
692 struct isakmp_data *attr;
693 int tlen;
694 size_t alen;
695 char *npp;
696 vchar_t *payload;
697 struct isakmp_pl_attr *reply;
698 vchar_t *reply_attr;
699 int type;
700 int error = -1;
701
702 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
703 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
704 return -1;
705 }
706 memset(payload->v, 0, sizeof(*reply));
707
708 tlen = ntohs(attrpl->h.len);
709 attr = (struct isakmp_data *)(attrpl + 1);
710 tlen -= sizeof(*attrpl);
711
712 /*
713 * We should send ack for the attributes we accepted
714 */
715 while (tlen > 0) {
716 if (tlen < sizeof(struct isakmp_data)) {
717 plog(ASL_LEVEL_ERR,
718 "isakmp_cfg_set invalid length of isakmp data, expected %zu actual %d\n",
719 sizeof(struct isakmp_data), tlen);
720 vfree(payload);
721 return error;
722 }
723 reply_attr = NULL;
724 type = ntohs(attr->type);
725
726 plog(ASL_LEVEL_DEBUG,
727 "Attribute %s\n",
728 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
729
730 switch (type & ~ISAKMP_GEN_MASK) {
731 case XAUTH_STATUS:
732 reply_attr = isakmp_xauth_set(iph1, attr);
733 break;
734 default:
735 plog(ASL_LEVEL_DEBUG,
736 "Unexpected SET attribute %s\n",
737 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
738 break;
739 }
740
741 if (reply_attr != NULL) {
742 payload = buffer_cat(payload, reply_attr);
743 vfree(reply_attr);
744 }
745
746 /*
747 * Move to next attribute. If we run out of the packet,
748 * tlen becomes negative and we exit.
749 */
750 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
751 tlen -= sizeof(*attr);
752 attr++;
753 } else {
754 alen = ntohs(attr->lorv);
755 if (tlen < (sizeof(*attr) + alen)) {
756 plog(ASL_LEVEL_ERR,
757 "isakmp_cfg_set packet too short for type %d, expected %zu actual %zu\n",
758 type, alen, tlen - sizeof(*attr));
759 vfree(payload);
760 return error;
761 }
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_NOTICE,
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_NOTICE, "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 error = 0;
1292 goto end;
1293 }
1294
1295 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1296 plog(ASL_LEVEL_ERR,
1297 "failed to send packet");
1298 VPTRINIT(iph2->sendbuf);
1299 goto err;
1300 }
1301 if (msg) {
1302 /* the sending message is added to the received-list. */
1303 if (ike_session_add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg,
1304 PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH1_FRAG_FLAGS(iph1)) == -1) {
1305 plog(ASL_LEVEL_ERR ,
1306 "failed to add a response packet to the tree.\n");
1307 }
1308 }
1309
1310 plog(ASL_LEVEL_NOTICE,
1311 "sendto mode config %s.\n", s_isakmp_nptype(np));
1312
1313 /*
1314 * XXX We might need to resend the message...
1315 */
1316
1317 error = 0;
1318 VPTRINIT(iph2->sendbuf);
1319 err:
1320 ike_session_unlink_phase2(iph2);
1321 end:
1322 if (hash)
1323 vfree(hash);
1324 return error;
1325 }
1326
1327
1328 void
1329 isakmp_cfg_rmstate(phase1_handle_t *iph1)
1330 {
1331 struct isakmp_cfg_state **state = &iph1->mode_cfg;
1332
1333 if (*state == NULL)
1334 return;
1335
1336 if ((*state)->flags & ISAKMP_CFG_PORT_ALLOCATED)
1337 isakmp_cfg_putport(iph1, (*state)->port);
1338
1339 /* Delete the IV if it's still there */
1340 if((*state)->ivm) {
1341 oakley_delivm((*state)->ivm);
1342 (*state)->ivm = NULL;
1343 }
1344
1345 /* Free any allocated splitnet lists */
1346 if((*state)->split_include != NULL)
1347 splitnet_list_free((*state)->split_include,
1348 &(*state)->include_count);
1349 if((*state)->split_local != NULL)
1350 splitnet_list_free((*state)->split_local,
1351 &(*state)->local_count);
1352
1353 xauth_rmstate(&(*state)->xauth);
1354
1355 if ((*state)->attr_list)
1356 vfree((*state)->attr_list);
1357
1358 racoon_free((*state));
1359 (*state) = NULL;
1360
1361 return;
1362 }
1363
1364 struct isakmp_cfg_state *
1365 isakmp_cfg_mkstate(void)
1366 {
1367 struct isakmp_cfg_state *state;
1368
1369 if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1370 plog(ASL_LEVEL_ERR,
1371 "Cannot allocate memory for mode config state\n");
1372 return NULL;
1373 }
1374 memset(state, 0, sizeof(*state));
1375
1376 return state;
1377 }
1378
1379 int
1380 isakmp_cfg_getport(iph1)
1381 phase1_handle_t *iph1;
1382 {
1383 unsigned int i;
1384 size_t size = isakmp_cfg_config.pool_size;
1385
1386 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1387 return iph1->mode_cfg->port;
1388
1389 if (isakmp_cfg_config.port_pool == NULL) {
1390 plog(ASL_LEVEL_ERR,
1391 "isakmp_cfg_config.port_pool == NULL\n");
1392 return -1;
1393 }
1394
1395 for (i = 0; i < size; i++) {
1396 if (isakmp_cfg_config.port_pool[i].used == 0)
1397 break;
1398 }
1399
1400 if (i == size) {
1401 plog(ASL_LEVEL_ERR,
1402 "No more addresses available\n");
1403 return -1;
1404 }
1405
1406 isakmp_cfg_config.port_pool[i].used = 1;
1407
1408 plog(ASL_LEVEL_NOTICE, "Using port %d\n", i);
1409
1410 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1411 iph1->mode_cfg->port = i;
1412
1413 return i;
1414 }
1415
1416 int
1417 isakmp_cfg_putport(iph1, index)
1418 phase1_handle_t *iph1;
1419 unsigned int index;
1420 {
1421 if (isakmp_cfg_config.port_pool == NULL) {
1422 plog(ASL_LEVEL_ERR,
1423 "isakmp_cfg_config.port_pool == NULL\n");
1424 return -1;
1425 }
1426
1427 if (isakmp_cfg_config.port_pool[index].used == 0) {
1428 plog(ASL_LEVEL_ERR,
1429 "Attempt to release an unallocated address (port %d)\n",
1430 index);
1431 return -1;
1432 }
1433
1434 isakmp_cfg_config.port_pool[index].used = 0;
1435 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1436
1437 plog(ASL_LEVEL_NOTICE, "Released port %d\n", index);
1438
1439 return 0;
1440 }
1441
1442
1443 int
1444 isakmp_cfg_getconfig(iph1)
1445 phase1_handle_t *iph1;
1446 {
1447 vchar_t *buffer;
1448 struct isakmp_pl_attr *attrpl;
1449 struct isakmp_data *attr;
1450 size_t len;
1451 vchar_t *version = NULL;
1452 int error;
1453 int attrcount;
1454 int i;
1455 int attrlist[] = {
1456 INTERNAL_IP4_ADDRESS,
1457 INTERNAL_IP4_NETMASK,
1458 INTERNAL_IP4_DNS,
1459 INTERNAL_IP4_NBNS,
1460 INTERNAL_ADDRESS_EXPIRY,
1461 APPLICATION_VERSION,
1462 UNITY_BANNER,
1463 UNITY_DEF_DOMAIN,
1464 UNITY_SPLITDNS_NAME,
1465 UNITY_SPLIT_INCLUDE,
1466 UNITY_LOCAL_LAN,
1467 };
1468
1469 attrcount = sizeof(attrlist) / sizeof(*attrlist);
1470 len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1471
1472 if (iph1->started_by_api) {
1473 if (iph1->remote->ss_family == AF_INET) {
1474 struct vpnctl_socket_elem *sock_elem;
1475 struct bound_addr *bound_addr;
1476 u_int32_t address;
1477
1478 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
1479 LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
1480 LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
1481 if (bound_addr->address == address) {
1482 if ((version = bound_addr->version))
1483 len += bound_addr->version->l;
1484 break;
1485 }
1486 }
1487 }
1488 }
1489 }
1490
1491 if ((buffer = vmalloc(len)) == NULL) {
1492 plog(ASL_LEVEL_ERR, "Cannot allocate memory\n");
1493 return -1;
1494 }
1495
1496 attrpl = (struct isakmp_pl_attr *)buffer->v;
1497 attrpl->h.len = htons(len);
1498 attrpl->type = ISAKMP_CFG_REQUEST;
1499 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1500
1501 attr = (struct isakmp_data *)(attrpl + 1);
1502
1503 for (i = 0; i < attrcount; i++) {
1504 switch (attrlist[i]) {
1505 case APPLICATION_VERSION:
1506 if (version) {
1507 attr->type = htons(attrlist[i]);
1508 attr->lorv = htons(version->l);
1509 memcpy(attr + 1, version->v, version->l);
1510 attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l);
1511 break;
1512 } else /* fall thru */;
1513 default:
1514 attr->type = htons(attrlist[i]);
1515 attr->lorv = htons(0);
1516 attr++;
1517 break;
1518 }
1519 }
1520
1521 plog(ASL_LEVEL_NOTICE,
1522 "Sending MODE_CFG REQUEST\n");
1523
1524 error = isakmp_cfg_send(iph1, buffer,
1525 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL);
1526
1527 vfree(buffer);
1528
1529 IPSECLOGASLMSG("IPSec Network Configuration requested.\n");
1530
1531 return error;
1532 }
1533
1534 static void
1535 isakmp_cfg_getaddr4(attr, ip)
1536 struct isakmp_data *attr;
1537 struct in_addr *ip;
1538 {
1539 size_t alen = ntohs(attr->lorv);
1540 in_addr_t *addr;
1541
1542 if (alen != sizeof(*ip)) {
1543 plog(ASL_LEVEL_ERR, "Bad IPv4 address len\n");
1544 return;
1545 }
1546
1547 addr = ALIGNED_CAST(in_addr_t *)(attr + 1); // Wcast-align fix (void*) - attr comes from packet data in a vchar_t
1548 ip->s_addr = *addr;
1549
1550 return;
1551 }
1552
1553 static void
1554 isakmp_cfg_appendaddr4(attr, ip, num, max)
1555 struct isakmp_data *attr;
1556 struct in_addr *ip;
1557 int *num;
1558 int max;
1559 {
1560 size_t alen = ntohs(attr->lorv);
1561 in_addr_t *addr;
1562
1563 if (alen != sizeof(*ip)) {
1564 plog(ASL_LEVEL_ERR, "Bad IPv4 address len\n");
1565 return;
1566 }
1567 if (*num == max) {
1568 plog(ASL_LEVEL_ERR, "Too many addresses given\n");
1569 return;
1570 }
1571
1572 addr = ALIGNED_CAST(in_addr_t *)(attr + 1); // Wcast-align fix (void*) - attr comes from packet data in a vchar_t
1573 ip->s_addr = *addr;
1574 (*num)++;
1575
1576 return;
1577 }
1578
1579 static void
1580 isakmp_cfg_getstring(attr, str)
1581 struct isakmp_data *attr;
1582 char *str;
1583 {
1584 size_t alen = ntohs(attr->lorv);
1585 char *src;
1586 src = (char *)(attr + 1);
1587
1588 memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
1589
1590 return;
1591 }
1592
1593 #define IP_MAX 40
1594
1595 void
1596 isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
1597 char *dest;
1598 int count;
1599 void *addr;
1600 int withmask;
1601 {
1602 int i;
1603 int p;
1604 int l;
1605 struct unity_network tmp;
1606 for(i = 0, p = 0; i < count; i++) {
1607 if(withmask == 1)
1608 l = sizeof(struct unity_network);
1609 else
1610 l = sizeof(struct in_addr);
1611 memcpy(&tmp, addr, l);
1612 addr += l;
1613 if((uint32_t)tmp.addr4.s_addr == 0)
1614 break;
1615
1616 inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
1617 p += strlen(dest + p);
1618 if(withmask == 1) {
1619 dest[p] = '/';
1620 p++;
1621 inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
1622 p += strlen(dest + p);
1623 }
1624 dest[p] = ' ';
1625 p++;
1626 }
1627 if(p > 0)
1628 dest[p-1] = '\0';
1629 else
1630 dest[0] = '\0';
1631 }
1632
1633 int
1634 isakmp_cfg_resize_pool(size)
1635 int size;
1636 {
1637 struct isakmp_cfg_port *new_pool;
1638 size_t len;
1639 int i;
1640
1641 if (size == isakmp_cfg_config.pool_size)
1642 return 0;
1643
1644 plog(ASL_LEVEL_NOTICE,
1645 "Resize address pool from %zu to %d\n",
1646 isakmp_cfg_config.pool_size, size);
1647
1648 /* If a pool already exists, check if we can shrink it */
1649 if ((isakmp_cfg_config.port_pool != NULL) &&
1650 (size < isakmp_cfg_config.pool_size)) {
1651 for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
1652 if (isakmp_cfg_config.port_pool[i].used) {
1653 plog(ASL_LEVEL_ERR,
1654 "resize pool from %zu to %d impossible "
1655 "port %d is in use\n",
1656 isakmp_cfg_config.pool_size, size, i);
1657 size = i;
1658 break;
1659 }
1660 }
1661 }
1662
1663 len = size * sizeof(*isakmp_cfg_config.port_pool);
1664 new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
1665 if (new_pool == NULL) {
1666 plog(ASL_LEVEL_ERR,
1667 "resize pool from %zu to %d impossible: %s",
1668 isakmp_cfg_config.pool_size, size, strerror(errno));
1669 return -1;
1670 }
1671
1672 /* If size increase, intialize correctly the new records */
1673 if (size > isakmp_cfg_config.pool_size) {
1674 size_t unit;
1675 size_t old_size;
1676
1677 unit = sizeof(*isakmp_cfg_config.port_pool);
1678 old_size = isakmp_cfg_config.pool_size;
1679
1680 bzero((char *)new_pool + (old_size * unit),
1681 (size - old_size) * unit);
1682 }
1683
1684 isakmp_cfg_config.port_pool = new_pool;
1685 isakmp_cfg_config.pool_size = size;
1686
1687 return 0;
1688 }
1689
1690 int
1691 isakmp_cfg_init(cold)
1692 int cold;
1693 {
1694 int i;
1695 #if 0
1696 int error;
1697 #endif
1698
1699 isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
1700 isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
1701 for (i = 0; i < MAXNS; i++)
1702 isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
1703 isakmp_cfg_config.dns4_index = 0;
1704 for (i = 0; i < MAXWINS; i++)
1705 isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
1706 isakmp_cfg_config.nbns4_index = 0;
1707 if (cold != ISAKMP_CFG_INIT_COLD) {
1708 if (isakmp_cfg_config.port_pool) {
1709 racoon_free(isakmp_cfg_config.port_pool);
1710 }
1711 }
1712 isakmp_cfg_config.port_pool = NULL;
1713 isakmp_cfg_config.pool_size = 0;
1714 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
1715 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
1716 if (cold != ISAKMP_CFG_INIT_COLD) {
1717 if (isakmp_cfg_config.grouplist != NULL) {
1718 for (i = 0; i < isakmp_cfg_config.groupcount; i++)
1719 racoon_free(isakmp_cfg_config.grouplist[i]);
1720 racoon_free(isakmp_cfg_config.grouplist);
1721 }
1722 }
1723 isakmp_cfg_config.grouplist = NULL;
1724 isakmp_cfg_config.groupcount = 0;
1725 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
1726 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
1727 isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
1728 strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
1729 sizeof(isakmp_cfg_config.default_domain));
1730 strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd));
1731
1732 if (cold != ISAKMP_CFG_INIT_COLD )
1733 if (isakmp_cfg_config.splitnet_list != NULL)
1734 splitnet_list_free(isakmp_cfg_config.splitnet_list,
1735 &isakmp_cfg_config.splitnet_count);
1736 isakmp_cfg_config.splitnet_list = NULL;
1737 isakmp_cfg_config.splitnet_count = 0;
1738 isakmp_cfg_config.splitnet_type = 0;
1739
1740 isakmp_cfg_config.pfs_group = 0;
1741 isakmp_cfg_config.save_passwd = 0;
1742
1743 if (cold != ISAKMP_CFG_INIT_COLD )
1744 if (isakmp_cfg_config.splitdns_list != NULL)
1745 racoon_free(isakmp_cfg_config.splitdns_list);
1746 isakmp_cfg_config.splitdns_list = NULL;
1747 isakmp_cfg_config.splitdns_len = 0;
1748
1749 #if 0
1750 if (cold == ISAKMP_CFG_INIT_COLD) {
1751 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
1752 return error;
1753 }
1754 #endif
1755
1756 return 0;
1757 }
1758