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