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