]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/isakmp_cfg.c
c72600ac82abd29453a0c91a41fb3e06a5454c37
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_cfg.c
1 /* $NetBSD: isakmp_cfg.c,v 1.12.6.1 2007/06/07 20:06:34 manu Exp $ */
2
3 /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
4
5 /*
6 * Copyright (C) 2004-2006 Emmanuel Dreyfus
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #include <sys/queue.h>
40
41 #include <utmpx.h>
42 #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
115 struct isakmp_cfg_config isakmp_cfg_config;
116
117 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
118 static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
119 #if 0
120 static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
121 #endif
122 static vchar_t *isakmp_cfg_addr4(struct ph1handle *,
123 struct isakmp_data *, in_addr_t *);
124 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
125 static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
126 struct isakmp_data *, in_addr_t *, int);
127 static void isakmp_cfg_appendaddr4(struct isakmp_data *,
128 struct in_addr *, int *, int);
129 static void isakmp_cfg_getstring(struct isakmp_data *,char *);
130 void isakmp_cfg_iplist_to_str(char *, int, void *, int);
131
132 #define ISAKMP_CFG_LOGIN 1
133 #define ISAKMP_CFG_LOGOUT 2
134 static int isakmp_cfg_accounting(struct ph1handle *, int);
135 #ifdef HAVE_LIBRADIUS
136 static 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 */
143 void
144 isakmp_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));
302 out:
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
312 int
313 isakmp_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
355 int
356 isakmp_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
564 int
565 isakmp_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
753 end:
754 vfree(payload);
755
756 return error;
757 }
758
759 int
760 isakmp_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 remph1(iph1);
843 delph1(iph1);
844 iph1 = NULL;
845 }
846 vfree(payload);
847
848 /*
849 * If required, request ISAKMP mode config information: ignore rekeys
850 */
851 if ((iph1 != NULL) && (!iph1->is_rekey) && (iph1->rmconf->mode_cfg) && (error == 0))
852 error = isakmp_cfg_getconfig(iph1);
853
854 return error;
855 }
856
857
858 static vchar_t *
859 buffer_cat(s, append)
860 vchar_t *s;
861 vchar_t *append;
862 {
863 vchar_t *new;
864
865 new = vmalloc(s->l + append->l);
866 if (new == NULL) {
867 plog(LLV_ERROR, LOCATION, NULL,
868 "Cannot allocate memory\n");
869 return s;
870 }
871
872 memcpy(new->v, s->v, s->l);
873 memcpy(new->v + s->l, append->v, append->l);
874
875 vfree(s);
876 return new;
877 }
878
879 static vchar_t *
880 isakmp_cfg_net(iph1, attr)
881 struct ph1handle *iph1;
882 struct isakmp_data *attr;
883 {
884 int type;
885 int confsource;
886 in_addr_t addr4;
887
888 type = ntohs(attr->type);
889
890 /*
891 * Don't give an address to a peer that did not succeed Xauth
892 */
893 if (xauth_check(iph1) != 0) {
894 plog(LLV_ERROR, LOCATION, NULL,
895 "Attempt to start phase config whereas Xauth failed\n");
896 return NULL;
897 }
898
899 confsource = isakmp_cfg_config.confsource;
900 /*
901 * If we have to fall back to a local
902 * configuration source, we will jump
903 * back to this point.
904 */
905 retry_source:
906
907 switch(type) {
908 case INTERNAL_IP4_ADDRESS:
909 switch(confsource) {
910 #ifdef HAVE_LIBLDAP
911 case ISAKMP_CFG_CONF_LDAP:
912 if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
913 break;
914 plog(LLV_INFO, LOCATION, NULL,
915 "No IP from LDAP, using local pool\n");
916 /* FALLTHROUGH */
917 confsource = ISAKMP_CFG_CONF_LOCAL;
918 goto retry_source;
919 #endif
920 #ifdef HAVE_LIBRADIUS
921 case ISAKMP_CFG_CONF_RADIUS:
922 if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
923 && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
924 /*
925 * -2 is 255.255.255.254, RADIUS uses that
926 * to instruct the NAS to use a local pool
927 */
928 break;
929 plog(LLV_INFO, LOCATION, NULL,
930 "No IP from RADIUS, using local pool\n");
931 /* FALLTHROUGH */
932 confsource = ISAKMP_CFG_CONF_LOCAL;
933 goto retry_source;
934 #endif
935 case ISAKMP_CFG_CONF_LOCAL:
936 if (isakmp_cfg_getport(iph1) == -1) {
937 plog(LLV_ERROR, LOCATION, NULL,
938 "Port pool depleted\n");
939 break;
940 }
941
942 iph1->mode_cfg->addr4.s_addr =
943 htonl(ntohl(isakmp_cfg_config.network4)
944 + iph1->mode_cfg->port);
945 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
946 break;
947
948 default:
949 plog(LLV_ERROR, LOCATION, NULL,
950 "Unexpected confsource\n");
951 }
952
953 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
954 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
955
956 return isakmp_cfg_addr4(iph1,
957 attr, &iph1->mode_cfg->addr4.s_addr);
958 break;
959
960 case INTERNAL_IP4_NETMASK:
961 switch(confsource) {
962 #ifdef HAVE_LIBLDAP
963 case ISAKMP_CFG_CONF_LDAP:
964 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
965 break;
966 plog(LLV_INFO, LOCATION, NULL,
967 "No mask from LDAP, using local pool\n");
968 /* FALLTHROUGH */
969 confsource = ISAKMP_CFG_CONF_LOCAL;
970 goto retry_source;
971 #endif
972 #ifdef HAVE_LIBRADIUS
973 case ISAKMP_CFG_CONF_RADIUS:
974 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
975 break;
976 plog(LLV_INFO, LOCATION, NULL,
977 "No mask from RADIUS, using local pool\n");
978 /* FALLTHROUGH */
979 confsource = ISAKMP_CFG_CONF_LOCAL;
980 goto retry_source;
981 #endif
982 case ISAKMP_CFG_CONF_LOCAL:
983 iph1->mode_cfg->mask4.s_addr
984 = isakmp_cfg_config.netmask4;
985 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
986 break;
987
988 default:
989 plog(LLV_ERROR, LOCATION, NULL,
990 "Unexpected confsource\n");
991 }
992 return isakmp_cfg_addr4(iph1, attr,
993 &iph1->mode_cfg->mask4.s_addr);
994 break;
995
996 case INTERNAL_IP4_DNS:
997 return isakmp_cfg_addr4_list(iph1,
998 attr, &isakmp_cfg_config.dns4[0],
999 isakmp_cfg_config.dns4_index);
1000 break;
1001
1002 case INTERNAL_IP4_NBNS:
1003 return isakmp_cfg_addr4_list(iph1,
1004 attr, &isakmp_cfg_config.nbns4[0],
1005 isakmp_cfg_config.nbns4_index);
1006 break;
1007
1008 case INTERNAL_IP4_SUBNET:
1009 return isakmp_cfg_addr4(iph1,
1010 attr, &isakmp_cfg_config.network4);
1011 break;
1012
1013 default:
1014 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
1015 break;
1016 }
1017 return NULL;
1018 }
1019
1020 #if 0
1021 static vchar_t *
1022 isakmp_cfg_void(iph1, attr)
1023 struct ph1handle *iph1;
1024 struct isakmp_data *attr;
1025 {
1026 vchar_t *buffer;
1027 struct isakmp_data *new;
1028
1029 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1030 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1031 return NULL;
1032 }
1033
1034 new = (struct isakmp_data *)buffer->v;
1035
1036 new->type = attr->type;
1037 new->lorv = htons(0);
1038
1039 return buffer;
1040 }
1041 #endif
1042
1043 vchar_t *
1044 isakmp_cfg_copy(iph1, attr)
1045 struct ph1handle *iph1;
1046 struct isakmp_data *attr;
1047 {
1048 vchar_t *buffer;
1049 size_t len = 0;
1050
1051 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
1052 len = ntohs(attr->lorv);
1053
1054 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1055 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1056 return NULL;
1057 }
1058
1059 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
1060
1061 return buffer;
1062 }
1063
1064 vchar_t *
1065 isakmp_cfg_short(iph1, attr, value)
1066 struct ph1handle *iph1;
1067 struct isakmp_data *attr;
1068 int value;
1069 {
1070 vchar_t *buffer;
1071 struct isakmp_data *new;
1072 int type;
1073
1074 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1075 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1076 return NULL;
1077 }
1078
1079 new = (struct isakmp_data *)buffer->v;
1080 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1081
1082 new->type = htons(type | ISAKMP_GEN_TV);
1083 new->lorv = htons(value);
1084
1085 return buffer;
1086 }
1087
1088 vchar_t *
1089 isakmp_cfg_varlen(iph1, attr, string, len)
1090 struct ph1handle *iph1;
1091 struct isakmp_data *attr;
1092 char *string;
1093 size_t len;
1094 {
1095 vchar_t *buffer;
1096 struct isakmp_data *new;
1097 char *data;
1098
1099 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1100 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1101 return NULL;
1102 }
1103
1104 new = (struct isakmp_data *)buffer->v;
1105
1106 new->type = attr->type;
1107 new->lorv = htons(len);
1108 data = (char *)(new + 1);
1109
1110 memcpy(data, string, len);
1111
1112 return buffer;
1113 }
1114 vchar_t *
1115 isakmp_cfg_string(iph1, attr, string)
1116 struct ph1handle *iph1;
1117 struct isakmp_data *attr;
1118 char *string;
1119 {
1120 size_t len = strlen(string);
1121 return isakmp_cfg_varlen(iph1, attr, string, len);
1122 }
1123
1124 static vchar_t *
1125 isakmp_cfg_addr4(iph1, attr, addr)
1126 struct ph1handle *iph1;
1127 struct isakmp_data *attr;
1128 in_addr_t *addr;
1129 {
1130 vchar_t *buffer;
1131 struct isakmp_data *new;
1132 size_t len;
1133
1134 len = sizeof(*addr);
1135 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1136 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1137 return NULL;
1138 }
1139
1140 new = (struct isakmp_data *)buffer->v;
1141
1142 new->type = attr->type;
1143 new->lorv = htons(len);
1144 memcpy(new + 1, addr, len);
1145
1146 return buffer;
1147 }
1148
1149 static vchar_t *
1150 isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1151 struct ph1handle *iph1;
1152 struct isakmp_data *attr;
1153 in_addr_t *addr;
1154 int nbr;
1155 {
1156 int error = -1;
1157 vchar_t *buffer = NULL;
1158 vchar_t *bufone = NULL;
1159 struct isakmp_data *new;
1160 size_t len;
1161 int i;
1162
1163 len = sizeof(*addr);
1164 if ((buffer = vmalloc(0)) == NULL) {
1165 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1166 goto out;
1167 }
1168 for(i = 0; i < nbr; i++) {
1169 if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1170 plog(LLV_ERROR, LOCATION, NULL,
1171 "Cannot allocate memory\n");
1172 goto out;
1173 }
1174 new = (struct isakmp_data *)bufone->v;
1175 new->type = attr->type;
1176 new->lorv = htons(len);
1177 memcpy(new + 1, &addr[i], len);
1178 new += (len + sizeof(*attr));
1179 buffer = buffer_cat(buffer, bufone);
1180 vfree(bufone);
1181 }
1182
1183 error = 0;
1184
1185 out:
1186 if ((error != 0) && (buffer != NULL)) {
1187 vfree(buffer);
1188 buffer = NULL;
1189 }
1190
1191 return buffer;
1192 }
1193
1194 struct isakmp_ivm *
1195 isakmp_cfg_newiv(iph1, msgid)
1196 struct ph1handle *iph1;
1197 u_int32_t msgid;
1198 {
1199 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1200
1201 if (ics == NULL) {
1202 plog(LLV_ERROR, LOCATION, NULL,
1203 "isakmp_cfg_newiv called without mode config state\n");
1204 return NULL;
1205 }
1206
1207 if (ics->ivm != NULL)
1208 oakley_delivm(ics->ivm);
1209
1210 ics->ivm = oakley_newiv2(iph1, msgid);
1211 ics->last_msgid = msgid;
1212
1213 return ics->ivm;
1214 }
1215
1216 /* Derived from isakmp_info_send_common */
1217 int
1218 isakmp_cfg_send(iph1, payload, np, flags, new_exchange, retry_count, msg)
1219 struct ph1handle *iph1;
1220 vchar_t *payload;
1221 u_int32_t np;
1222 int flags;
1223 int new_exchange;
1224 int retry_count;
1225 vchar_t *msg;
1226 {
1227 struct ph2handle *iph2 = NULL;
1228 vchar_t *hash = NULL;
1229 struct isakmp *isakmp;
1230 struct isakmp_gen *gen;
1231 char *p;
1232 int tlen;
1233 int error = -1;
1234 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1235
1236 /* Check if phase 1 is established */
1237 if ((iph1->status != PHASE1ST_ESTABLISHED) ||
1238 (iph1->local == NULL) ||
1239 (iph1->remote == NULL)) {
1240 plog(LLV_ERROR, LOCATION, NULL,
1241 "ISAKMP mode config exchange with immature phase 1\n");
1242 goto end;
1243 }
1244
1245 /* add new entry to isakmp status table */
1246 iph2 = newph2();
1247 if (iph2 == NULL) {
1248 plog(LLV_ERROR, LOCATION, NULL,
1249 "failed to allocate ph2");
1250 goto end;
1251 }
1252
1253 iph2->dst = dupsaddr(iph1->remote);
1254 if (iph2->dst == NULL) {
1255 plog(LLV_ERROR, LOCATION, NULL,
1256 "failed to duplicate remote address");
1257 delph2(iph2);
1258 goto end;
1259 }
1260 iph2->src = dupsaddr(iph1->local);
1261 if (iph2->src == NULL) {
1262 plog(LLV_ERROR, LOCATION, NULL,
1263 "failed to duplicate local address");
1264 delph2(iph2);
1265 goto end;
1266 }
1267
1268 switch (iph1->remote->sa_family) {
1269 case AF_INET:
1270 #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1271 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1272 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1273 #endif
1274 break;
1275 #ifdef INET6
1276 case AF_INET6:
1277 #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1278 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1279 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
1280 #endif
1281 break;
1282 #endif
1283 default:
1284 plog(LLV_ERROR, LOCATION, NULL,
1285 "invalid family: %d\n", iph1->remote->sa_family);
1286 delph2(iph2);
1287 goto end;
1288 }
1289 iph2->ph1 = iph1;
1290 iph2->side = INITIATOR;
1291 iph2->status = PHASE2ST_START;
1292
1293 if (new_exchange)
1294 iph2->msgid = isakmp_newmsgid2(iph1);
1295 else
1296 iph2->msgid = iph1->msgid;
1297
1298 /* get IV and HASH(1) if skeyid_a was generated. */
1299 if (iph1->skeyid_a != NULL) {
1300 if (new_exchange) {
1301 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1302 plog(LLV_ERROR, LOCATION, NULL,
1303 "failed to generate IV");
1304 delph2(iph2);
1305 goto end;
1306 }
1307 }
1308
1309 /* generate HASH(1) */
1310 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
1311 if (hash == NULL) {
1312 plog(LLV_ERROR, LOCATION, NULL,
1313 "failed to generate HASH");
1314 delph2(iph2);
1315 goto end;
1316 }
1317
1318 /* initialized total buffer length */
1319 tlen = hash->l;
1320 tlen += sizeof(*gen);
1321 } else {
1322 /* IKE-SA is not established */
1323 hash = NULL;
1324
1325 /* initialized total buffer length */
1326 tlen = 0;
1327 }
1328 if ((flags & ISAKMP_FLAG_A) == 0)
1329 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1330 else
1331 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1332
1333 insph2(iph2);
1334 bindph12(iph1, iph2);
1335
1336 tlen += sizeof(*isakmp) + payload->l;
1337
1338 /* create buffer for isakmp payload */
1339 iph2->sendbuf = vmalloc(tlen);
1340 if (iph2->sendbuf == NULL) {
1341 plog(LLV_ERROR, LOCATION, NULL,
1342 "failed to get buffer to send.\n");
1343 goto err;
1344 }
1345
1346 /* create isakmp header */
1347 isakmp = (struct isakmp *)iph2->sendbuf->v;
1348 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1349 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1350 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1351 isakmp->v = iph1->version;
1352 isakmp->etype = ISAKMP_ETYPE_CFG;
1353 isakmp->flags = iph2->flags;
1354 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1355 isakmp->len = htonl(tlen);
1356 p = (char *)(isakmp + 1);
1357
1358 /* create HASH payload */
1359 if (hash != NULL) {
1360 gen = (struct isakmp_gen *)p;
1361 gen->np = np & 0xff;
1362 gen->len = htons(sizeof(*gen) + hash->l);
1363 p += sizeof(*gen);
1364 memcpy(p, hash->v, hash->l);
1365 p += hash->l;
1366 }
1367
1368 /* add payload */
1369 memcpy(p, payload->v, payload->l);
1370 p += payload->l;
1371
1372 #ifdef HAVE_PRINT_ISAKMP_C
1373 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1374 #endif
1375
1376 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
1377 plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
1378
1379 /* encoding */
1380 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1381 vchar_t *tmp;
1382
1383 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1384 ics->ivm->ive, ics->ivm->iv);
1385 VPTRINIT(iph2->sendbuf);
1386 if (tmp == NULL) {
1387 plog(LLV_ERROR, LOCATION, NULL,
1388 "failed to encrypt packet");
1389 goto err;
1390 }
1391 iph2->sendbuf = tmp;
1392 }
1393
1394 /* HDR*, HASH(1), ATTR */
1395
1396 if (retry_count > 0) {
1397 iph2->retry_counter = retry_count;
1398 if (isakmp_ph2resend(iph2) < 0) {
1399 plog(LLV_ERROR, LOCATION, NULL,
1400 "failed to resend packet");
1401 VPTRINIT(iph2->sendbuf);
1402 goto err;
1403 }
1404 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1405 IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT,
1406 CONSTSTR("Mode-Config retransmit"),
1407 CONSTSTR(NULL));
1408 error = 0;
1409 goto end;
1410 }
1411
1412 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1413 plog(LLV_ERROR, LOCATION, NULL,
1414 "failed to send packet");
1415 VPTRINIT(iph2->sendbuf);
1416 goto err;
1417 }
1418 if (msg) {
1419 /* the sending message is added to the received-list. */
1420 if (add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg,
1421 PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
1422 plog(LLV_ERROR , LOCATION, NULL,
1423 "failed to add a response packet to the tree.\n");
1424 }
1425 }
1426
1427 plog(LLV_DEBUG, LOCATION, NULL,
1428 "sendto mode config %s.\n", s_isakmp_nptype(np));
1429
1430 /*
1431 * XXX We might need to resend the message...
1432 */
1433
1434 error = 0;
1435 VPTRINIT(iph2->sendbuf);
1436
1437 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1438 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
1439 CONSTSTR("Mode-Config message"),
1440 CONSTSTR(NULL));
1441
1442 err:
1443 if (error) {
1444 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1445 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
1446 CONSTSTR("Mode-Config message"),
1447 CONSTSTR("Failed to transmit Mode-Config message"));
1448 }
1449 unbindph12(iph2);
1450 remph2(iph2);
1451 delph2(iph2);
1452 end:
1453 if (hash)
1454 vfree(hash);
1455 return error;
1456 }
1457
1458
1459 void
1460 isakmp_cfg_rmstate(iph1)
1461 struct ph1handle *iph1;
1462 {
1463 struct isakmp_cfg_state *state = iph1->mode_cfg;
1464
1465 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1466 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1467
1468 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1469 isakmp_cfg_putport(iph1, state->port);
1470
1471 /* Delete the IV if it's still there */
1472 if(iph1->mode_cfg->ivm) {
1473 oakley_delivm(iph1->mode_cfg->ivm);
1474 iph1->mode_cfg->ivm = NULL;
1475 }
1476
1477 /* Free any allocated splitnet lists */
1478 if(iph1->mode_cfg->split_include != NULL)
1479 splitnet_list_free(iph1->mode_cfg->split_include,
1480 &iph1->mode_cfg->include_count);
1481 if(iph1->mode_cfg->split_local != NULL)
1482 splitnet_list_free(iph1->mode_cfg->split_local,
1483 &iph1->mode_cfg->local_count);
1484
1485 xauth_rmstate(&state->xauth);
1486
1487 if (state->attr_list)
1488 vfree(state->attr_list);
1489
1490 racoon_free(state);
1491 iph1->mode_cfg = NULL;
1492
1493 return;
1494 }
1495
1496 struct isakmp_cfg_state *
1497 isakmp_cfg_mkstate(void)
1498 {
1499 struct isakmp_cfg_state *state;
1500
1501 if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1502 plog(LLV_ERROR, LOCATION, NULL,
1503 "Cannot allocate memory for mode config state\n");
1504 return NULL;
1505 }
1506 memset(state, 0, sizeof(*state));
1507
1508 return state;
1509 }
1510
1511 int
1512 isakmp_cfg_getport(iph1)
1513 struct ph1handle *iph1;
1514 {
1515 unsigned int i;
1516 size_t size = isakmp_cfg_config.pool_size;
1517
1518 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1519 return iph1->mode_cfg->port;
1520
1521 if (isakmp_cfg_config.port_pool == NULL) {
1522 plog(LLV_ERROR, LOCATION, NULL,
1523 "isakmp_cfg_config.port_pool == NULL\n");
1524 return -1;
1525 }
1526
1527 for (i = 0; i < size; i++) {
1528 if (isakmp_cfg_config.port_pool[i].used == 0)
1529 break;
1530 }
1531
1532 if (i == size) {
1533 plog(LLV_ERROR, LOCATION, NULL,
1534 "No more addresses available\n");
1535 return -1;
1536 }
1537
1538 isakmp_cfg_config.port_pool[i].used = 1;
1539
1540 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1541
1542 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1543 iph1->mode_cfg->port = i;
1544
1545 return i;
1546 }
1547
1548 int
1549 isakmp_cfg_putport(iph1, index)
1550 struct ph1handle *iph1;
1551 unsigned int index;
1552 {
1553 if (isakmp_cfg_config.port_pool == NULL) {
1554 plog(LLV_ERROR, LOCATION, NULL,
1555 "isakmp_cfg_config.port_pool == NULL\n");
1556 return -1;
1557 }
1558
1559 if (isakmp_cfg_config.port_pool[index].used == 0) {
1560 plog(LLV_ERROR, LOCATION, NULL,
1561 "Attempt to release an unallocated address (port %d)\n",
1562 index);
1563 return -1;
1564 }
1565
1566 #ifdef HAVE_LIBPAM
1567 /* Cleanup PAM status associated with the port */
1568 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1569 privsep_cleanup_pam(index);
1570 #endif
1571 isakmp_cfg_config.port_pool[index].used = 0;
1572 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1573
1574 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1575
1576 return 0;
1577 }
1578
1579 #ifdef HAVE_LIBPAM
1580 void
1581 cleanup_pam(port)
1582 int port;
1583 {
1584 if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1585 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1586 isakmp_cfg_config.port_pool[port].pam = NULL;
1587 }
1588
1589 return;
1590 }
1591 #endif
1592
1593 /* Accounting, only for RADIUS or PAM */
1594 static int
1595 isakmp_cfg_accounting(iph1, inout)
1596 struct ph1handle *iph1;
1597 int inout;
1598 {
1599 #ifdef HAVE_LIBPAM
1600 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1601 return privsep_accounting_pam(iph1->mode_cfg->port,
1602 inout);
1603 #endif
1604 #ifdef HAVE_LIBRADIUS
1605 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1606 return isakmp_cfg_accounting_radius(iph1, inout);
1607 #endif
1608 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
1609 return privsep_accounting_system(iph1->mode_cfg->port,
1610 iph1->remote, iph1->mode_cfg->login, inout);
1611 return 0;
1612 }
1613
1614 #ifdef HAVE_LIBPAM
1615 int
1616 isakmp_cfg_accounting_pam(port, inout)
1617 int port;
1618 int inout;
1619 {
1620 int error = 0;
1621 pam_handle_t *pam;
1622
1623 if (isakmp_cfg_config.port_pool == NULL) {
1624 plog(LLV_ERROR, LOCATION, NULL,
1625 "isakmp_cfg_config.port_pool == NULL\n");
1626 return -1;
1627 }
1628
1629 pam = isakmp_cfg_config.port_pool[port].pam;
1630 if (pam == NULL) {
1631 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1632 return -1;
1633 }
1634
1635 switch (inout) {
1636 case ISAKMP_CFG_LOGIN:
1637 error = pam_open_session(pam, 0);
1638 break;
1639 case ISAKMP_CFG_LOGOUT:
1640 error = pam_close_session(pam, 0);
1641 pam_end(pam, error);
1642 isakmp_cfg_config.port_pool[port].pam = NULL;
1643 break;
1644 default:
1645 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1646 break;
1647 }
1648
1649 if (error != 0) {
1650 plog(LLV_ERROR, LOCATION, NULL,
1651 "pam_open_session/pam_close_session failed: %s\n",
1652 pam_strerror(pam, error));
1653 return -1;
1654 }
1655
1656 return 0;
1657 }
1658 #endif /* HAVE_LIBPAM */
1659
1660 #ifdef HAVE_LIBRADIUS
1661 static int
1662 isakmp_cfg_accounting_radius(iph1, inout)
1663 struct ph1handle *iph1;
1664 int inout;
1665 {
1666 /* For first time use, initialize Radius */
1667 if (radius_acct_state == NULL) {
1668 if ((radius_acct_state = rad_acct_open()) == NULL) {
1669 plog(LLV_ERROR, LOCATION, NULL,
1670 "Cannot init librradius\n");
1671 return -1;
1672 }
1673
1674 if (rad_config(radius_acct_state, NULL) != 0) {
1675 plog(LLV_ERROR, LOCATION, NULL,
1676 "Cannot open librarius config file: %s\n",
1677 rad_strerror(radius_acct_state));
1678 rad_close(radius_acct_state);
1679 radius_acct_state = NULL;
1680 return -1;
1681 }
1682 }
1683
1684 if (rad_create_request(radius_acct_state,
1685 RAD_ACCOUNTING_REQUEST) != 0) {
1686 plog(LLV_ERROR, LOCATION, NULL,
1687 "rad_create_request failed: %s\n",
1688 rad_strerror(radius_acct_state));
1689 return -1;
1690 }
1691
1692 if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1693 iph1->mode_cfg->login) != 0) {
1694 plog(LLV_ERROR, LOCATION, NULL,
1695 "rad_put_string failed: %s\n",
1696 rad_strerror(radius_acct_state));
1697 return -1;
1698 }
1699
1700 switch (inout) {
1701 case ISAKMP_CFG_LOGIN:
1702 inout = RAD_START;
1703 break;
1704 case ISAKMP_CFG_LOGOUT:
1705 inout = RAD_STOP;
1706 break;
1707 default:
1708 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1709 break;
1710 }
1711
1712 if (rad_put_addr(radius_acct_state,
1713 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1714 plog(LLV_ERROR, LOCATION, NULL,
1715 "rad_put_addr failed: %s\n",
1716 rad_strerror(radius_acct_state));
1717 return -1;
1718 }
1719
1720 if (rad_put_addr(radius_acct_state,
1721 RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1722 plog(LLV_ERROR, LOCATION, NULL,
1723 "rad_put_addr failed: %s\n",
1724 rad_strerror(radius_acct_state));
1725 return -1;
1726 }
1727
1728 if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1729 plog(LLV_ERROR, LOCATION, NULL,
1730 "rad_put_int failed: %s\n",
1731 rad_strerror(radius_acct_state));
1732 return -1;
1733 }
1734
1735 if (isakmp_cfg_radius_common(radius_acct_state,
1736 iph1->mode_cfg->port) != 0)
1737 return -1;
1738
1739 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1740 plog(LLV_ERROR, LOCATION, NULL,
1741 "rad_send_request failed: %s\n",
1742 rad_strerror(radius_acct_state));
1743 return -1;
1744 }
1745
1746 return 0;
1747 }
1748 #endif /* HAVE_LIBRADIUS */
1749
1750 /*
1751 * Attributes common to all RADIUS requests
1752 */
1753 #ifdef HAVE_LIBRADIUS
1754 int
1755 isakmp_cfg_radius_common(radius_state, port)
1756 struct rad_handle *radius_state;
1757 int port;
1758 {
1759 struct utsname name;
1760 static struct hostent *host = NULL;
1761 struct in_addr nas_addr;
1762
1763 /*
1764 * Find our own IP by resolving our nodename
1765 */
1766 if (host == NULL) {
1767 if (uname(&name) != 0) {
1768 plog(LLV_ERROR, LOCATION, NULL,
1769 "uname failed: %s\n", strerror(errno));
1770 return -1;
1771 }
1772
1773 if ((host = gethostbyname(name.nodename)) == NULL) {
1774 plog(LLV_ERROR, LOCATION, NULL,
1775 "gethostbyname failed: %s\n", strerror(errno));
1776 return -1;
1777 }
1778 }
1779
1780 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1781 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1782 plog(LLV_ERROR, LOCATION, NULL,
1783 "rad_put_addr failed: %s\n",
1784 rad_strerror(radius_state));
1785 return -1;
1786 }
1787
1788 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1789 plog(LLV_ERROR, LOCATION, NULL,
1790 "rad_put_int failed: %s\n",
1791 rad_strerror(radius_state));
1792 return -1;
1793 }
1794
1795 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1796 plog(LLV_ERROR, LOCATION, NULL,
1797 "rad_put_int failed: %s\n",
1798 rad_strerror(radius_state));
1799 return -1;
1800 }
1801
1802 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1803 plog(LLV_ERROR, LOCATION, NULL,
1804 "rad_put_int failed: %s\n",
1805 rad_strerror(radius_state));
1806 return -1;
1807 }
1808
1809 return 0;
1810 }
1811 #endif
1812
1813 /*
1814 Logs the user into the utmp system files.
1815 */
1816
1817 int
1818 isakmp_cfg_accounting_system(port, raddr, usr, inout)
1819 int port;
1820 struct sockaddr *raddr;
1821 char *usr;
1822 int inout;
1823 {
1824 int error = 0;
1825 struct utmpx ut;
1826 char term[_UTX_LINESIZE];
1827 char addr[NI_MAXHOST];
1828
1829 if (usr == NULL || usr[0]=='\0') {
1830 plog(LLV_ERROR, LOCATION, NULL,
1831 "system accounting : no login found\n");
1832 return -1;
1833 }
1834
1835 snprintf(term, sizeof(term), TERMSPEC, port);
1836
1837 switch (inout) {
1838 case ISAKMP_CFG_LOGIN:
1839 strlcpy(ut.ut_user, usr, sizeof(ut.ut_user));
1840
1841 strlcpy(ut.ut_line, term, sizeof(ut.ut_line));
1842
1843 GETNAMEINFO_NULL(raddr, addr);
1844 strlcpy(ut.ut_host, addr, sizeof(ut.ut_host));
1845
1846 ut.ut_pid = getpid();
1847
1848 ut.ut_type = UTMPX_AUTOFILL_MASK | USER_PROCESS;
1849
1850 gettimeofday(&ut.ut_tv, NULL);
1851
1852 plog(LLV_INFO, LOCATION, NULL,
1853 "Accounting : '%s' logging on '%s' from %s.\n",
1854 ut.ut_user, ut.ut_line, ut.ut_host);
1855
1856 if (pututxline(&ut) == NULL)
1857 return -1;
1858
1859 break;
1860 case ISAKMP_CFG_LOGOUT:
1861
1862 plog(LLV_INFO, LOCATION, NULL,
1863 "Accounting : '%s' unlogging from '%s'.\n",
1864 usr, term);
1865
1866 ut.ut_type = UTMPX_AUTOFILL_MASK | DEAD_PROCESS;
1867
1868 gettimeofday(&ut.ut_tv, NULL);
1869
1870 if (pututxline(&ut) == NULL)
1871 return -1;
1872
1873 break;
1874 default:
1875 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1876 break;
1877 }
1878
1879 return 0;
1880 }
1881
1882 int
1883 isakmp_cfg_getconfig(iph1)
1884 struct ph1handle *iph1;
1885 {
1886 vchar_t *buffer;
1887 struct isakmp_pl_attr *attrpl;
1888 struct isakmp_data *attr;
1889 size_t len;
1890 vchar_t *version = NULL;
1891 int error;
1892 int attrcount;
1893 int i;
1894 int attrlist[] = {
1895 INTERNAL_IP4_ADDRESS,
1896 INTERNAL_IP4_NETMASK,
1897 INTERNAL_IP4_DNS,
1898 INTERNAL_IP4_NBNS,
1899 INTERNAL_ADDRESS_EXPIRY,
1900 APPLICATION_VERSION,
1901 UNITY_BANNER,
1902 UNITY_DEF_DOMAIN,
1903 UNITY_SPLITDNS_NAME,
1904 UNITY_SPLIT_INCLUDE,
1905 UNITY_LOCAL_LAN,
1906 };
1907
1908 attrcount = sizeof(attrlist) / sizeof(*attrlist);
1909 len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1910
1911 if (iph1->started_by_api) {
1912 if (iph1->remote->sa_family == AF_INET) {
1913 struct vpnctl_socket_elem *sock_elem;
1914 struct bound_addr *bound_addr;
1915 u_int32_t address;
1916
1917 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
1918 LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
1919 LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
1920 if (bound_addr->address == address) {
1921 if (version = bound_addr->version)
1922 len += bound_addr->version->l;
1923 break;
1924 }
1925 }
1926 }
1927 }
1928 }
1929
1930 if ((buffer = vmalloc(len)) == NULL) {
1931 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1932 return -1;
1933 }
1934
1935 attrpl = (struct isakmp_pl_attr *)buffer->v;
1936 attrpl->h.len = htons(len);
1937 attrpl->type = ISAKMP_CFG_REQUEST;
1938 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1939
1940 attr = (struct isakmp_data *)(attrpl + 1);
1941
1942 for (i = 0; i < attrcount; i++) {
1943 switch (attrlist[i]) {
1944 case APPLICATION_VERSION:
1945 if (version) {
1946 attr->type = htons(attrlist[i]);
1947 attr->lorv = htons(version->l);
1948 memcpy(attr + 1, version->v, version->l);
1949 attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l);
1950 break;
1951 } else /* fall thru */;
1952 default:
1953 attr->type = htons(attrlist[i]);
1954 attr->lorv = htons(0);
1955 attr++;
1956 break;
1957 }
1958 }
1959
1960 plog(LLV_DEBUG, LOCATION, NULL,
1961 "Sending MODE_CFG REQUEST\n");
1962
1963 error = isakmp_cfg_send(iph1, buffer,
1964 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL);
1965
1966 vfree(buffer);
1967
1968 return error;
1969 }
1970
1971 static void
1972 isakmp_cfg_getaddr4(attr, ip)
1973 struct isakmp_data *attr;
1974 struct in_addr *ip;
1975 {
1976 size_t alen = ntohs(attr->lorv);
1977 in_addr_t *addr;
1978
1979 if (alen != sizeof(*ip)) {
1980 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1981 return;
1982 }
1983
1984 addr = (in_addr_t *)(attr + 1);
1985 ip->s_addr = *addr;
1986
1987 return;
1988 }
1989
1990 static void
1991 isakmp_cfg_appendaddr4(attr, ip, num, max)
1992 struct isakmp_data *attr;
1993 struct in_addr *ip;
1994 int *num;
1995 int max;
1996 {
1997 size_t alen = ntohs(attr->lorv);
1998 in_addr_t *addr;
1999
2000 if (alen != sizeof(*ip)) {
2001 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
2002 return;
2003 }
2004 if (*num == max) {
2005 plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
2006 return;
2007 }
2008
2009 addr = (in_addr_t *)(attr + 1);
2010 ip->s_addr = *addr;
2011 (*num)++;
2012
2013 return;
2014 }
2015
2016 static void
2017 isakmp_cfg_getstring(attr, str)
2018 struct isakmp_data *attr;
2019 char *str;
2020 {
2021 size_t alen = ntohs(attr->lorv);
2022 char *src;
2023 src = (char *)(attr + 1);
2024
2025 memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
2026
2027 return;
2028 }
2029
2030 #define IP_MAX 40
2031
2032 void
2033 isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
2034 char *dest;
2035 int count;
2036 void *addr;
2037 int withmask;
2038 {
2039 int i;
2040 int p;
2041 int l;
2042 struct unity_network tmp;
2043 for(i = 0, p = 0; i < count; i++) {
2044 if(withmask == 1)
2045 l = sizeof(struct unity_network);
2046 else
2047 l = sizeof(struct in_addr);
2048 memcpy(&tmp, addr, l);
2049 addr += l;
2050 if((uint32_t)tmp.addr4.s_addr == 0)
2051 break;
2052
2053 inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
2054 p += strlen(dest + p);
2055 if(withmask == 1) {
2056 dest[p] = '/';
2057 p++;
2058 inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
2059 p += strlen(dest + p);
2060 }
2061 dest[p] = ' ';
2062 p++;
2063 }
2064 if(p > 0)
2065 dest[p-1] = '\0';
2066 else
2067 dest[0] = '\0';
2068 }
2069
2070 int
2071 isakmp_cfg_setenv(iph1, envp, envc)
2072 struct ph1handle *iph1;
2073 char ***envp;
2074 int *envc;
2075 {
2076 char addrstr[IP_MAX];
2077 char addrlist[IP_MAX * MAXNS + MAXNS];
2078 char *splitlist = addrlist;
2079 char defdom[MAXPATHLEN + 1];
2080 int cidr, tmp;
2081 char cidrstr[4];
2082 int i, p;
2083 int test;
2084
2085 plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
2086
2087 /*
2088 * Internal IPv4 address, either if
2089 * we are a client or a server.
2090 */
2091 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
2092 #ifdef HAVE_LIBLDAP
2093 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2094 #endif
2095 #ifdef HAVE_LIBRADIUS
2096 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2097 #endif
2098 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
2099 inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
2100 addrstr, IP_MAX);
2101 } else
2102 addrstr[0] = '\0';
2103
2104 if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
2105 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
2106 return -1;
2107 }
2108
2109 if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
2110 if (script_env_append(envp, envc, "XAUTH_USER",
2111 iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
2112 plog(LLV_ERROR, LOCATION, NULL,
2113 "Cannot set XAUTH_USER\n");
2114 return -1;
2115 }
2116 }
2117
2118 /* Internal IPv4 mask */
2119 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
2120 inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
2121 addrstr, IP_MAX);
2122 else
2123 addrstr[0] = '\0';
2124
2125 /*
2126 * During several releases, documentation adverised INTERNAL_NETMASK4
2127 * while code was using INTERNAL_MASK4. We now do both.
2128 */
2129
2130 if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
2131 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
2132 return -1;
2133 }
2134
2135 if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
2136 plog(LLV_ERROR, LOCATION, NULL,
2137 "Cannot set INTERNAL_NETMASK4\n");
2138 return -1;
2139 }
2140
2141 tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
2142 for (cidr = 0; tmp != 0; cidr++)
2143 tmp <<= 1;
2144 snprintf(cidrstr, 3, "%d", cidr);
2145
2146 if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
2147 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
2148 return -1;
2149 }
2150
2151 /* Internal IPv4 DNS */
2152 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
2153 /* First Internal IPv4 DNS (for compatibilty with older code */
2154 inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0],
2155 addrstr, IP_MAX);
2156
2157 /* Internal IPv4 DNS - all */
2158 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
2159 (void *)iph1->mode_cfg->dns4, 0);
2160 } else {
2161 addrstr[0] = '\0';
2162 addrlist[0] = '\0';
2163 }
2164
2165 if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
2166 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
2167 return -1;
2168 }
2169 if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
2170 plog(LLV_ERROR, LOCATION, NULL,
2171 "Cannot set INTERNAL_DNS4_LIST\n");
2172 return -1;
2173 }
2174
2175 /* Internal IPv4 WINS */
2176 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
2177 /*
2178 * First Internal IPv4 WINS
2179 * (for compatibilty with older code
2180 */
2181 inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0],
2182 addrstr, IP_MAX);
2183
2184 /* Internal IPv4 WINS - all */
2185 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
2186 (void *)iph1->mode_cfg->wins4, 0);
2187 } else {
2188 addrstr[0] = '\0';
2189 addrlist[0] = '\0';
2190 }
2191
2192 if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
2193 plog(LLV_ERROR, LOCATION, NULL,
2194 "Cannot set INTERNAL_WINS4\n");
2195 return -1;
2196 }
2197 if (script_env_append(envp, envc,
2198 "INTERNAL_WINS4_LIST", addrlist) != 0) {
2199 plog(LLV_ERROR, LOCATION, NULL,
2200 "Cannot set INTERNAL_WINS4_LIST\n");
2201 return -1;
2202 }
2203
2204 /* Deault domain */
2205 if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN)
2206 strlcpy(defdom,
2207 iph1->mode_cfg->default_domain,
2208 sizeof(defdom));
2209 else
2210 defdom[0] = '\0';
2211
2212 if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) {
2213 plog(LLV_ERROR, LOCATION, NULL,
2214 "Cannot set DEFAULT_DOMAIN\n");
2215 return -1;
2216 }
2217
2218 /* Split networks */
2219 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE)
2220 splitlist = splitnet_list_2str(iph1->mode_cfg->split_include);
2221 else {
2222 splitlist = addrlist;
2223 addrlist[0] = '\0';
2224 }
2225
2226 if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
2227 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
2228 return -1;
2229 }
2230 if (splitlist != addrlist)
2231 racoon_free(splitlist);
2232
2233 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL)
2234 splitlist = splitnet_list_2str(iph1->mode_cfg->split_local);
2235 else {
2236 splitlist = addrlist;
2237 addrlist[0] = '\0';
2238 }
2239
2240 if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
2241 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
2242 return -1;
2243 }
2244 if (splitlist != addrlist)
2245 racoon_free(splitlist);
2246
2247 return 0;
2248 }
2249
2250 int
2251 isakmp_cfg_resize_pool(size)
2252 int size;
2253 {
2254 struct isakmp_cfg_port *new_pool;
2255 size_t len;
2256 int i;
2257
2258 if (size == isakmp_cfg_config.pool_size)
2259 return 0;
2260
2261 plog(LLV_INFO, LOCATION, NULL,
2262 "Resize address pool from %zu to %d\n",
2263 isakmp_cfg_config.pool_size, size);
2264
2265 /* If a pool already exists, check if we can shrink it */
2266 if ((isakmp_cfg_config.port_pool != NULL) &&
2267 (size < isakmp_cfg_config.pool_size)) {
2268 for (i = isakmp_cfg_config.pool_size; i >= size; --i) {
2269 if (isakmp_cfg_config.port_pool[i].used) {
2270 plog(LLV_ERROR, LOCATION, NULL,
2271 "resize pool from %zu to %d impossible "
2272 "port %d is in use\n",
2273 isakmp_cfg_config.pool_size, size, i);
2274 size = i;
2275 break;
2276 }
2277 }
2278 }
2279
2280 len = size * sizeof(*isakmp_cfg_config.port_pool);
2281 new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
2282 if (new_pool == NULL) {
2283 plog(LLV_ERROR, LOCATION, NULL,
2284 "resize pool from %zu to %d impossible: %s",
2285 isakmp_cfg_config.pool_size, size, strerror(errno));
2286 return -1;
2287 }
2288
2289 /* If size increase, intialize correctly the new records */
2290 if (size > isakmp_cfg_config.pool_size) {
2291 size_t unit;
2292 size_t old_size;
2293
2294 unit = sizeof(*isakmp_cfg_config.port_pool);
2295 old_size = isakmp_cfg_config.pool_size;
2296
2297 bzero((char *)new_pool + (old_size * unit),
2298 (size - old_size) * unit);
2299 }
2300
2301 isakmp_cfg_config.port_pool = new_pool;
2302 isakmp_cfg_config.pool_size = size;
2303
2304 return 0;
2305 }
2306
2307 int
2308 isakmp_cfg_init(cold)
2309 int cold;
2310 {
2311 int i;
2312 int error;
2313
2314 isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
2315 isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
2316 for (i = 0; i < MAXNS; i++)
2317 isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
2318 isakmp_cfg_config.dns4_index = 0;
2319 for (i = 0; i < MAXWINS; i++)
2320 isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
2321 isakmp_cfg_config.nbns4_index = 0;
2322 if (cold != ISAKMP_CFG_INIT_COLD) {
2323 if (isakmp_cfg_config.port_pool) {
2324 racoon_free(isakmp_cfg_config.port_pool);
2325 }
2326 }
2327 isakmp_cfg_config.port_pool = NULL;
2328 isakmp_cfg_config.pool_size = 0;
2329 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
2330 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
2331 if (cold != ISAKMP_CFG_INIT_COLD) {
2332 if (isakmp_cfg_config.grouplist != NULL) {
2333 for (i = 0; i < isakmp_cfg_config.groupcount; i++)
2334 racoon_free(isakmp_cfg_config.grouplist[i]);
2335 racoon_free(isakmp_cfg_config.grouplist);
2336 }
2337 }
2338 isakmp_cfg_config.grouplist = NULL;
2339 isakmp_cfg_config.groupcount = 0;
2340 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
2341 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
2342 isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
2343 strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
2344 sizeof(isakmp_cfg_config.default_domain));
2345 strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd));
2346
2347 if (cold != ISAKMP_CFG_INIT_COLD )
2348 if (isakmp_cfg_config.splitnet_list != NULL)
2349 splitnet_list_free(isakmp_cfg_config.splitnet_list,
2350 &isakmp_cfg_config.splitnet_count);
2351 isakmp_cfg_config.splitnet_list = NULL;
2352 isakmp_cfg_config.splitnet_count = 0;
2353 isakmp_cfg_config.splitnet_type = 0;
2354
2355 isakmp_cfg_config.pfs_group = 0;
2356 isakmp_cfg_config.save_passwd = 0;
2357
2358 if (cold != ISAKMP_CFG_INIT_COLD )
2359 if (isakmp_cfg_config.splitdns_list != NULL)
2360 racoon_free(isakmp_cfg_config.splitdns_list);
2361 isakmp_cfg_config.splitdns_list = NULL;
2362 isakmp_cfg_config.splitdns_len = 0;
2363
2364 if (cold == ISAKMP_CFG_INIT_COLD) {
2365 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
2366 return error;
2367 }
2368
2369 return 0;
2370 }
2371