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