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