]> git.saurik.com Git - apple/ipsec.git/blame_incremental - ipsec-tools/racoon/isakmp_cfg.c
ipsec-93.10.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_cfg.c
... / ...
CommitLineData
1/* $NetBSD: isakmp_cfg.c,v 1.12.6.1 2007/06/07 20:06:34 manu Exp $ */
2
3/* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
4
5/*
6 * Copyright (C) 2004-2006 Emmanuel Dreyfus
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39#include <sys/queue.h>
40
41#include <utmpx.h>
42#if defined(__APPLE__) && defined(__MACH__)
43#include <util.h>
44#endif
45
46#ifdef __FreeBSD__
47# include <libutil.h>
48#endif
49#ifdef __NetBSD__
50# include <util.h>
51#endif
52
53#include <netinet/in.h>
54#include <arpa/inet.h>
55
56#include <stdlib.h>
57#include <stdio.h>
58#include <string.h>
59#include <errno.h>
60#if TIME_WITH_SYS_TIME
61# include <sys/time.h>
62# include <time.h>
63#else
64# if HAVE_SYS_TIME_H
65# include <sys/time.h>
66# else
67# include <time.h>
68# endif
69#endif
70#include <netdb.h>
71#ifdef HAVE_UNISTD_H
72#include <unistd.h>
73#endif
74#if HAVE_STDINT_H
75#include <stdint.h>
76#endif
77#include <ctype.h>
78#include <resolv.h>
79
80#ifdef HAVE_LIBRADIUS
81#include <sys/utsname.h>
82#include <radlib.h>
83#endif
84
85#include "var.h"
86#include "misc.h"
87#include "vmbuf.h"
88#include "plog.h"
89#include "sockmisc.h"
90#include "schedule.h"
91#include "debug.h"
92
93#include "isakmp_var.h"
94#include "isakmp.h"
95#include "handler.h"
96#include "evt.h"
97#include "throttle.h"
98#include "remoteconf.h"
99#include "localconf.h"
100#include "crypto_openssl.h"
101#include "isakmp_inf.h"
102#include "isakmp_xauth.h"
103#include "isakmp_unity.h"
104#include "isakmp_cfg.h"
105#include "strnames.h"
106#include "admin.h"
107#include "privsep.h"
108#include "vpn_control.h"
109#include "vpn_control_var.h"
110#include "ike_session.h"
111#include "ipsecSessionTracer.h"
112#include "ipsecMessageTracer.h"
113#include "nattraversal.h"
114
115struct isakmp_cfg_config isakmp_cfg_config;
116
117static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
118static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
119#if 0
120static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
121#endif
122static vchar_t *isakmp_cfg_addr4(struct ph1handle *,
123 struct isakmp_data *, in_addr_t *);
124static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
125static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
126 struct isakmp_data *, in_addr_t *, int);
127static void isakmp_cfg_appendaddr4(struct isakmp_data *,
128 struct in_addr *, int *, int);
129static void isakmp_cfg_getstring(struct isakmp_data *,char *);
130void isakmp_cfg_iplist_to_str(char *, int, void *, int);
131
132#define ISAKMP_CFG_LOGIN 1
133#define ISAKMP_CFG_LOGOUT 2
134static int isakmp_cfg_accounting(struct ph1handle *, int);
135#ifdef HAVE_LIBRADIUS
136static int isakmp_cfg_accounting_radius(struct ph1handle *, int);
137#endif
138
139/*
140 * Handle an ISAKMP config mode packet
141 * We expect HDR, HASH, ATTR
142 */
143void
144isakmp_cfg_r(iph1, msg)
145 struct ph1handle *iph1;
146 vchar_t *msg;
147{
148 struct isakmp *packet;
149 struct isakmp_gen *ph;
150 int tlen;
151 char *npp;
152 int np;
153 vchar_t *dmsg;
154 struct isakmp_ivm *ivm;
155 struct ph2handle *iph2;
156 int error = -1;
157
158 /* Check that the packet is long enough to have a header */
159 if (msg->l < sizeof(*packet)) {
160 IPSECSESSIONTRACEREVENT(iph1->parent_session,
161 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
162 CONSTSTR("MODE-Config. Unexpected short packet"),
163 CONSTSTR("Failed to process short MODE-Config packet"));
164 plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
165 return;
166 }
167
168 packet = (struct isakmp *)msg->v;
169
170 /* Is it encrypted? It should be encrypted */
171 if ((packet->flags & ISAKMP_FLAG_E) == 0) {
172 IPSECSESSIONTRACEREVENT(iph1->parent_session,
173 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
174 CONSTSTR("MODE-Config. User credentials sent in cleartext"),
175 CONSTSTR("Dropped cleattext User credentials"));
176 plog(LLV_ERROR, LOCATION, NULL,
177 "User credentials sent in cleartext!\n");
178 return;
179 }
180
181 /*
182 * Decrypt the packet. If this is the beginning of a new
183 * exchange, reinitialize the IV
184 */
185 if (iph1->mode_cfg->ivm == NULL ||
186 iph1->mode_cfg->last_msgid != packet->msgid )
187 iph1->mode_cfg->ivm =
188 isakmp_cfg_newiv(iph1, packet->msgid);
189 ivm = iph1->mode_cfg->ivm;
190
191 dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
192 if (dmsg == NULL) {
193 IPSECSESSIONTRACEREVENT(iph1->parent_session,
194 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
195 CONSTSTR("MODE-Config. Failed to decrypt packet"),
196 CONSTSTR("Failed to decrypt MODE-Config packet"));
197 plog(LLV_ERROR, LOCATION, NULL,
198 "failed to decrypt message\n");
199 return;
200 }
201
202 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n");
203 plogdump(LLV_DEBUG, dmsg->v, dmsg->l);
204
205 /* Now work with the decrypted packet */
206 packet = (struct isakmp *)dmsg->v;
207 tlen = dmsg->l - sizeof(*packet);
208 ph = (struct isakmp_gen *)(packet + 1);
209
210 np = packet->np;
211 while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
212 /* Check that the payload header fits in the packet */
213 if (tlen < sizeof(*ph)) {
214 plog(LLV_WARNING, LOCATION, NULL,
215 "Short payload header\n");
216 goto out;
217 }
218
219 /* Check that the payload fits in the packet */
220 if (tlen < ntohs(ph->len)) {
221 plog(LLV_WARNING, LOCATION, NULL,
222 "Short payload\n");
223 goto out;
224 }
225
226 plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np);
227 plogdump(LLV_DEBUG, ph, ntohs(ph->len));
228
229 switch(np) {
230 case ISAKMP_NPTYPE_HASH: {
231 vchar_t *check;
232 vchar_t *payload;
233 size_t plen;
234 struct isakmp_gen *nph;
235
236 plen = ntohs(ph->len);
237 nph = (struct isakmp_gen *)((char *)ph + plen);
238 plen = ntohs(nph->len);
239
240 if ((payload = vmalloc(plen)) == NULL) {
241 plog(LLV_ERROR, LOCATION, NULL,
242 "Cannot allocate memory\n");
243 goto out;
244 }
245 memcpy(payload->v, nph, plen);
246
247 if ((check = oakley_compute_hash1(iph1,
248 packet->msgid, payload)) == NULL) {
249 plog(LLV_ERROR, LOCATION, NULL,
250 "Cannot compute hash\n");
251 vfree(payload);
252 goto out;
253 }
254
255 if (memcmp(ph + 1, check->v, check->l) != 0) {
256 plog(LLV_ERROR, LOCATION, NULL,
257 "Hash verification failed\n");
258 vfree(payload);
259 vfree(check);
260 goto out;
261 }
262 vfree(payload);
263 vfree(check);
264 break;
265 }
266 case ISAKMP_NPTYPE_ATTR: {
267 struct isakmp_pl_attr *attrpl;
268
269 attrpl = (struct isakmp_pl_attr *)ph;
270 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl, msg);
271
272 break;
273 }
274 default:
275 plog(LLV_WARNING, LOCATION, NULL,
276 "Unexpected next payload %d\n", np);
277 /* Skip to the next payload */
278 break;
279 }
280
281 /* Move to the next payload */
282 np = ph->np;
283 tlen -= ntohs(ph->len);
284 npp = (char *)ph;
285 ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
286 }
287
288 error = 0;
289 /* find phase 2 in case pkt scheduled for resend */
290 iph2 = getph2bymsgid(iph1, packet->msgid);
291 if (iph2 == NULL)
292 goto out; /* no resend scheduled */
293 SCHED_KILL(iph2->scr); /* turn off schedule */
294 unbindph12(iph2);
295 remph2(iph2);
296 delph2(iph2);
297
298 IPSECSESSIONTRACEREVENT(iph1->parent_session,
299 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
300 CONSTSTR("MODE-Config"),
301 CONSTSTR(NULL));
302out:
303 if (error) {
304 IPSECSESSIONTRACEREVENT(iph1->parent_session,
305 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
306 CONSTSTR("MODE-Config"),
307 CONSTSTR("Failed to process Mode-Config packet"));
308 }
309 vfree(dmsg);
310}
311
312int
313isakmp_cfg_attr_r(iph1, msgid, attrpl, msg)
314 struct ph1handle *iph1;
315 u_int32_t msgid;
316 struct isakmp_pl_attr *attrpl;
317 vchar_t *msg;
318{
319 int type = attrpl->type;
320
321 plog(LLV_DEBUG, LOCATION, NULL,
322 "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
323 switch (type) {
324 case ISAKMP_CFG_ACK:
325 /* ignore, but this is the time to reinit the IV */
326 oakley_delivm(iph1->mode_cfg->ivm);
327 iph1->mode_cfg->ivm = NULL;
328 return 0;
329 break;
330
331 case ISAKMP_CFG_REPLY:
332 return isakmp_cfg_reply(iph1, attrpl);
333 break;
334
335 case ISAKMP_CFG_REQUEST:
336 iph1->msgid = msgid;
337 return isakmp_cfg_request(iph1, attrpl, msg);
338 break;
339
340 case ISAKMP_CFG_SET:
341 iph1->msgid = msgid;
342 return isakmp_cfg_set(iph1, attrpl, msg);
343 break;
344
345 default:
346 plog(LLV_WARNING, LOCATION, NULL,
347 "Unepected configuration exchange type %d\n", type);
348 return -1;
349 break;
350 }
351
352 return 0;
353}
354
355int
356isakmp_cfg_reply(iph1, attrpl)
357 struct ph1handle *iph1;
358 struct isakmp_pl_attr *attrpl;
359{
360 struct isakmp_data *attr;
361 int tlen;
362 size_t alen;
363 char *npp;
364 int type;
365 int error;
366
367 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_REPLY)
368 return 0; /* already received this - duplicate packet */
369
370 tlen = ntohs(attrpl->h.len);
371 attr = (struct isakmp_data *)(attrpl + 1);
372 tlen -= sizeof(*attrpl);
373
374 while (tlen > 0) {
375 type = ntohs(attr->type);
376
377 /* Handle short attributes */
378 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
379 type &= ~ISAKMP_GEN_MASK;
380
381 plog(LLV_DEBUG, LOCATION, NULL,
382 "Short attribute %s = %d\n",
383 s_isakmp_cfg_type(type), ntohs(attr->lorv));
384
385 switch (type) {
386 case XAUTH_TYPE:
387 if ((error = xauth_attr_reply(iph1,
388 attr, ntohs(attrpl->id))) != 0)
389 return error;
390 break;
391
392 break;
393
394 default:
395 plog(LLV_WARNING, LOCATION, NULL,
396 "Ignored short attribute %s\n",
397 s_isakmp_cfg_type(type));
398 break;
399 }
400
401 tlen -= sizeof(*attr);
402 attr++;
403 continue;
404 }
405
406 type = ntohs(attr->type);
407 alen = ntohs(attr->lorv);
408
409 /* Check that the attribute fit in the packet */
410 if (tlen < alen) {
411 plog(LLV_ERROR, LOCATION, NULL,
412 "Short attribute %s\n",
413 s_isakmp_cfg_type(type));
414 return -1;
415 }
416
417 plog(LLV_DEBUG, LOCATION, NULL,
418 "Attribute %s, len %zu\n",
419 s_isakmp_cfg_type(type), alen);
420
421 switch(type) {
422 case XAUTH_TYPE:
423 case XAUTH_USER_NAME:
424 case XAUTH_USER_PASSWORD:
425 case XAUTH_PASSCODE:
426 case XAUTH_MESSAGE:
427 case XAUTH_CHALLENGE:
428 case XAUTH_DOMAIN:
429 case XAUTH_STATUS:
430 case XAUTH_NEXT_PIN:
431 case XAUTH_ANSWER:
432 if ((error = xauth_attr_reply(iph1,
433 attr, ntohs(attrpl->id))) != 0)
434 return error;
435 break;
436 case INTERNAL_IP4_ADDRESS:
437 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) == 0) {
438 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
439 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
440 }
441 break;
442 case INTERNAL_IP4_NETMASK:
443 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) == 0) {
444 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
445 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
446 }
447 break;
448 case INTERNAL_IP4_DNS:
449 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) == 0) {
450 isakmp_cfg_appendaddr4(attr,
451 &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
452 &iph1->mode_cfg->dns4_index, MAXNS);
453 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
454 }
455 break;
456 case INTERNAL_IP4_NBNS:
457 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) == 0) {
458 isakmp_cfg_appendaddr4(attr,
459 &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
460 &iph1->mode_cfg->wins4_index, MAXNS);
461 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
462 }
463 break;
464 case UNITY_DEF_DOMAIN:
465 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) == 0) {
466 isakmp_cfg_getstring(attr,
467 iph1->mode_cfg->default_domain);
468 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
469 }
470 break;
471 case UNITY_SPLIT_INCLUDE:
472 case UNITY_LOCAL_LAN:
473 case UNITY_SPLITDNS_NAME:
474 case UNITY_BANNER:
475 case UNITY_SAVE_PASSWD:
476 case UNITY_NATT_PORT:
477 case UNITY_FW_TYPE:
478 case UNITY_BACKUP_SERVERS:
479 case UNITY_DDNS_HOSTNAME:
480 case APPLICATION_VERSION:
481 case UNITY_PFS:
482 isakmp_unity_reply(iph1, attr);
483 break;
484 case INTERNAL_IP4_SUBNET:
485 case INTERNAL_ADDRESS_EXPIRY:
486 if (iph1->started_by_api)
487 break; /* not actually ignored - don't fall thru */
488 // else fall thru
489 default:
490 plog(LLV_WARNING, LOCATION, NULL,
491 "Ignored attribute %s\n",
492 s_isakmp_cfg_type(type));
493 break;
494 }
495
496 npp = (char *)attr;
497 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
498 tlen -= (sizeof(*attr) + alen);
499 }
500 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_REPLY;
501
502 if (iph1->started_by_api || (iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client)) {
503 /* connection was started by API - save attr list for passing to VPN controller */
504 if (iph1->mode_cfg->attr_list != NULL) /* shouldn't happen */
505 vfree(iph1->mode_cfg->attr_list);
506 alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
507 if ((iph1->mode_cfg->attr_list = vmalloc(alen)) == NULL) {
508 plog(LLV_ERROR, LOCATION, NULL,
509 "Cannot allocate memory for mode-cfg attribute list\n");
510 return -1;
511 }
512 memcpy(iph1->mode_cfg->attr_list->v, attrpl + 1, alen);
513 }
514
515 /*
516 * Call the SA up script hook now that we have the configuration
517 * It is done at the end of phase 1 if ISAKMP mode config is not
518 * requested.
519 */
520
521 if ((iph1->status == PHASE1ST_ESTABLISHED) &&
522 iph1->rmconf->mode_cfg) {
523 switch (AUTHMETHOD(iph1)) {
524 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
525 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
526 /* Unimplemented */
527 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
528 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
529 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
530 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
531 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
532 script_hook(iph1, SCRIPT_PHASE1_UP);
533 break;
534 default:
535 break;
536 }
537 }
538
539#ifdef ENABLE_VPNCONTROL_PORT
540 if (iph1->status == PHASE1ST_ESTABLISHED)
541 vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
542#endif
543
544#ifdef ENABLE_ADMINPORT
545 {
546 vchar_t *buf;
547
548 alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
549 if ((buf = vmalloc(alen)) == NULL) {
550 plog(LLV_WARNING, LOCATION, NULL,
551 "Cannot allocate memory: %s\n", strerror(errno));
552 } else {
553 memcpy(buf->v, attrpl + 1, buf->l);
554 EVT_PUSH(iph1->local, iph1->remote,
555 EVTT_ISAKMP_CFG_DONE, buf);
556 vfree(buf);
557 }
558 }
559#endif
560
561 return 0;
562}
563
564int
565isakmp_cfg_request(iph1, attrpl, msg)
566 struct ph1handle *iph1;
567 struct isakmp_pl_attr *attrpl;
568 vchar_t *msg;
569{
570 struct isakmp_data *attr;
571 int tlen;
572 size_t alen;
573 char *npp;
574 vchar_t *payload = NULL;
575 struct isakmp_pl_attr *reply;
576 vchar_t *reply_attr;
577 int type;
578 int error = -1;
579
580 tlen = ntohs(attrpl->h.len);
581 attr = (struct isakmp_data *)(attrpl + 1);
582 tlen -= sizeof(*attrpl);
583
584 /*
585 * if started_by_api then we are a VPN client and if we receive
586 * a mode-cfg request it needs to go to the VPN controller to
587 * retrieve the appropriate data (name, pw, pin, etc.)
588 */
589 if (iph1->started_by_api || ike_session_is_client_ph1_rekey(iph1)) {
590 /*
591 * if we already received this one - ignore it
592 * we are waiting for a reply from the vpn control socket
593 */
594 if (iph1->xauth_awaiting_userinput)
595 return 0;
596
597 /* otherwise - save the msg id and call and send the status notification */
598 iph1->pended_xauth_id = attrpl->id; /* network byte order */
599 if (vpncontrol_notify_need_authinfo(iph1, attrpl + 1, tlen))
600 goto end;
601 iph1->xauth_awaiting_userinput = 1;
602 iph1->xauth_awaiting_userinput_msg = vdup(msg); // dup the message for later
603 ike_session_start_xauth_timer(iph1);
604 return 0;
605 }
606
607 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
608 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
609 return -1;
610 }
611 memset(payload->v, 0, sizeof(*reply));
612
613 while (tlen > 0) {
614 reply_attr = NULL;
615 type = ntohs(attr->type);
616
617 /* Handle short attributes */
618 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
619 type &= ~ISAKMP_GEN_MASK;
620
621 plog(LLV_DEBUG, LOCATION, NULL,
622 "Short attribute %s = %d\n",
623 s_isakmp_cfg_type(type), ntohs(attr->lorv));
624
625 switch (type) {
626 case XAUTH_TYPE:
627 reply_attr = isakmp_xauth_req(iph1, attr);
628 break;
629 default:
630 plog(LLV_WARNING, LOCATION, NULL,
631 "Ignored short attribute %s\n",
632 s_isakmp_cfg_type(type));
633 break;
634 }
635
636 tlen -= sizeof(*attr);
637 attr++;
638
639 if (reply_attr != NULL) {
640 payload = buffer_cat(payload, reply_attr);
641 vfree(reply_attr);
642 }
643
644 continue;
645 }
646
647 type = ntohs(attr->type);
648 alen = ntohs(attr->lorv);
649
650 /* Check that the attribute fit in the packet */
651 if (tlen < alen) {
652 plog(LLV_ERROR, LOCATION, NULL,
653 "Short attribute %s\n",
654 s_isakmp_cfg_type(type));
655 goto end;
656 }
657
658 plog(LLV_DEBUG, LOCATION, NULL,
659 "Attribute %s, len %zu\n",
660 s_isakmp_cfg_type(type), alen);
661
662 switch(type) {
663 case INTERNAL_IP4_ADDRESS:
664 case INTERNAL_IP4_NETMASK:
665 case INTERNAL_IP4_DNS:
666 case INTERNAL_IP4_NBNS:
667 case INTERNAL_IP4_SUBNET:
668 reply_attr = isakmp_cfg_net(iph1, attr);
669 break;
670
671 case XAUTH_TYPE:
672 case XAUTH_USER_NAME:
673 case XAUTH_USER_PASSWORD:
674 case XAUTH_PASSCODE:
675 case XAUTH_MESSAGE:
676 case XAUTH_CHALLENGE:
677 case XAUTH_DOMAIN:
678 case XAUTH_STATUS:
679 case XAUTH_NEXT_PIN:
680 case XAUTH_ANSWER:
681 reply_attr = isakmp_xauth_req(iph1, attr);
682 break;
683
684 case APPLICATION_VERSION:
685 reply_attr = isakmp_cfg_string(iph1,
686 attr, ISAKMP_CFG_RACOON_VERSION);
687 break;
688
689 case UNITY_BANNER:
690 case UNITY_PFS:
691 case UNITY_SAVE_PASSWD:
692 case UNITY_DEF_DOMAIN:
693 case UNITY_DDNS_HOSTNAME:
694 case UNITY_FW_TYPE:
695 case UNITY_SPLITDNS_NAME:
696 case UNITY_SPLIT_INCLUDE:
697 case UNITY_LOCAL_LAN:
698 case UNITY_NATT_PORT:
699 case UNITY_BACKUP_SERVERS:
700 reply_attr = isakmp_unity_req(iph1, attr);
701 break;
702
703 case INTERNAL_ADDRESS_EXPIRY:
704 default:
705 plog(LLV_WARNING, LOCATION, NULL,
706 "Ignored attribute %s\n",
707 s_isakmp_cfg_type(type));
708 break;
709 }
710
711 npp = (char *)attr;
712 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
713 tlen -= (sizeof(*attr) + alen);
714
715 if (reply_attr != NULL) {
716 payload = buffer_cat(payload, reply_attr);
717 vfree(reply_attr);
718 }
719 }
720
721 reply = (struct isakmp_pl_attr *)payload->v;
722 reply->h.len = htons(payload->l);
723 reply->type = ISAKMP_CFG_REPLY;
724 reply->id = attrpl->id;
725
726 plog(LLV_DEBUG, LOCATION, NULL,
727 "Sending MODE_CFG REPLY\n");
728
729 error = isakmp_cfg_send(iph1, payload,
730 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
731
732 if (iph1->status == PHASE1ST_ESTABLISHED) {
733 switch (AUTHMETHOD(iph1)) {
734 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
735 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
736 /* Unimplemented */
737 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
738 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
739 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
740 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
741 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
742 script_hook(iph1, SCRIPT_PHASE1_UP);
743 break;
744 default:
745 break;
746 }
747#ifdef ENABLE_VPNCONTROL_PORT
748 vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
749#endif
750
751 }
752
753end:
754 vfree(payload);
755
756 return error;
757}
758
759int
760isakmp_cfg_set(iph1, attrpl, msg)
761 struct ph1handle *iph1;
762 struct isakmp_pl_attr *attrpl;
763 vchar_t *msg;
764{
765 struct isakmp_data *attr;
766 int tlen;
767 size_t alen;
768 char *npp;
769 vchar_t *payload;
770 struct isakmp_pl_attr *reply;
771 vchar_t *reply_attr;
772 int type;
773 int error = -1;
774
775 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
776 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
777 return -1;
778 }
779 memset(payload->v, 0, sizeof(*reply));
780
781 tlen = ntohs(attrpl->h.len);
782 attr = (struct isakmp_data *)(attrpl + 1);
783 tlen -= sizeof(*attrpl);
784
785 /*
786 * We should send ack for the attributes we accepted
787 */
788 while (tlen > 0) {
789 reply_attr = NULL;
790 type = ntohs(attr->type);
791
792 plog(LLV_DEBUG, LOCATION, NULL,
793 "Attribute %s\n",
794 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
795
796 switch (type & ~ISAKMP_GEN_MASK) {
797 case XAUTH_STATUS:
798 reply_attr = isakmp_xauth_set(iph1, attr);
799 break;
800 default:
801 plog(LLV_DEBUG, LOCATION, NULL,
802 "Unexpected SET attribute %s\n",
803 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
804 break;
805 }
806
807 if (reply_attr != NULL) {
808 payload = buffer_cat(payload, reply_attr);
809 vfree(reply_attr);
810 }
811
812 /*
813 * Move to next attribute. If we run out of the packet,
814 * tlen becomes negative and we exit.
815 */
816 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
817 tlen -= sizeof(*attr);
818 attr++;
819 } else {
820 alen = ntohs(attr->lorv);
821 tlen -= (sizeof(*attr) + alen);
822 npp = (char *)attr;
823 attr = (struct isakmp_data *)
824 (npp + sizeof(*attr) + alen);
825 }
826 }
827
828 reply = (struct isakmp_pl_attr *)payload->v;
829 reply->h.len = htons(payload->l);
830 reply->type = ISAKMP_CFG_ACK;
831 reply->id = attrpl->id;
832
833 plog(LLV_DEBUG, LOCATION, NULL,
834 "Sending MODE_CFG ACK\n");
835
836 error = isakmp_cfg_send(iph1, payload,
837 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
838
839 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
840 if (iph1->status == PHASE1ST_ESTABLISHED)
841 isakmp_info_send_d1(iph1);
842 isakmp_ph1expire(iph1);
843 iph1 = NULL;
844 }
845 vfree(payload);
846
847 /*
848 * If required, request ISAKMP mode config information: ignore rekeys
849 */
850 if ((iph1 != NULL) && (!iph1->is_rekey) && (iph1->rmconf->mode_cfg) && (error == 0))
851 error = isakmp_cfg_getconfig(iph1);
852
853 return error;
854}
855
856
857static vchar_t *
858buffer_cat(s, append)
859 vchar_t *s;
860 vchar_t *append;
861{
862 vchar_t *new;
863
864 new = vmalloc(s->l + append->l);
865 if (new == NULL) {
866 plog(LLV_ERROR, LOCATION, NULL,
867 "Cannot allocate memory\n");
868 return s;
869 }
870
871 memcpy(new->v, s->v, s->l);
872 memcpy(new->v + s->l, append->v, append->l);
873
874 vfree(s);
875 return new;
876}
877
878static vchar_t *
879isakmp_cfg_net(iph1, attr)
880 struct ph1handle *iph1;
881 struct isakmp_data *attr;
882{
883 int type;
884 int confsource;
885 in_addr_t addr4;
886
887 type = ntohs(attr->type);
888
889 /*
890 * Don't give an address to a peer that did not succeed Xauth
891 */
892 if (xauth_check(iph1) != 0) {
893 plog(LLV_ERROR, LOCATION, NULL,
894 "Attempt to start phase config whereas Xauth failed\n");
895 return NULL;
896 }
897
898 confsource = isakmp_cfg_config.confsource;
899 /*
900 * If we have to fall back to a local
901 * configuration source, we will jump
902 * back to this point.
903 */
904retry_source:
905
906 switch(type) {
907 case INTERNAL_IP4_ADDRESS:
908 switch(confsource) {
909#ifdef HAVE_LIBLDAP
910 case ISAKMP_CFG_CONF_LDAP:
911 if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
912 break;
913 plog(LLV_INFO, LOCATION, NULL,
914 "No IP from LDAP, using local pool\n");
915 /* FALLTHROUGH */
916 confsource = ISAKMP_CFG_CONF_LOCAL;
917 goto retry_source;
918#endif
919#ifdef HAVE_LIBRADIUS
920 case ISAKMP_CFG_CONF_RADIUS:
921 if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
922 && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
923 /*
924 * -2 is 255.255.255.254, RADIUS uses that
925 * to instruct the NAS to use a local pool
926 */
927 break;
928 plog(LLV_INFO, LOCATION, NULL,
929 "No IP from RADIUS, using local pool\n");
930 /* FALLTHROUGH */
931 confsource = ISAKMP_CFG_CONF_LOCAL;
932 goto retry_source;
933#endif
934 case ISAKMP_CFG_CONF_LOCAL:
935 if (isakmp_cfg_getport(iph1) == -1) {
936 plog(LLV_ERROR, LOCATION, NULL,
937 "Port pool depleted\n");
938 break;
939 }
940
941 iph1->mode_cfg->addr4.s_addr =
942 htonl(ntohl(isakmp_cfg_config.network4)
943 + iph1->mode_cfg->port);
944 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
945 break;
946
947 default:
948 plog(LLV_ERROR, LOCATION, NULL,
949 "Unexpected confsource\n");
950 }
951
952 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
953 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
954
955 return isakmp_cfg_addr4(iph1,
956 attr, &iph1->mode_cfg->addr4.s_addr);
957 break;
958
959 case INTERNAL_IP4_NETMASK:
960 switch(confsource) {
961#ifdef HAVE_LIBLDAP
962 case ISAKMP_CFG_CONF_LDAP:
963 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
964 break;
965 plog(LLV_INFO, LOCATION, NULL,
966 "No mask from LDAP, using local pool\n");
967 /* FALLTHROUGH */
968 confsource = ISAKMP_CFG_CONF_LOCAL;
969 goto retry_source;
970#endif
971#ifdef HAVE_LIBRADIUS
972 case ISAKMP_CFG_CONF_RADIUS:
973 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
974 break;
975 plog(LLV_INFO, LOCATION, NULL,
976 "No mask from RADIUS, using local pool\n");
977 /* FALLTHROUGH */
978 confsource = ISAKMP_CFG_CONF_LOCAL;
979 goto retry_source;
980#endif
981 case ISAKMP_CFG_CONF_LOCAL:
982 iph1->mode_cfg->mask4.s_addr
983 = isakmp_cfg_config.netmask4;
984 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
985 break;
986
987 default:
988 plog(LLV_ERROR, LOCATION, NULL,
989 "Unexpected confsource\n");
990 }
991 return isakmp_cfg_addr4(iph1, attr,
992 &iph1->mode_cfg->mask4.s_addr);
993 break;
994
995 case INTERNAL_IP4_DNS:
996 return isakmp_cfg_addr4_list(iph1,
997 attr, &isakmp_cfg_config.dns4[0],
998 isakmp_cfg_config.dns4_index);
999 break;
1000
1001 case INTERNAL_IP4_NBNS:
1002 return isakmp_cfg_addr4_list(iph1,
1003 attr, &isakmp_cfg_config.nbns4[0],
1004 isakmp_cfg_config.nbns4_index);
1005 break;
1006
1007 case INTERNAL_IP4_SUBNET:
1008 return isakmp_cfg_addr4(iph1,
1009 attr, &isakmp_cfg_config.network4);
1010 break;
1011
1012 default:
1013 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
1014 break;
1015 }
1016 return NULL;
1017}
1018
1019#if 0
1020static vchar_t *
1021isakmp_cfg_void(iph1, attr)
1022 struct ph1handle *iph1;
1023 struct isakmp_data *attr;
1024{
1025 vchar_t *buffer;
1026 struct isakmp_data *new;
1027
1028 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1029 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1030 return NULL;
1031 }
1032
1033 new = (struct isakmp_data *)buffer->v;
1034
1035 new->type = attr->type;
1036 new->lorv = htons(0);
1037
1038 return buffer;
1039}
1040#endif
1041
1042vchar_t *
1043isakmp_cfg_copy(iph1, attr)
1044 struct ph1handle *iph1;
1045 struct isakmp_data *attr;
1046{
1047 vchar_t *buffer;
1048 size_t len = 0;
1049
1050 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
1051 len = ntohs(attr->lorv);
1052
1053 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1054 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1055 return NULL;
1056 }
1057
1058 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
1059
1060 return buffer;
1061}
1062
1063vchar_t *
1064isakmp_cfg_short(iph1, attr, value)
1065 struct ph1handle *iph1;
1066 struct isakmp_data *attr;
1067 int value;
1068{
1069 vchar_t *buffer;
1070 struct isakmp_data *new;
1071 int type;
1072
1073 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1074 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1075 return NULL;
1076 }
1077
1078 new = (struct isakmp_data *)buffer->v;
1079 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1080
1081 new->type = htons(type | ISAKMP_GEN_TV);
1082 new->lorv = htons(value);
1083
1084 return buffer;
1085}
1086
1087vchar_t *
1088isakmp_cfg_varlen(iph1, attr, string, len)
1089 struct ph1handle *iph1;
1090 struct isakmp_data *attr;
1091 char *string;
1092 size_t len;
1093{
1094 vchar_t *buffer;
1095 struct isakmp_data *new;
1096 char *data;
1097
1098 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1099 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1100 return NULL;
1101 }
1102
1103 new = (struct isakmp_data *)buffer->v;
1104
1105 new->type = attr->type;
1106 new->lorv = htons(len);
1107 data = (char *)(new + 1);
1108
1109 memcpy(data, string, len);
1110
1111 return buffer;
1112}
1113vchar_t *
1114isakmp_cfg_string(iph1, attr, string)
1115 struct ph1handle *iph1;
1116 struct isakmp_data *attr;
1117 char *string;
1118{
1119 size_t len = strlen(string);
1120 return isakmp_cfg_varlen(iph1, attr, string, len);
1121}
1122
1123static vchar_t *
1124isakmp_cfg_addr4(iph1, attr, addr)
1125 struct ph1handle *iph1;
1126 struct isakmp_data *attr;
1127 in_addr_t *addr;
1128{
1129 vchar_t *buffer;
1130 struct isakmp_data *new;
1131 size_t len;
1132
1133 len = sizeof(*addr);
1134 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1135 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1136 return NULL;
1137 }
1138
1139 new = (struct isakmp_data *)buffer->v;
1140
1141 new->type = attr->type;
1142 new->lorv = htons(len);
1143 memcpy(new + 1, addr, len);
1144
1145 return buffer;
1146}
1147
1148static vchar_t *
1149isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1150 struct ph1handle *iph1;
1151 struct isakmp_data *attr;
1152 in_addr_t *addr;
1153 int nbr;
1154{
1155 int error = -1;
1156 vchar_t *buffer = NULL;
1157 vchar_t *bufone = NULL;
1158 struct isakmp_data *new;
1159 size_t len;
1160 int i;
1161
1162 len = sizeof(*addr);
1163 if ((buffer = vmalloc(0)) == NULL) {
1164 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1165 goto out;
1166 }
1167 for(i = 0; i < nbr; i++) {
1168 if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1169 plog(LLV_ERROR, LOCATION, NULL,
1170 "Cannot allocate memory\n");
1171 goto out;
1172 }
1173 new = (struct isakmp_data *)bufone->v;
1174 new->type = attr->type;
1175 new->lorv = htons(len);
1176 memcpy(new + 1, &addr[i], len);
1177 new += (len + sizeof(*attr));
1178 buffer = buffer_cat(buffer, bufone);
1179 vfree(bufone);
1180 }
1181
1182 error = 0;
1183
1184out:
1185 if ((error != 0) && (buffer != NULL)) {
1186 vfree(buffer);
1187 buffer = NULL;
1188 }
1189
1190 return buffer;
1191}
1192
1193struct isakmp_ivm *
1194isakmp_cfg_newiv(iph1, msgid)
1195 struct ph1handle *iph1;
1196 u_int32_t msgid;
1197{
1198 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1199
1200 if (ics == NULL) {
1201 plog(LLV_ERROR, LOCATION, NULL,
1202 "isakmp_cfg_newiv called without mode config state\n");
1203 return NULL;
1204 }
1205
1206 if (ics->ivm != NULL)
1207 oakley_delivm(ics->ivm);
1208
1209 ics->ivm = oakley_newiv2(iph1, msgid);
1210 ics->last_msgid = msgid;
1211
1212 return ics->ivm;
1213}
1214
1215/* Derived from isakmp_info_send_common */
1216int
1217isakmp_cfg_send(iph1, payload, np, flags, new_exchange, retry_count, msg)
1218 struct ph1handle *iph1;
1219 vchar_t *payload;
1220 u_int32_t np;
1221 int flags;
1222 int new_exchange;
1223 int retry_count;
1224 vchar_t *msg;
1225{
1226 struct ph2handle *iph2 = NULL;
1227 vchar_t *hash = NULL;
1228 struct isakmp *isakmp;
1229 struct isakmp_gen *gen;
1230 char *p;
1231 int tlen;
1232 int error = -1;
1233 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1234
1235 /* Check if phase 1 is established */
1236 if ((iph1->status != PHASE1ST_ESTABLISHED) ||
1237 (iph1->local == NULL) ||
1238 (iph1->remote == NULL)) {
1239 plog(LLV_ERROR, LOCATION, NULL,
1240 "ISAKMP mode config exchange with immature phase 1\n");
1241 goto end;
1242 }
1243
1244 /* add new entry to isakmp status table */
1245 iph2 = newph2();
1246 if (iph2 == NULL) {
1247 plog(LLV_ERROR, LOCATION, NULL,
1248 "failed to allocate ph2");
1249 goto end;
1250 }
1251
1252 iph2->dst = dupsaddr(iph1->remote);
1253 if (iph2->dst == NULL) {
1254 plog(LLV_ERROR, LOCATION, NULL,
1255 "failed to duplicate remote address");
1256 delph2(iph2);
1257 goto end;
1258 }
1259 iph2->src = dupsaddr(iph1->local);
1260 if (iph2->src == NULL) {
1261 plog(LLV_ERROR, LOCATION, NULL,
1262 "failed to duplicate local address");
1263 delph2(iph2);
1264 goto end;
1265 }
1266
1267 switch (iph1->remote->sa_family) {
1268 case AF_INET:
1269#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1270 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1271 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1272#endif
1273 break;
1274#ifdef INET6
1275 case AF_INET6:
1276#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1277 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1278 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
1279#endif
1280 break;
1281#endif
1282 default:
1283 plog(LLV_ERROR, LOCATION, NULL,
1284 "invalid family: %d\n", iph1->remote->sa_family);
1285 delph2(iph2);
1286 goto end;
1287 }
1288 iph2->ph1 = iph1;
1289 iph2->side = INITIATOR;
1290 iph2->status = PHASE2ST_START;
1291
1292 if (new_exchange)
1293 iph2->msgid = isakmp_newmsgid2(iph1);
1294 else
1295 iph2->msgid = iph1->msgid;
1296
1297 /* get IV and HASH(1) if skeyid_a was generated. */
1298 if (iph1->skeyid_a != NULL) {
1299 if (new_exchange) {
1300 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1301 plog(LLV_ERROR, LOCATION, NULL,
1302 "failed to generate IV");
1303 delph2(iph2);
1304 goto end;
1305 }
1306 }
1307
1308 /* generate HASH(1) */
1309 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
1310 if (hash == NULL) {
1311 plog(LLV_ERROR, LOCATION, NULL,
1312 "failed to generate HASH");
1313 delph2(iph2);
1314 goto end;
1315 }
1316
1317 /* initialized total buffer length */
1318 tlen = hash->l;
1319 tlen += sizeof(*gen);
1320 } else {
1321 /* IKE-SA is not established */
1322 hash = NULL;
1323
1324 /* initialized total buffer length */
1325 tlen = 0;
1326 }
1327 if ((flags & ISAKMP_FLAG_A) == 0)
1328 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1329 else
1330 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1331
1332 insph2(iph2);
1333 bindph12(iph1, iph2);
1334
1335 tlen += sizeof(*isakmp) + payload->l;
1336
1337 /* create buffer for isakmp payload */
1338 iph2->sendbuf = vmalloc(tlen);
1339 if (iph2->sendbuf == NULL) {
1340 plog(LLV_ERROR, LOCATION, NULL,
1341 "failed to get buffer to send.\n");
1342 goto err;
1343 }
1344
1345 /* create isakmp header */
1346 isakmp = (struct isakmp *)iph2->sendbuf->v;
1347 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1348 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1349 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1350 isakmp->v = iph1->version;
1351 isakmp->etype = ISAKMP_ETYPE_CFG;
1352 isakmp->flags = iph2->flags;
1353 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1354 isakmp->len = htonl(tlen);
1355 p = (char *)(isakmp + 1);
1356
1357 /* create HASH payload */
1358 if (hash != NULL) {
1359 gen = (struct isakmp_gen *)p;
1360 gen->np = np & 0xff;
1361 gen->len = htons(sizeof(*gen) + hash->l);
1362 p += sizeof(*gen);
1363 memcpy(p, hash->v, hash->l);
1364 p += hash->l;
1365 }
1366
1367 /* add payload */
1368 memcpy(p, payload->v, payload->l);
1369 p += payload->l;
1370
1371#ifdef HAVE_PRINT_ISAKMP_C
1372 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1373#endif
1374
1375 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
1376 plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
1377
1378 /* encoding */
1379 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1380 vchar_t *tmp;
1381
1382 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1383 ics->ivm->ive, ics->ivm->iv);
1384 VPTRINIT(iph2->sendbuf);
1385 if (tmp == NULL) {
1386 plog(LLV_ERROR, LOCATION, NULL,
1387 "failed to encrypt packet");
1388 goto err;
1389 }
1390 iph2->sendbuf = tmp;
1391 }
1392
1393 /* HDR*, HASH(1), ATTR */
1394
1395 if (retry_count > 0) {
1396 iph2->retry_counter = retry_count;
1397 if (isakmp_ph2resend(iph2) < 0) {
1398 plog(LLV_ERROR, LOCATION, NULL,
1399 "failed to resend packet");
1400 VPTRINIT(iph2->sendbuf);
1401 goto err;
1402 }
1403 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1404 IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT,
1405 CONSTSTR("Mode-Config retransmit"),
1406 CONSTSTR(NULL));
1407 error = 0;
1408 goto end;
1409 }
1410
1411 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1412 plog(LLV_ERROR, LOCATION, NULL,
1413 "failed to send packet");
1414 VPTRINIT(iph2->sendbuf);
1415 goto err;
1416 }
1417 if (msg) {
1418 /* the sending message is added to the received-list. */
1419 if (add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg,
1420 PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
1421 plog(LLV_ERROR , LOCATION, NULL,
1422 "failed to add a response packet to the tree.\n");
1423 }
1424 }
1425
1426 plog(LLV_DEBUG, LOCATION, NULL,
1427 "sendto mode config %s.\n", s_isakmp_nptype(np));
1428
1429 /*
1430 * XXX We might need to resend the message...
1431 */
1432
1433 error = 0;
1434 VPTRINIT(iph2->sendbuf);
1435
1436 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1437 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
1438 CONSTSTR("Mode-Config message"),
1439 CONSTSTR(NULL));
1440
1441err:
1442 if (error) {
1443 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1444 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
1445 CONSTSTR("Mode-Config message"),
1446 CONSTSTR("Failed to transmit Mode-Config message"));
1447 }
1448 unbindph12(iph2);
1449 remph2(iph2);
1450 delph2(iph2);
1451end:
1452 if (hash)
1453 vfree(hash);
1454 return error;
1455}
1456
1457
1458void
1459isakmp_cfg_rmstate(iph1)
1460 struct ph1handle *iph1;
1461{
1462 struct isakmp_cfg_state *state = iph1->mode_cfg;
1463
1464 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1465 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1466
1467 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1468 isakmp_cfg_putport(iph1, state->port);
1469
1470 /* Delete the IV if it's still there */
1471 if(iph1->mode_cfg->ivm) {
1472 oakley_delivm(iph1->mode_cfg->ivm);
1473 iph1->mode_cfg->ivm = NULL;
1474 }
1475
1476 /* Free any allocated splitnet lists */
1477 if(iph1->mode_cfg->split_include != NULL)
1478 splitnet_list_free(iph1->mode_cfg->split_include,
1479 &iph1->mode_cfg->include_count);
1480 if(iph1->mode_cfg->split_local != NULL)
1481 splitnet_list_free(iph1->mode_cfg->split_local,
1482 &iph1->mode_cfg->local_count);
1483
1484 xauth_rmstate(&state->xauth);
1485
1486 if (state->attr_list)
1487 vfree(state->attr_list);
1488
1489 racoon_free(state);
1490 iph1->mode_cfg = NULL;
1491
1492 return;
1493}
1494
1495struct isakmp_cfg_state *
1496isakmp_cfg_mkstate(void)
1497{
1498 struct isakmp_cfg_state *state;
1499
1500 if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1501 plog(LLV_ERROR, LOCATION, NULL,
1502 "Cannot allocate memory for mode config state\n");
1503 return NULL;
1504 }
1505 memset(state, 0, sizeof(*state));
1506
1507 return state;
1508}
1509
1510int
1511isakmp_cfg_getport(iph1)
1512 struct ph1handle *iph1;
1513{
1514 unsigned int i;
1515 size_t size = isakmp_cfg_config.pool_size;
1516
1517 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1518 return iph1->mode_cfg->port;
1519
1520 if (isakmp_cfg_config.port_pool == NULL) {
1521 plog(LLV_ERROR, LOCATION, NULL,
1522 "isakmp_cfg_config.port_pool == NULL\n");
1523 return -1;
1524 }
1525
1526 for (i = 0; i < size; i++) {
1527 if (isakmp_cfg_config.port_pool[i].used == 0)
1528 break;
1529 }
1530
1531 if (i == size) {
1532 plog(LLV_ERROR, LOCATION, NULL,
1533 "No more addresses available\n");
1534 return -1;
1535 }
1536
1537 isakmp_cfg_config.port_pool[i].used = 1;
1538
1539 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1540
1541 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1542 iph1->mode_cfg->port = i;
1543
1544 return i;
1545}
1546
1547int
1548isakmp_cfg_putport(iph1, index)
1549 struct ph1handle *iph1;
1550 unsigned int index;
1551{
1552 if (isakmp_cfg_config.port_pool == NULL) {
1553 plog(LLV_ERROR, LOCATION, NULL,
1554 "isakmp_cfg_config.port_pool == NULL\n");
1555 return -1;
1556 }
1557
1558 if (isakmp_cfg_config.port_pool[index].used == 0) {
1559 plog(LLV_ERROR, LOCATION, NULL,
1560 "Attempt to release an unallocated address (port %d)\n",
1561 index);
1562 return -1;
1563 }
1564
1565#ifdef HAVE_LIBPAM
1566 /* Cleanup PAM status associated with the port */
1567 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1568 privsep_cleanup_pam(index);
1569#endif
1570 isakmp_cfg_config.port_pool[index].used = 0;
1571 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1572
1573 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1574
1575 return 0;
1576}
1577
1578#ifdef HAVE_LIBPAM
1579void
1580cleanup_pam(port)
1581 int port;
1582{
1583 if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1584 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1585 isakmp_cfg_config.port_pool[port].pam = NULL;
1586 }
1587
1588 return;
1589}
1590#endif
1591
1592/* Accounting, only for RADIUS or PAM */
1593static int
1594isakmp_cfg_accounting(iph1, inout)
1595 struct ph1handle *iph1;
1596 int inout;
1597{
1598#ifdef HAVE_LIBPAM
1599 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1600 return privsep_accounting_pam(iph1->mode_cfg->port,
1601 inout);
1602#endif
1603#ifdef HAVE_LIBRADIUS
1604 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1605 return isakmp_cfg_accounting_radius(iph1, inout);
1606#endif
1607 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
1608 return privsep_accounting_system(iph1->mode_cfg->port,
1609 iph1->remote, iph1->mode_cfg->login, inout);
1610 return 0;
1611}
1612
1613#ifdef HAVE_LIBPAM
1614int
1615isakmp_cfg_accounting_pam(port, inout)
1616 int port;
1617 int inout;
1618{
1619 int error = 0;
1620 pam_handle_t *pam;
1621
1622 if (isakmp_cfg_config.port_pool == NULL) {
1623 plog(LLV_ERROR, LOCATION, NULL,
1624 "isakmp_cfg_config.port_pool == NULL\n");
1625 return -1;
1626 }
1627
1628 pam = isakmp_cfg_config.port_pool[port].pam;
1629 if (pam == NULL) {
1630 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1631 return -1;
1632 }
1633
1634 switch (inout) {
1635 case ISAKMP_CFG_LOGIN:
1636 error = pam_open_session(pam, 0);
1637 break;
1638 case ISAKMP_CFG_LOGOUT:
1639 error = pam_close_session(pam, 0);
1640 pam_end(pam, error);
1641 isakmp_cfg_config.port_pool[port].pam = NULL;
1642 break;
1643 default:
1644 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1645 break;
1646 }
1647
1648 if (error != 0) {
1649 plog(LLV_ERROR, LOCATION, NULL,
1650 "pam_open_session/pam_close_session failed: %s\n",
1651 pam_strerror(pam, error));
1652 return -1;
1653 }
1654
1655 return 0;
1656}
1657#endif /* HAVE_LIBPAM */
1658
1659#ifdef HAVE_LIBRADIUS
1660static int
1661isakmp_cfg_accounting_radius(iph1, inout)
1662 struct ph1handle *iph1;
1663 int inout;
1664{
1665 /* For first time use, initialize Radius */
1666 if (radius_acct_state == NULL) {
1667 if ((radius_acct_state = rad_acct_open()) == NULL) {
1668 plog(LLV_ERROR, LOCATION, NULL,
1669 "Cannot init librradius\n");
1670 return -1;
1671 }
1672
1673 if (rad_config(radius_acct_state, NULL) != 0) {
1674 plog(LLV_ERROR, LOCATION, NULL,
1675 "Cannot open librarius config file: %s\n",
1676 rad_strerror(radius_acct_state));
1677 rad_close(radius_acct_state);
1678 radius_acct_state = NULL;
1679 return -1;
1680 }
1681 }
1682
1683 if (rad_create_request(radius_acct_state,
1684 RAD_ACCOUNTING_REQUEST) != 0) {
1685 plog(LLV_ERROR, LOCATION, NULL,
1686 "rad_create_request failed: %s\n",
1687 rad_strerror(radius_acct_state));
1688 return -1;
1689 }
1690
1691 if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1692 iph1->mode_cfg->login) != 0) {
1693 plog(LLV_ERROR, LOCATION, NULL,
1694 "rad_put_string failed: %s\n",
1695 rad_strerror(radius_acct_state));
1696 return -1;
1697 }
1698
1699 switch (inout) {
1700 case ISAKMP_CFG_LOGIN:
1701 inout = RAD_START;
1702 break;
1703 case ISAKMP_CFG_LOGOUT:
1704 inout = RAD_STOP;
1705 break;
1706 default:
1707 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1708 break;
1709 }
1710
1711 if (rad_put_addr(radius_acct_state,
1712 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1713 plog(LLV_ERROR, LOCATION, NULL,
1714 "rad_put_addr failed: %s\n",
1715 rad_strerror(radius_acct_state));
1716 return -1;
1717 }
1718
1719 if (rad_put_addr(radius_acct_state,
1720 RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1721 plog(LLV_ERROR, LOCATION, NULL,
1722 "rad_put_addr failed: %s\n",
1723 rad_strerror(radius_acct_state));
1724 return -1;
1725 }
1726
1727 if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1728 plog(LLV_ERROR, LOCATION, NULL,
1729 "rad_put_int failed: %s\n",
1730 rad_strerror(radius_acct_state));
1731 return -1;
1732 }
1733
1734 if (isakmp_cfg_radius_common(radius_acct_state,
1735 iph1->mode_cfg->port) != 0)
1736 return -1;
1737
1738 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1739 plog(LLV_ERROR, LOCATION, NULL,
1740 "rad_send_request failed: %s\n",
1741 rad_strerror(radius_acct_state));
1742 return -1;
1743 }
1744
1745 return 0;
1746}
1747#endif /* HAVE_LIBRADIUS */
1748
1749/*
1750 * Attributes common to all RADIUS requests
1751 */
1752#ifdef HAVE_LIBRADIUS
1753int
1754isakmp_cfg_radius_common(radius_state, port)
1755 struct rad_handle *radius_state;
1756 int port;
1757{
1758 struct utsname name;
1759 static struct hostent *host = NULL;
1760 struct in_addr nas_addr;
1761
1762 /*
1763 * Find our own IP by resolving our nodename
1764 */
1765 if (host == NULL) {
1766 if (uname(&name) != 0) {
1767 plog(LLV_ERROR, LOCATION, NULL,
1768 "uname failed: %s\n", strerror(errno));
1769 return -1;
1770 }
1771
1772 if ((host = gethostbyname(name.nodename)) == NULL) {
1773 plog(LLV_ERROR, LOCATION, NULL,
1774 "gethostbyname failed: %s\n", strerror(errno));
1775 return -1;
1776 }
1777 }
1778
1779 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1780 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1781 plog(LLV_ERROR, LOCATION, NULL,
1782 "rad_put_addr failed: %s\n",
1783 rad_strerror(radius_state));
1784 return -1;
1785 }
1786
1787 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1788 plog(LLV_ERROR, LOCATION, NULL,
1789 "rad_put_int failed: %s\n",
1790 rad_strerror(radius_state));
1791 return -1;
1792 }
1793
1794 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1795 plog(LLV_ERROR, LOCATION, NULL,
1796 "rad_put_int failed: %s\n",
1797 rad_strerror(radius_state));
1798 return -1;
1799 }
1800
1801 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1802 plog(LLV_ERROR, LOCATION, NULL,
1803 "rad_put_int failed: %s\n",
1804 rad_strerror(radius_state));
1805 return -1;
1806 }
1807
1808 return 0;
1809}
1810#endif
1811
1812/*
1813 Logs the user into the utmp system files.
1814*/
1815
1816int
1817isakmp_cfg_accounting_system(port, raddr, usr, inout)
1818 int port;
1819 struct sockaddr *raddr;
1820 char *usr;
1821 int inout;
1822{
1823 int error = 0;
1824 struct utmpx ut;
1825 char term[_UTX_LINESIZE];
1826 char addr[NI_MAXHOST];
1827
1828 if (usr == NULL || usr[0]=='\0') {
1829 plog(LLV_ERROR, LOCATION, NULL,
1830 "system accounting : no login found\n");
1831 return -1;
1832 }
1833
1834 snprintf(term, sizeof(term), TERMSPEC, port);
1835
1836 switch (inout) {
1837 case ISAKMP_CFG_LOGIN:
1838 strlcpy(ut.ut_user, usr, sizeof(ut.ut_user));
1839
1840 strlcpy(ut.ut_line, term, sizeof(ut.ut_line));
1841
1842 GETNAMEINFO_NULL(raddr, addr);
1843 strlcpy(ut.ut_host, addr, sizeof(ut.ut_host));
1844
1845 ut.ut_pid = getpid();
1846
1847 ut.ut_type = UTMPX_AUTOFILL_MASK | USER_PROCESS;
1848
1849 gettimeofday(&ut.ut_tv, NULL);
1850
1851 plog(LLV_INFO, LOCATION, NULL,
1852 "Accounting : '%s' logging on '%s' from %s.\n",
1853 ut.ut_user, ut.ut_line, ut.ut_host);
1854
1855 if (pututxline(&ut) == NULL)
1856 return -1;
1857
1858 break;
1859 case ISAKMP_CFG_LOGOUT:
1860
1861 plog(LLV_INFO, LOCATION, NULL,
1862 "Accounting : '%s' unlogging from '%s'.\n",
1863 usr, term);
1864
1865 ut.ut_type = UTMPX_AUTOFILL_MASK | DEAD_PROCESS;
1866
1867 gettimeofday(&ut.ut_tv, NULL);
1868
1869 if (pututxline(&ut) == NULL)
1870 return -1;
1871
1872 break;
1873 default:
1874 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1875 break;
1876 }
1877
1878 return 0;
1879}
1880
1881int
1882isakmp_cfg_getconfig(iph1)
1883 struct ph1handle *iph1;
1884{
1885 vchar_t *buffer;
1886 struct isakmp_pl_attr *attrpl;
1887 struct isakmp_data *attr;
1888 size_t len;
1889 vchar_t *version = NULL;
1890 int error;
1891 int attrcount;
1892 int i;
1893 int attrlist[] = {
1894 INTERNAL_IP4_ADDRESS,
1895 INTERNAL_IP4_NETMASK,
1896 INTERNAL_IP4_DNS,
1897 INTERNAL_IP4_NBNS,
1898 INTERNAL_ADDRESS_EXPIRY,
1899 APPLICATION_VERSION,
1900 UNITY_BANNER,
1901 UNITY_DEF_DOMAIN,
1902 UNITY_SPLITDNS_NAME,
1903 UNITY_SPLIT_INCLUDE,
1904 UNITY_LOCAL_LAN,
1905 };
1906
1907 attrcount = sizeof(attrlist) / sizeof(*attrlist);
1908 len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1909
1910 if (iph1->started_by_api) {
1911 if (iph1->remote->sa_family == AF_INET) {
1912 struct vpnctl_socket_elem *sock_elem;
1913 struct bound_addr *bound_addr;
1914 u_int32_t address;
1915
1916 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
1917 LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
1918 LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
1919 if (bound_addr->address == address) {
1920 if (version = bound_addr->version)
1921 len += bound_addr->version->l;
1922 break;
1923 }
1924 }
1925 }
1926 }
1927 }
1928
1929 if ((buffer = vmalloc(len)) == NULL) {
1930 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1931 return -1;
1932 }
1933
1934 attrpl = (struct isakmp_pl_attr *)buffer->v;
1935 attrpl->h.len = htons(len);
1936 attrpl->type = ISAKMP_CFG_REQUEST;
1937 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1938
1939 attr = (struct isakmp_data *)(attrpl + 1);
1940
1941 for (i = 0; i < attrcount; i++) {
1942 switch (attrlist[i]) {
1943 case APPLICATION_VERSION:
1944 if (version) {
1945 attr->type = htons(attrlist[i]);
1946 attr->lorv = htons(version->l);
1947 memcpy(attr + 1, version->v, version->l);
1948 attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l);
1949 break;
1950 } else /* fall thru */;
1951 default:
1952 attr->type = htons(attrlist[i]);
1953 attr->lorv = htons(0);
1954 attr++;
1955 break;
1956 }
1957 }
1958
1959 plog(LLV_DEBUG, LOCATION, NULL,
1960 "Sending MODE_CFG REQUEST\n");
1961
1962 error = isakmp_cfg_send(iph1, buffer,
1963 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL);
1964
1965 vfree(buffer);
1966
1967 return error;
1968}
1969
1970static void
1971isakmp_cfg_getaddr4(attr, ip)
1972 struct isakmp_data *attr;
1973 struct in_addr *ip;
1974{
1975 size_t alen = ntohs(attr->lorv);
1976 in_addr_t *addr;
1977
1978 if (alen != sizeof(*ip)) {
1979 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1980 return;
1981 }
1982
1983 addr = (in_addr_t *)(attr + 1);
1984 ip->s_addr = *addr;
1985
1986 return;
1987}
1988
1989static void
1990isakmp_cfg_appendaddr4(attr, ip, num, max)
1991 struct isakmp_data *attr;
1992 struct in_addr *ip;
1993 int *num;
1994 int max;
1995{
1996 size_t alen = ntohs(attr->lorv);
1997 in_addr_t *addr;
1998
1999 if (alen != sizeof(*ip)) {
2000 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
2001 return;
2002 }
2003 if (*num == max) {
2004 plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
2005 return;
2006 }
2007
2008 addr = (in_addr_t *)(attr + 1);
2009 ip->s_addr = *addr;
2010 (*num)++;
2011
2012 return;
2013}
2014
2015static void
2016isakmp_cfg_getstring(attr, str)
2017 struct isakmp_data *attr;
2018 char *str;
2019{
2020 size_t alen = ntohs(attr->lorv);
2021 char *src;
2022 src = (char *)(attr + 1);
2023
2024 memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
2025
2026 return;
2027}
2028
2029#define IP_MAX 40
2030
2031void
2032isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
2033 char *dest;
2034 int count;
2035 void *addr;
2036 int withmask;
2037{
2038 int i;
2039 int p;
2040 int l;
2041 struct unity_network tmp;
2042 for(i = 0, p = 0; i < count; i++) {
2043 if(withmask == 1)
2044 l = sizeof(struct unity_network);
2045 else
2046 l = sizeof(struct in_addr);
2047 memcpy(&tmp, addr, l);
2048 addr += l;
2049 if((uint32_t)tmp.addr4.s_addr == 0)
2050 break;
2051
2052 inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
2053 p += strlen(dest + p);
2054 if(withmask == 1) {
2055 dest[p] = '/';
2056 p++;
2057 inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
2058 p += strlen(dest + p);
2059 }
2060 dest[p] = ' ';
2061 p++;
2062 }
2063 if(p > 0)
2064 dest[p-1] = '\0';
2065 else
2066 dest[0] = '\0';
2067}
2068
2069int
2070isakmp_cfg_setenv(iph1, envp, envc)
2071 struct ph1handle *iph1;
2072 char ***envp;
2073 int *envc;
2074{
2075 char addrstr[IP_MAX];
2076 char addrlist[IP_MAX * MAXNS + MAXNS];
2077 char *splitlist = addrlist;
2078 char defdom[MAXPATHLEN + 1];
2079 int cidr, tmp;
2080 char cidrstr[4];
2081 int i, p;
2082 int test;
2083
2084 plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
2085
2086 /*
2087 * Internal IPv4 address, either if
2088 * we are a client or a server.
2089 */
2090 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
2091#ifdef HAVE_LIBLDAP
2092 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2093#endif
2094#ifdef HAVE_LIBRADIUS
2095 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2096#endif
2097 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
2098 inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
2099 addrstr, IP_MAX);
2100 } else
2101 addrstr[0] = '\0';
2102
2103 if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
2104 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
2105 return -1;
2106 }
2107
2108 if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
2109 if (script_env_append(envp, envc, "XAUTH_USER",
2110 iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
2111 plog(LLV_ERROR, LOCATION, NULL,
2112 "Cannot set XAUTH_USER\n");
2113 return -1;
2114 }
2115 }
2116
2117 /* Internal IPv4 mask */
2118 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
2119 inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
2120 addrstr, IP_MAX);
2121 else
2122 addrstr[0] = '\0';
2123
2124 /*
2125 * During several releases, documentation adverised INTERNAL_NETMASK4
2126 * while code was using INTERNAL_MASK4. We now do both.
2127 */
2128
2129 if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
2130 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
2131 return -1;
2132 }
2133
2134 if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
2135 plog(LLV_ERROR, LOCATION, NULL,
2136 "Cannot set INTERNAL_NETMASK4\n");
2137 return -1;
2138 }
2139
2140 tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
2141 for (cidr = 0; tmp != 0; cidr++)
2142 tmp <<= 1;
2143 snprintf(cidrstr, 3, "%d", cidr);
2144
2145 if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
2146 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
2147 return -1;
2148 }
2149
2150 /* Internal IPv4 DNS */
2151 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
2152 /* First Internal IPv4 DNS (for compatibilty with older code */
2153 inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0],
2154 addrstr, IP_MAX);
2155
2156 /* Internal IPv4 DNS - all */
2157 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
2158 (void *)iph1->mode_cfg->dns4, 0);
2159 } else {
2160 addrstr[0] = '\0';
2161 addrlist[0] = '\0';
2162 }
2163
2164 if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
2165 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
2166 return -1;
2167 }
2168 if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
2169 plog(LLV_ERROR, LOCATION, NULL,
2170 "Cannot set INTERNAL_DNS4_LIST\n");
2171 return -1;
2172 }
2173
2174 /* Internal IPv4 WINS */
2175 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
2176 /*
2177 * First Internal IPv4 WINS
2178 * (for compatibilty with older code
2179 */
2180 inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0],
2181 addrstr, IP_MAX);
2182
2183 /* Internal IPv4 WINS - all */
2184 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
2185 (void *)iph1->mode_cfg->wins4, 0);
2186 } else {
2187 addrstr[0] = '\0';
2188 addrlist[0] = '\0';
2189 }
2190
2191 if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
2192 plog(LLV_ERROR, LOCATION, NULL,
2193 "Cannot set INTERNAL_WINS4\n");
2194 return -1;
2195 }
2196 if (script_env_append(envp, envc,
2197 "INTERNAL_WINS4_LIST", addrlist) != 0) {
2198 plog(LLV_ERROR, LOCATION, NULL,
2199 "Cannot set INTERNAL_WINS4_LIST\n");
2200 return -1;
2201 }
2202
2203 /* Deault domain */
2204 if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN)
2205 strlcpy(defdom,
2206 iph1->mode_cfg->default_domain,
2207 sizeof(defdom));
2208 else
2209 defdom[0] = '\0';
2210
2211 if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) {
2212 plog(LLV_ERROR, LOCATION, NULL,
2213 "Cannot set DEFAULT_DOMAIN\n");
2214 return -1;
2215 }
2216
2217 /* Split networks */
2218 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE)
2219 splitlist = splitnet_list_2str(iph1->mode_cfg->split_include);
2220 else {
2221 splitlist = addrlist;
2222 addrlist[0] = '\0';
2223 }
2224
2225 if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
2226 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
2227 return -1;
2228 }
2229 if (splitlist != addrlist)
2230 racoon_free(splitlist);
2231
2232 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL)
2233 splitlist = splitnet_list_2str(iph1->mode_cfg->split_local);
2234 else {
2235 splitlist = addrlist;
2236 addrlist[0] = '\0';
2237 }
2238
2239 if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
2240 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
2241 return -1;
2242 }
2243 if (splitlist != addrlist)
2244 racoon_free(splitlist);
2245
2246 return 0;
2247}
2248
2249int
2250isakmp_cfg_resize_pool(size)
2251 int size;
2252{
2253 struct isakmp_cfg_port *new_pool;
2254 size_t len;
2255 int i;
2256
2257 if (size == isakmp_cfg_config.pool_size)
2258 return 0;
2259
2260 plog(LLV_INFO, LOCATION, NULL,
2261 "Resize address pool from %zu to %d\n",
2262 isakmp_cfg_config.pool_size, size);
2263
2264 /* If a pool already exists, check if we can shrink it */
2265 if ((isakmp_cfg_config.port_pool != NULL) &&
2266 (size < isakmp_cfg_config.pool_size)) {
2267 for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
2268 if (isakmp_cfg_config.port_pool[i].used) {
2269 plog(LLV_ERROR, LOCATION, NULL,
2270 "resize pool from %zu to %d impossible "
2271 "port %d is in use\n",
2272 isakmp_cfg_config.pool_size, size, i);
2273 size = i;
2274 break;
2275 }
2276 }
2277 }
2278
2279 len = size * sizeof(*isakmp_cfg_config.port_pool);
2280 new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
2281 if (new_pool == NULL) {
2282 plog(LLV_ERROR, LOCATION, NULL,
2283 "resize pool from %zu to %d impossible: %s",
2284 isakmp_cfg_config.pool_size, size, strerror(errno));
2285 return -1;
2286 }
2287
2288 /* If size increase, intialize correctly the new records */
2289 if (size > isakmp_cfg_config.pool_size) {
2290 size_t unit;
2291 size_t old_size;
2292
2293 unit = sizeof(*isakmp_cfg_config.port_pool);
2294 old_size = isakmp_cfg_config.pool_size;
2295
2296 bzero((char *)new_pool + (old_size * unit),
2297 (size - old_size) * unit);
2298 }
2299
2300 isakmp_cfg_config.port_pool = new_pool;
2301 isakmp_cfg_config.pool_size = size;
2302
2303 return 0;
2304}
2305
2306int
2307isakmp_cfg_init(cold)
2308 int cold;
2309{
2310 int i;
2311 int error;
2312
2313 isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
2314 isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
2315 for (i = 0; i < MAXNS; i++)
2316 isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
2317 isakmp_cfg_config.dns4_index = 0;
2318 for (i = 0; i < MAXWINS; i++)
2319 isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
2320 isakmp_cfg_config.nbns4_index = 0;
2321 if (cold != ISAKMP_CFG_INIT_COLD) {
2322 if (isakmp_cfg_config.port_pool) {
2323 racoon_free(isakmp_cfg_config.port_pool);
2324 }
2325 }
2326 isakmp_cfg_config.port_pool = NULL;
2327 isakmp_cfg_config.pool_size = 0;
2328 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
2329 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
2330 if (cold != ISAKMP_CFG_INIT_COLD) {
2331 if (isakmp_cfg_config.grouplist != NULL) {
2332 for (i = 0; i < isakmp_cfg_config.groupcount; i++)
2333 racoon_free(isakmp_cfg_config.grouplist[i]);
2334 racoon_free(isakmp_cfg_config.grouplist);
2335 }
2336 }
2337 isakmp_cfg_config.grouplist = NULL;
2338 isakmp_cfg_config.groupcount = 0;
2339 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
2340 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
2341 isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
2342 strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
2343 sizeof(isakmp_cfg_config.default_domain));
2344 strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd));
2345
2346 if (cold != ISAKMP_CFG_INIT_COLD )
2347 if (isakmp_cfg_config.splitnet_list != NULL)
2348 splitnet_list_free(isakmp_cfg_config.splitnet_list,
2349 &isakmp_cfg_config.splitnet_count);
2350 isakmp_cfg_config.splitnet_list = NULL;
2351 isakmp_cfg_config.splitnet_count = 0;
2352 isakmp_cfg_config.splitnet_type = 0;
2353
2354 isakmp_cfg_config.pfs_group = 0;
2355 isakmp_cfg_config.save_passwd = 0;
2356
2357 if (cold != ISAKMP_CFG_INIT_COLD )
2358 if (isakmp_cfg_config.splitdns_list != NULL)
2359 racoon_free(isakmp_cfg_config.splitdns_list);
2360 isakmp_cfg_config.splitdns_list = NULL;
2361 isakmp_cfg_config.splitdns_len = 0;
2362
2363#if 0
2364 if (cold == ISAKMP_CFG_INIT_COLD) {
2365 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
2366 return error;
2367 }
2368#endif
2369
2370 return 0;
2371}
2372