]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/isakmp_cfg.c
ipsec-34.0.3.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_cfg.c
CommitLineData
52b7d2ce
A
1/* $Id: isakmp_cfg.c,v 1.26.2.7 2006/01/07 23:50:42 manubsd Exp $ */
2
3/*
4 * Copyright (C) 2004-2006 Emmanuel Dreyfus
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include "config.h"
33
34#include <sys/types.h>
35#include <sys/param.h>
36#include <sys/socket.h>
37#include <sys/queue.h>
38
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42#include <stdlib.h>
43#include <stdio.h>
44#include <string.h>
45#include <errno.h>
46#if TIME_WITH_SYS_TIME
47# include <sys/time.h>
48# include <time.h>
49#else
50# if HAVE_SYS_TIME_H
51# include <sys/time.h>
52# else
53# include <time.h>
54# endif
55#endif
56#include <netdb.h>
57#ifdef HAVE_UNISTD_H
58#include <unistd.h>
59#endif
60#include <ctype.h>
61
62#ifdef HAVE_LIBRADIUS
63#include <sys/utsname.h>
64#include <radlib.h>
65#endif
66
67#include "var.h"
68#include "misc.h"
69#include "vmbuf.h"
70#include "plog.h"
71#include "sockmisc.h"
72#include "schedule.h"
73#include "debug.h"
74
75#include "isakmp_var.h"
76#include "isakmp.h"
77#include "handler.h"
78#include "evt.h"
79#include "throttle.h"
80#include "remoteconf.h"
81#include "crypto_openssl.h"
82#include "isakmp_inf.h"
83#include "isakmp_xauth.h"
84#include "isakmp_unity.h"
85#include "isakmp_cfg.h"
86#include "strnames.h"
87#include "admin.h"
88#include "privsep.h"
89
90struct isakmp_cfg_config isakmp_cfg_config = {
91 0x00000000, /* network4 */
92 0x00000000, /* netmask4 */
93 0x00000000, /* dns4 */
94 0x00000000, /* nbns4 */
95 NULL, /* pool */
96 ISAKMP_CFG_AUTH_SYSTEM, /* authsource */
97 ISAKMP_CFG_CONF_LOCAL, /* confsource */
98 ISAKMP_CFG_ACCT_NONE, /* accounting */
99 ISAKMP_CFG_MAX_CNX, /* pool_size */
100 THROTTLE_PENALTY, /* auth_throttle */
101 ISAKMP_CFG_MOTD, /* motd */
102 0, /* pfs_group */
103 0, /* save_passwd */
104};
105
106static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
107static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
108#if 0
109static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
110#endif
111static vchar_t *isakmp_cfg_addr4(struct ph1handle *,
112 struct isakmp_data *, in_addr_t *);
113static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
114
115#define ISAKMP_CFG_LOGIN 1
116#define ISAKMP_CFG_LOGOUT 2
117static int isakmp_cfg_accounting(struct ph1handle *, int);
118#ifdef HAVE_LIBRADIUS
119static int isakmp_cfg_accounting_radius(struct ph1handle *, int);
120#endif
121
122/*
123 * Handle an ISAKMP config mode packet
124 * We expect HDR, HASH, ATTR
125 */
126void
127isakmp_cfg_r(iph1, msg)
128 struct ph1handle *iph1;
129 vchar_t *msg;
130{
131 struct isakmp *packet;
132 struct isakmp_gen *ph;
133 int tlen;
134 char *npp;
135 int np;
136 vchar_t *dmsg;
137 struct isakmp_ivm *ivm;
138
139 /* Check that the packet is long enough to have a header */
140 if (msg->l < sizeof(*packet)) {
141 plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
142 return;
143 }
144
145 packet = (struct isakmp *)msg->v;
146
147 /* Is it encrypted? It should be encrypted */
148 if ((packet->flags & ISAKMP_FLAG_E) == 0) {
149 plog(LLV_ERROR, LOCATION, NULL,
150 "User credentials sent in cleartext!\n");
151 return;
152 }
153
154 /*
155 * Decrypt the packet. If this is the beginning of a new
156 * exchange, reinitialize the IV
157 */
158 if (iph1->mode_cfg->ivm == NULL)
159 iph1->mode_cfg->ivm =
160 isakmp_cfg_newiv(iph1, packet->msgid);
161 ivm = iph1->mode_cfg->ivm;
162
163 dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
164 if (dmsg == NULL) {
165 plog(LLV_ERROR, LOCATION, NULL,
166 "failed to decrypt message\n");
167 return;
168 }
169
170 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n");
171 plogdump(LLV_DEBUG, dmsg->v, dmsg->l);
172
173 /* Now work with the decrypted packet */
174 packet = (struct isakmp *)dmsg->v;
175 tlen = dmsg->l - sizeof(*packet);
176 ph = (struct isakmp_gen *)(packet + 1);
177
178 np = packet->np;
179 while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
180 /* Check that the payload header fits in the packet */
181 if (tlen < sizeof(*ph)) {
182 plog(LLV_WARNING, LOCATION, NULL,
183 "Short payload header\n");
184 goto out;
185 }
186
187 /* Check that the payload fits in the packet */
188 if (tlen < ntohs(ph->len)) {
189 plog(LLV_WARNING, LOCATION, NULL,
190 "Short payload\n");
191 goto out;
192 }
193
194 plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np);
195 plogdump(LLV_DEBUG, ph, ntohs(ph->len));
196
197 switch(np) {
198 case ISAKMP_NPTYPE_HASH: {
199 vchar_t *check;
200 vchar_t *payload;
201 size_t plen;
202 struct isakmp_gen *nph;
203
204 plen = ntohs(ph->len);
205 nph = (struct isakmp_gen *)((char *)ph + plen);
206 plen = ntohs(nph->len);
207
208 if ((payload = vmalloc(plen)) == NULL) {
209 plog(LLV_ERROR, LOCATION, NULL,
210 "Cannot allocate memory\n");
211 goto out;
212 }
213 memcpy(payload->v, nph, plen);
214
215 if ((check = oakley_compute_hash1(iph1,
216 packet->msgid, payload)) == NULL) {
217 plog(LLV_ERROR, LOCATION, NULL,
218 "Cannot compute hash\n");
219 vfree(payload);
220 goto out;
221 }
222
223 if (memcmp(ph + 1, check->v, check->l) != 0) {
224 plog(LLV_ERROR, LOCATION, NULL,
225 "Hash verification failed\n");
226 vfree(payload);
227 vfree(check);
228 goto out;
229 }
230 vfree(payload);
231 vfree(check);
232 break;
233 }
234 case ISAKMP_NPTYPE_ATTR: {
235 struct isakmp_pl_attr *attrpl;
236
237 attrpl = (struct isakmp_pl_attr *)ph;
238 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl);
239
240 break;
241 }
242 default:
243 plog(LLV_WARNING, LOCATION, NULL,
244 "Unexpected next payload %d\n", np);
245 /* Skip to the next payload */
246 break;
247 }
248
249 /* Move to the next payload */
250 np = ph->np;
251 tlen -= ntohs(ph->len);
252 npp = (char *)ph;
253 ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
254 }
255
256out:
257 vfree(dmsg);
258}
259
260int
261isakmp_cfg_attr_r(iph1, msgid, attrpl)
262 struct ph1handle *iph1;
263 u_int32_t msgid;
264 struct isakmp_pl_attr *attrpl;
265{
266 int type = attrpl->type;
267
268 switch (type) {
269 case ISAKMP_CFG_ACK:
270 /* ignore, but this is the time to reinit the IV */
271 oakley_delivm(iph1->mode_cfg->ivm);
272 iph1->mode_cfg->ivm = NULL;
273 return 0;
274 break;
275
276 case ISAKMP_CFG_REPLY:
277 return isakmp_cfg_reply(iph1, attrpl);
278 break;
279
280 case ISAKMP_CFG_REQUEST:
281 iph1->msgid = msgid;
282 return isakmp_cfg_request(iph1, attrpl);
283 break;
284
285 case ISAKMP_CFG_SET:
286 iph1->msgid = msgid;
287 return isakmp_cfg_set(iph1, attrpl);
288 break;
289
290 default:
291 plog(LLV_WARNING, LOCATION, NULL,
292 "Unepected configuration exchange type %d\n", type);
293 return -1;
294 break;
295 }
296
297 return 0;
298}
299
300int
301isakmp_cfg_reply(iph1, attrpl)
302 struct ph1handle *iph1;
303 struct isakmp_pl_attr *attrpl;
304{
305 struct isakmp_data *attr;
306 int tlen;
307 size_t alen;
308 char *npp;
309 int type;
310 struct sockaddr_in *sin;
311
312 tlen = ntohs(attrpl->h.len);
313 attr = (struct isakmp_data *)(attrpl + 1);
314 tlen -= sizeof(*attrpl);
315
316 while (tlen > 0) {
317 type = ntohs(attr->type);
318
319 /* Handle short attributes */
320 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
321 type &= ~ISAKMP_GEN_MASK;
322
323 plog(LLV_DEBUG, LOCATION, NULL,
324 "Short attribute %d = %d\n",
325 type, ntohs(attr->lorv));
326
327 switch (type) {
328 case XAUTH_TYPE:
329 xauth_attr_reply(iph1, attr, ntohs(attrpl->id));
330 break;
331
332 default:
333 plog(LLV_WARNING, LOCATION, NULL,
334 "Ignored short attribute %d\n", type);
335 break;
336 }
337
338 tlen -= sizeof(*attr);
339 attr++;
340 continue;
341 }
342
343 type = ntohs(attr->type);
344 alen = ntohs(attr->lorv);
345
346 /* Check that the attribute fit in the packet */
347 if (tlen < alen) {
348 plog(LLV_ERROR, LOCATION, NULL,
349 "Short attribute %d\n", type);
350 return -1;
351 }
352
353 plog(LLV_DEBUG, LOCATION, NULL,
354 "Attribute %d, len %zu\n", type, alen);
355
356 switch(type) {
357 case XAUTH_TYPE:
358 case XAUTH_USER_NAME:
359 case XAUTH_USER_PASSWORD:
360 case XAUTH_PASSCODE:
361 case XAUTH_MESSAGE:
362 case XAUTH_CHALLENGE:
363 case XAUTH_DOMAIN:
364 case XAUTH_STATUS:
365 case XAUTH_NEXT_PIN:
366 case XAUTH_ANSWER:
367 xauth_attr_reply(iph1, attr, ntohs(attrpl->id));
368 break;
369 case INTERNAL_IP4_ADDRESS:
370 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
371 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
372 break;
373 case INTERNAL_IP4_NETMASK:
374 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
375 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
376 break;
377 case INTERNAL_IP4_DNS:
378 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->dns4);
379 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
380 break;
381 case INTERNAL_IP4_NBNS:
382 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->wins4);
383 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
384 break;
385 case INTERNAL_IP4_SUBNET:
386 case INTERNAL_ADDRESS_EXPIRY:
387 case UNITY_BANNER:
388 case UNITY_SAVE_PASSWD:
389 case UNITY_DEF_DOMAIN:
390 case UNITY_SPLITDNS_NAME:
391 case UNITY_SPLIT_INCLUDE:
392 case UNITY_NATT_PORT:
393 case UNITY_PFS:
394 case UNITY_FW_TYPE:
395 case UNITY_BACKUP_SERVERS:
396 case UNITY_DDNS_HOSTNAME:
397 default:
398 plog(LLV_WARNING, LOCATION, NULL,
399 "Ignored attribute %d\n", type);
400 break;
401 }
402
403 npp = (char *)attr;
404 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
405 tlen -= (sizeof(*attr) + alen);
406 }
407
408 /*
409 * Call the SA up script hook now that we have the configuration
410 * It is done at the end of phase 1 if ISAKMP mode config is not
411 * requested.
412 */
413 if ((iph1->status == PHASE1ST_ESTABLISHED) &&
414 iph1->rmconf->mode_cfg)
415 script_hook(iph1, SCRIPT_PHASE1_UP);
416
417#ifdef ENABLE_ADMINPORT
418 {
419 vchar_t *buf;
420
421 alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
422 if ((buf = vmalloc(alen)) == NULL) {
423 plog(LLV_WARNING, LOCATION, NULL,
424 "Cannot allocate memory: %s\n", strerror(errno));
425 } else {
426 memcpy(buf->v, attrpl + 1, buf->l);
427 EVT_PUSH(iph1->local, iph1->remote,
428 EVTT_ISAKMP_CFG_DONE, buf);
429 vfree(buf);
430 }
431 }
432#endif
433
434 return 0;
435}
436
437int
438isakmp_cfg_request(iph1, attrpl)
439 struct ph1handle *iph1;
440 struct isakmp_pl_attr *attrpl;
441{
442 struct isakmp_data *attr;
443 int tlen;
444 size_t alen;
445 char *npp;
446 vchar_t *payload;
447 struct isakmp_pl_attr *reply;
448 vchar_t *reply_attr;
449 int type;
450 int error = -1;
451
452 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
453 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
454 return -1;
455 }
456 memset(payload->v, 0, sizeof(*reply));
457
458 tlen = ntohs(attrpl->h.len);
459 attr = (struct isakmp_data *)(attrpl + 1);
460 tlen -= sizeof(*attrpl);
461
462 while (tlen > 0) {
463 reply_attr = NULL;
464 type = ntohs(attr->type);
465
466 /* Handle short attributes */
467 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
468 type &= ~ISAKMP_GEN_MASK;
469
470 plog(LLV_DEBUG, LOCATION, NULL,
471 "Short attribute %d = %d\n",
472 type, ntohs(attr->lorv));
473
474 switch (type) {
475 case XAUTH_TYPE:
476 reply_attr = isakmp_xauth_req(iph1, attr);
477 break;
478 default:
479 plog(LLV_WARNING, LOCATION, NULL,
480 "Ignored short attribute %d\n", type);
481 break;
482 }
483
484 tlen -= sizeof(*attr);
485 attr++;
486
487 if (reply_attr != NULL) {
488 payload = buffer_cat(payload, reply_attr);
489 vfree(reply_attr);
490 }
491
492 continue;
493 }
494
495 type = ntohs(attr->type);
496 alen = ntohs(attr->lorv);
497
498 /* Check that the attribute fit in the packet */
499 if (tlen < alen) {
500 plog(LLV_ERROR, LOCATION, NULL,
501 "Short attribute %d\n", type);
502 goto end;
503 }
504
505 plog(LLV_DEBUG, LOCATION, NULL,
506 "Attribute %d, len %zu\n", type, alen);
507
508 switch(type) {
509 case INTERNAL_IP4_ADDRESS:
510 case INTERNAL_IP4_NETMASK:
511 case INTERNAL_IP4_DNS:
512 case INTERNAL_IP4_NBNS:
513 case INTERNAL_IP4_SUBNET:
514 reply_attr = isakmp_cfg_net(iph1, attr);
515 break;
516
517 case XAUTH_TYPE:
518 case XAUTH_USER_NAME:
519 case XAUTH_USER_PASSWORD:
520 case XAUTH_PASSCODE:
521 case XAUTH_MESSAGE:
522 case XAUTH_CHALLENGE:
523 case XAUTH_DOMAIN:
524 case XAUTH_STATUS:
525 case XAUTH_NEXT_PIN:
526 case XAUTH_ANSWER:
527 reply_attr = isakmp_xauth_req(iph1, attr);
528 break;
529
530 case APPLICATION_VERSION:
531 reply_attr = isakmp_cfg_string(iph1,
532 attr, ISAKMP_CFG_RACOON_VERSION);
533 break;
534
535 case UNITY_BANNER:
536 case UNITY_PFS:
537 case UNITY_SAVE_PASSWD:
538 case UNITY_DEF_DOMAIN:
539 case UNITY_DDNS_HOSTNAME:
540 case UNITY_FW_TYPE:
541 case UNITY_SPLITDNS_NAME:
542 case UNITY_SPLIT_INCLUDE:
543 case UNITY_NATT_PORT:
544 case UNITY_BACKUP_SERVERS:
545 reply_attr = isakmp_unity_req(iph1, attr);
546 break;
547
548 case INTERNAL_ADDRESS_EXPIRY:
549 default:
550 plog(LLV_WARNING, LOCATION, NULL,
551 "Ignored attribute %d\n", type);
552 break;
553 }
554
555 npp = (char *)attr;
556 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
557 tlen -= (sizeof(*attr) + alen);
558
559 if (reply_attr != NULL) {
560 payload = buffer_cat(payload, reply_attr);
561 vfree(reply_attr);
562 }
563
564 }
565
566 reply = (struct isakmp_pl_attr *)payload->v;
567 reply->h.len = htons(payload->l);
568 reply->type = ISAKMP_CFG_REPLY;
569 reply->id = attrpl->id;
570
571 error = isakmp_cfg_send(iph1, payload,
572 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
573
574 /* Reinit the IV */
575 oakley_delivm(iph1->mode_cfg->ivm);
576 iph1->mode_cfg->ivm = NULL;
577end:
578 vfree(payload);
579
580 return error;
581}
582
583int
584isakmp_cfg_set(iph1, attrpl)
585 struct ph1handle *iph1;
586 struct isakmp_pl_attr *attrpl;
587{
588 struct isakmp_data *attr;
589 int tlen;
590 size_t alen;
591 char *npp;
592 vchar_t *payload;
593 struct isakmp_pl_attr *reply;
594 vchar_t *reply_attr;
595 int type;
596 int error = -1;
597
598 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
599 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
600 return -1;
601 }
602 memset(payload->v, 0, sizeof(*reply));
603
604 tlen = ntohs(attrpl->h.len);
605 attr = (struct isakmp_data *)(attrpl + 1);
606 tlen -= sizeof(*attrpl);
607
608 /*
609 * We should send ack for the attributes we accepted
610 */
611 while (tlen > 0) {
612 reply_attr = NULL;
613 type = ntohs(attr->type);
614
615 switch (type & ~ISAKMP_GEN_MASK) {
616 case XAUTH_STATUS:
617 reply_attr = isakmp_xauth_set(iph1, attr);
618 break;
619 default:
620 plog(LLV_DEBUG, LOCATION, NULL,
621 "Unexpected SET attribute %d\n",
622 type & ~ISAKMP_GEN_MASK);
623 break;
624 }
625
626 if ((reply_attr = vmalloc(sizeof(*reply_attr))) != NULL) {
627 payload = buffer_cat(payload, reply_attr);
628 vfree(reply_attr);
629 }
630
631 /*
632 * Move to next attribute. If we run out of the packet,
633 * tlen becomes negative and we exit.
634 */
635 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
636 tlen -= sizeof(*attr);
637 attr++;
638 } else {
639 alen = ntohs(attr->lorv);
640 tlen -= (sizeof(*attr) + alen);
641 npp = (char *)attr;
642 attr = (struct isakmp_data *)
643 (npp + sizeof(*attr) + alen);
644 }
645 }
646
647 reply = (struct isakmp_pl_attr *)payload->v;
648 reply->h.len = htons(payload->l);
649 reply->type = ISAKMP_CFG_ACK;
650 reply->id = attrpl->id;
651
652 error = isakmp_cfg_send(iph1, payload,
653 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
654
655 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
656 if (iph1->status == PHASE1ST_ESTABLISHED)
657 isakmp_info_send_d1(iph1);
658 remph1(iph1);
659 delph1(iph1);
660 }
661end:
662 vfree(payload);
663
664 /*
665 * If required, request ISAKMP mode config information
666 */
667 if ((iph1->rmconf->mode_cfg) && (error == 0))
668 error = isakmp_cfg_getconfig(iph1);
669
670 return error;
671}
672
673
674static vchar_t *
675buffer_cat(s, append)
676 vchar_t *s;
677 vchar_t *append;
678{
679 vchar_t *new;
680
681 new = vmalloc(s->l + append->l);
682 if (new == NULL) {
683 plog(LLV_ERROR, LOCATION, NULL,
684 "Cannot allocate memory\n");
685 return s;
686 }
687
688 memcpy(new->v, s->v, s->l);
689 memcpy(new->v + s->l, append->v, append->l);
690
691 vfree(s);
692 return new;
693}
694
695static vchar_t *
696isakmp_cfg_net(iph1, attr)
697 struct ph1handle *iph1;
698 struct isakmp_data *attr;
699{
700 int type;
701 in_addr_t addr4;
702
703 type = ntohs(attr->type);
704
705 /*
706 * Don't give an address to a peer that did not succeed Xauth
707 */
708 if (xauth_check(iph1) != 0) {
709 plog(LLV_ERROR, LOCATION, NULL,
710 "Attempt to start phase config whereas Xauth failed\n");
711 return NULL;
712 }
713
714 switch(type) {
715 case INTERNAL_IP4_ADDRESS:
716 switch(isakmp_cfg_config.confsource) {
717#ifdef HAVE_LIBRADIUS
718 case ISAKMP_CFG_CONF_RADIUS:
719 if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS)
720 && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
721 /*
722 * -2 is 255.255.255.254, RADIUS uses that
723 * to instruct the NAS to use a local pool
724 */
725 break;
726 plog(LLV_INFO, LOCATION, NULL,
727 "No IP from RADIUS, using local pool\n");
728 /* FALLTHROUGH */
729#endif
730 case ISAKMP_CFG_CONF_LOCAL:
731 if (isakmp_cfg_getport(iph1) == -1) {
732 plog(LLV_ERROR, LOCATION, NULL,
733 "Port pool depleted\n");
734 break;
735 }
736
737 iph1->mode_cfg->addr4.s_addr =
738 htonl(ntohl(isakmp_cfg_config.network4)
739 + iph1->mode_cfg->port);
740 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
741 break;
742
743 default:
744 plog(LLV_ERROR, LOCATION, NULL,
745 "Unexpected confsource\n");
746 }
747
748 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
749 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
750
751 return isakmp_cfg_addr4(iph1,
752 attr, &iph1->mode_cfg->addr4.s_addr);
753 break;
754
755 case INTERNAL_IP4_NETMASK:
756 switch(isakmp_cfg_config.confsource) {
757#ifdef HAVE_LIBRADIUS
758 case ISAKMP_CFG_CONF_RADIUS:
759 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_RADIUS)
760 break;
761 plog(LLV_INFO, LOCATION, NULL,
762 "No mask from RADIUS, using local pool\n");
763 /* FALLTHROUGH */
764#endif
765 case ISAKMP_CFG_CONF_LOCAL:
766 iph1->mode_cfg->mask4.s_addr
767 = isakmp_cfg_config.netmask4;
768 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
769 break;
770
771 default:
772 plog(LLV_ERROR, LOCATION, NULL,
773 "Unexpected confsource\n");
774 }
775 return isakmp_cfg_addr4(iph1, attr,
776 &iph1->mode_cfg->mask4.s_addr);
777 break;
778
779 case INTERNAL_IP4_DNS:
780 return isakmp_cfg_addr4(iph1,
781 attr, &isakmp_cfg_config.dns4);
782 break;
783
784 case INTERNAL_IP4_NBNS:
785 return isakmp_cfg_addr4(iph1,
786 attr, &isakmp_cfg_config.nbns4);
787 break;
788
789 case INTERNAL_IP4_SUBNET:
790 return isakmp_cfg_addr4(iph1,
791 attr, &isakmp_cfg_config.network4);
792 break;
793
794 default:
795 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
796 break;
797 }
798
799 return NULL;
800}
801
802#if 0
803static vchar_t *
804isakmp_cfg_void(iph1, attr)
805 struct ph1handle *iph1;
806 struct isakmp_data *attr;
807{
808 vchar_t *buffer;
809 struct isakmp_data *new;
810
811 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
812 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
813 return NULL;
814 }
815
816 new = (struct isakmp_data *)buffer->v;
817
818 new->type = attr->type;
819 new->lorv = htons(0);
820
821 return buffer;
822}
823#endif
824
825vchar_t *
826isakmp_cfg_copy(iph1, attr)
827 struct ph1handle *iph1;
828 struct isakmp_data *attr;
829{
830 vchar_t *buffer;
831 size_t len = 0;
832
833 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
834 len = ntohs(attr->lorv);
835
836 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
837 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
838 return NULL;
839 }
840
841 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
842
843 return buffer;
844}
845
846vchar_t *
847isakmp_cfg_short(iph1, attr, value)
848 struct ph1handle *iph1;
849 struct isakmp_data *attr;
850 int value;
851{
852 vchar_t *buffer;
853 struct isakmp_data *new;
854 int type;
855
856 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
857 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
858 return NULL;
859 }
860
861 new = (struct isakmp_data *)buffer->v;
862 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
863
864 new->type = htons(type | ISAKMP_GEN_TV);
865 new->lorv = htons(value);
866
867 return buffer;
868}
869
870vchar_t *
871isakmp_cfg_string(iph1, attr, string)
872 struct ph1handle *iph1;
873 struct isakmp_data *attr;
874 char *string;
875{
876 vchar_t *buffer;
877 struct isakmp_data *new;
878 size_t len;
879 char *data;
880
881 len = strlen(string);
882 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
883 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
884 return NULL;
885 }
886
887 new = (struct isakmp_data *)buffer->v;
888
889 new->type = attr->type;
890 new->lorv = htons(len);
891 data = (char *)(new + 1);
892
893 memcpy(data, string, len);
894
895 return buffer;
896}
897
898static vchar_t *
899isakmp_cfg_addr4(iph1, attr, addr)
900 struct ph1handle *iph1;
901 struct isakmp_data *attr;
902 in_addr_t *addr;
903{
904 vchar_t *buffer;
905 struct isakmp_data *new;
906 size_t len;
907
908 len = sizeof(*addr);
909 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
910 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
911 return NULL;
912 }
913
914 new = (struct isakmp_data *)buffer->v;
915
916 new->type = attr->type;
917 new->lorv = htons(len);
918 memcpy(new + 1, addr, len);
919
920 return buffer;
921}
922
923struct isakmp_ivm *
924isakmp_cfg_newiv(iph1, msgid)
925 struct ph1handle *iph1;
926 u_int32_t msgid;
927{
928 struct isakmp_cfg_state *ics = iph1->mode_cfg;
929
930 if (ics == NULL) {
931 plog(LLV_ERROR, LOCATION, NULL,
932 "isakmp_cfg_newiv called without mode config state\n");
933 return NULL;
934 }
935
936 if (ics->ivm != NULL)
937 oakley_delivm(ics->ivm);
938
939 ics->ivm = oakley_newiv2(iph1, msgid);
940
941 return ics->ivm;
942}
943
944/* Derived from isakmp_info_send_common */
945int
946isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
947 struct ph1handle *iph1;
948 vchar_t *payload;
949 u_int32_t np;
950 int flags;
951 int new_exchange;
952{
953 struct ph2handle *iph2 = NULL;
954 vchar_t *hash = NULL;
955 struct isakmp *isakmp;
956 struct isakmp_gen *gen;
957 char *p;
958 int tlen;
959 int error = -1;
960 struct isakmp_cfg_state *ics = iph1->mode_cfg;
961
962 /* Check if phase 1 is established */
963 if ((iph1->status != PHASE1ST_ESTABLISHED) ||
964 (iph1->local == NULL) ||
965 (iph1->remote == NULL)) {
966 plog(LLV_ERROR, LOCATION, NULL,
967 "ISAKMP mode config exchange with immature phase 1\n");
968 goto end;
969 }
970
971 /* add new entry to isakmp status table */
972 iph2 = newph2();
973 if (iph2 == NULL)
974 goto end;
975
976 iph2->dst = dupsaddr(iph1->remote);
977 iph2->src = dupsaddr(iph1->local);
978 switch (iph1->remote->sa_family) {
979 case AF_INET:
980#ifndef ENABLE_NATT
981 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
982 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
983#endif
984 break;
985#ifdef INET6
986 case AF_INET6:
987 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
988 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
989 break;
990#endif
991 default:
992 plog(LLV_ERROR, LOCATION, NULL,
993 "invalid family: %d\n", iph1->remote->sa_family);
994 delph2(iph2);
995 goto end;
996 }
997 iph2->ph1 = iph1;
998 iph2->side = INITIATOR;
999 iph2->status = PHASE2ST_START;
1000
1001 if (new_exchange)
1002 iph2->msgid = isakmp_newmsgid2(iph1);
1003 else
1004 iph2->msgid = iph1->msgid;
1005
1006 /* get IV and HASH(1) if skeyid_a was generated. */
1007 if (iph1->skeyid_a != NULL) {
1008 if (new_exchange) {
1009 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1010 delph2(iph2);
1011 goto end;
1012 }
1013 }
1014
1015 /* generate HASH(1) */
1016 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
1017 if (hash == NULL) {
1018 delph2(iph2);
1019 goto end;
1020 }
1021
1022 /* initialized total buffer length */
1023 tlen = hash->l;
1024 tlen += sizeof(*gen);
1025 } else {
1026 /* IKE-SA is not established */
1027 hash = NULL;
1028
1029 /* initialized total buffer length */
1030 tlen = 0;
1031 }
1032 if ((flags & ISAKMP_FLAG_A) == 0)
1033 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1034 else
1035 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1036
1037 insph2(iph2);
1038 bindph12(iph1, iph2);
1039
1040 tlen += sizeof(*isakmp) + payload->l;
1041
1042 /* create buffer for isakmp payload */
1043 iph2->sendbuf = vmalloc(tlen);
1044 if (iph2->sendbuf == NULL) {
1045 plog(LLV_ERROR, LOCATION, NULL,
1046 "failed to get buffer to send.\n");
1047 goto err;
1048 }
1049
1050 /* create isakmp header */
1051 isakmp = (struct isakmp *)iph2->sendbuf->v;
1052 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1053 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1054 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1055 isakmp->v = iph1->version;
1056 isakmp->etype = ISAKMP_ETYPE_CFG;
1057 isakmp->flags = iph2->flags;
1058 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1059 isakmp->len = htonl(tlen);
1060 p = (char *)(isakmp + 1);
1061
1062 /* create HASH payload */
1063 if (hash != NULL) {
1064 gen = (struct isakmp_gen *)p;
1065 gen->np = np & 0xff;
1066 gen->len = htons(sizeof(*gen) + hash->l);
1067 p += sizeof(*gen);
1068 memcpy(p, hash->v, hash->l);
1069 p += hash->l;
1070 }
1071
1072 /* add payload */
1073 memcpy(p, payload->v, payload->l);
1074 p += payload->l;
1075
1076#ifdef HAVE_PRINT_ISAKMP_C
1077 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1078#endif
1079
1080 /* encoding */
1081 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1082 vchar_t *tmp;
1083
1084 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1085 ics->ivm->ive, ics->ivm->iv);
1086 VPTRINIT(iph2->sendbuf);
1087 if (tmp == NULL)
1088 goto err;
1089 iph2->sendbuf = tmp;
1090 }
1091
1092 /* HDR*, HASH(1), ATTR */
1093 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1094 VPTRINIT(iph2->sendbuf);
1095 goto err;
1096 }
1097
1098 plog(LLV_DEBUG, LOCATION, NULL,
1099 "sendto mode config %s.\n", s_isakmp_nptype(np));
1100
1101 /*
1102 * XXX We might need to resend the message...
1103 */
1104
1105 error = 0;
1106 VPTRINIT(iph2->sendbuf);
1107
1108err:
1109 if (iph2->sendbuf != NULL)
1110 vfree(iph2->sendbuf);
1111
1112 unbindph12(iph2);
1113 remph2(iph2);
1114 delph2(iph2);
1115end:
1116 if (hash)
1117 vfree(hash);
1118 return error;
1119}
1120
1121
1122void
1123isakmp_cfg_rmstate(iph1)
1124 struct ph1handle *iph1;
1125{
1126 struct isakmp_cfg_state *state = iph1->mode_cfg;
1127
1128 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1129 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1130
1131 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1132 isakmp_cfg_putport(iph1, state->port);
1133
1134 xauth_rmstate(&state->xauth);
1135
1136 racoon_free(state);
1137 iph1->mode_cfg = NULL;
1138
1139 return;
1140}
1141
1142struct isakmp_cfg_state *
1143isakmp_cfg_mkstate(void)
1144{
1145 struct isakmp_cfg_state *state;
1146
1147 if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1148 plog(LLV_ERROR, LOCATION, NULL,
1149 "Cannot allocate memory for mode config state\n");
1150 return NULL;
1151 }
1152 memset(state, 0, sizeof(*state));
1153
1154 return state;
1155}
1156
1157int
1158isakmp_cfg_getport(iph1)
1159 struct ph1handle *iph1;
1160{
1161 unsigned int i;
1162 size_t size = isakmp_cfg_config.pool_size;
1163
1164 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1165 return iph1->mode_cfg->port;
1166
1167 if (isakmp_cfg_config.port_pool == NULL) {
1168 plog(LLV_ERROR, LOCATION, NULL,
1169 "isakmp_cfg_config.port_pool == NULL\n");
1170 return -1;
1171 }
1172
1173 for (i = 0; i < size; i++) {
1174 if (isakmp_cfg_config.port_pool[i].used == 0)
1175 break;
1176 }
1177
1178 if (i == size) {
1179 plog(LLV_ERROR, LOCATION, NULL,
1180 "No more addresses available\n");
1181 return -1;
1182 }
1183
1184 isakmp_cfg_config.port_pool[i].used = 1;
1185
1186 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1187
1188 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1189 iph1->mode_cfg->port = i;
1190
1191 return i;
1192}
1193
1194int
1195isakmp_cfg_putport(iph1, index)
1196 struct ph1handle *iph1;
1197 unsigned int index;
1198{
1199 if (isakmp_cfg_config.port_pool == NULL) {
1200 plog(LLV_ERROR, LOCATION, NULL,
1201 "isakmp_cfg_config.port_pool == NULL\n");
1202 return -1;
1203 }
1204
1205 if (isakmp_cfg_config.port_pool[index].used == 0) {
1206 plog(LLV_ERROR, LOCATION, NULL,
1207 "Attempt to release an unallocated address (port %d)\n",
1208 index);
1209 return -1;
1210 }
1211
1212#ifdef HAVE_LIBPAM
1213 /* Cleanup PAM status associated with the port */
1214 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1215 privsep_cleanup_pam(index);
1216#endif
1217 isakmp_cfg_config.port_pool[index].used = 0;
1218 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1219
1220 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1221
1222 return 0;
1223}
1224
1225#ifdef HAVE_LIBPAM
1226void
1227cleanup_pam(port)
1228 int port;
1229{
1230 if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1231 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1232 isakmp_cfg_config.port_pool[port].pam = NULL;
1233 }
1234
1235 return;
1236}
1237#endif
1238
1239/* Accounting, only for RADIUS or PAM */
1240static int
1241isakmp_cfg_accounting(iph1, inout)
1242 struct ph1handle *iph1;
1243 int inout;
1244{
1245#ifdef HAVE_LIBPAM
1246 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1247 return privsep_accounting_pam(iph1->mode_cfg->port,
1248 inout);
1249#endif
1250#ifdef HAVE_LIBRADIUS
1251 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1252 return isakmp_cfg_accounting_radius(iph1, inout);
1253#endif
1254 return 0;
1255}
1256
1257#ifdef HAVE_LIBPAM
1258int
1259isakmp_cfg_accounting_pam(port, inout)
1260 int port;
1261 int inout;
1262{
1263 int error = 0;
1264 pam_handle_t *pam;
1265
1266 if (isakmp_cfg_config.port_pool == NULL) {
1267 plog(LLV_ERROR, LOCATION, NULL,
1268 "isakmp_cfg_config.port_pool == NULL\n");
1269 return -1;
1270 }
1271
1272 pam = isakmp_cfg_config.port_pool[port].pam;
1273 if (pam == NULL) {
1274 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1275 return -1;
1276 }
1277
1278 switch (inout) {
1279 case ISAKMP_CFG_LOGIN:
1280 error = pam_open_session(pam, 0);
1281 break;
1282 case ISAKMP_CFG_LOGOUT:
1283 error = pam_close_session(pam, 0);
1284 pam_end(pam, error);
1285 isakmp_cfg_config.port_pool[port].pam = NULL;
1286 break;
1287 default:
1288 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1289 break;
1290 }
1291
1292 if (error != 0) {
1293 plog(LLV_ERROR, LOCATION, NULL,
1294 "pam_open_session/pam_close_session failed: %s\n",
1295 pam_strerror(pam, error));
1296 return -1;
1297 }
1298
1299 return 0;
1300}
1301#endif /* HAVE_LIBPAM */
1302
1303#ifdef HAVE_LIBRADIUS
1304static int
1305isakmp_cfg_accounting_radius(iph1, inout)
1306 struct ph1handle *iph1;
1307 int inout;
1308{
1309 /* For first time use, initialize Radius */
1310 if (radius_acct_state == NULL) {
1311 if ((radius_acct_state = rad_acct_open()) == NULL) {
1312 plog(LLV_ERROR, LOCATION, NULL,
1313 "Cannot init librradius\n");
1314 return -1;
1315 }
1316
1317 if (rad_config(radius_acct_state, NULL) != 0) {
1318 plog(LLV_ERROR, LOCATION, NULL,
1319 "Cannot open librarius config file: %s\n",
1320 rad_strerror(radius_acct_state));
1321 rad_close(radius_acct_state);
1322 radius_acct_state = NULL;
1323 return -1;
1324 }
1325 }
1326
1327 if (rad_create_request(radius_acct_state,
1328 RAD_ACCOUNTING_REQUEST) != 0) {
1329 plog(LLV_ERROR, LOCATION, NULL,
1330 "rad_create_request failed: %s\n",
1331 rad_strerror(radius_acct_state));
1332 return -1;
1333 }
1334
1335 if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1336 iph1->mode_cfg->login) != 0) {
1337 plog(LLV_ERROR, LOCATION, NULL,
1338 "rad_put_string failed: %s\n",
1339 rad_strerror(radius_acct_state));
1340 return -1;
1341 }
1342
1343 switch (inout) {
1344 case ISAKMP_CFG_LOGIN:
1345 inout = RAD_START;
1346 break;
1347 case ISAKMP_CFG_LOGOUT:
1348 inout = RAD_STOP;
1349 break;
1350 default:
1351 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1352 break;
1353 }
1354
1355 if (rad_put_addr(radius_acct_state,
1356 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1357 plog(LLV_ERROR, LOCATION, NULL,
1358 "rad_put_addr failed: %s\n",
1359 rad_strerror(radius_acct_state));
1360 return -1;
1361 }
1362
1363 if (rad_put_addr(radius_acct_state,
1364 RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1365 plog(LLV_ERROR, LOCATION, NULL,
1366 "rad_put_addr failed: %s\n",
1367 rad_strerror(radius_acct_state));
1368 return -1;
1369 }
1370
1371 if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1372 plog(LLV_ERROR, LOCATION, NULL,
1373 "rad_put_int failed: %s\n",
1374 rad_strerror(radius_acct_state));
1375 return -1;
1376 }
1377
1378 if (isakmp_cfg_radius_common(radius_acct_state,
1379 iph1->mode_cfg->port) != 0)
1380 return -1;
1381
1382 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1383 plog(LLV_ERROR, LOCATION, NULL,
1384 "rad_send_request failed: %s\n",
1385 rad_strerror(radius_acct_state));
1386 return -1;
1387 }
1388
1389 return 0;
1390}
1391#endif /* HAVE_LIBRADIUS */
1392
1393/*
1394 * Attributes common to all RADIUS requests
1395 */
1396#ifdef HAVE_LIBRADIUS
1397int
1398isakmp_cfg_radius_common(radius_state, port)
1399 struct rad_handle *radius_state;
1400 int port;
1401{
1402 struct utsname name;
1403 static struct hostent *host = NULL;
1404 struct in_addr nas_addr;
1405
1406 /*
1407 * Find our own IP by resolving our nodename
1408 */
1409 if (host == NULL) {
1410 if (uname(&name) != 0) {
1411 plog(LLV_ERROR, LOCATION, NULL,
1412 "uname failed: %s\n", strerror(errno));
1413 return -1;
1414 }
1415
1416 if ((host = gethostbyname(name.nodename)) == NULL) {
1417 plog(LLV_ERROR, LOCATION, NULL,
1418 "gethostbyname failed: %s\n", strerror(errno));
1419 return -1;
1420 }
1421 }
1422
1423 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1424 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1425 plog(LLV_ERROR, LOCATION, NULL,
1426 "rad_put_addr failed: %s\n",
1427 rad_strerror(radius_state));
1428 return -1;
1429 }
1430
1431 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1432 plog(LLV_ERROR, LOCATION, NULL,
1433 "rad_put_int failed: %s\n",
1434 rad_strerror(radius_state));
1435 return -1;
1436 }
1437
1438 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1439 plog(LLV_ERROR, LOCATION, NULL,
1440 "rad_put_int failed: %s\n",
1441 rad_strerror(radius_state));
1442 return -1;
1443 }
1444
1445 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1446 plog(LLV_ERROR, LOCATION, NULL,
1447 "rad_put_int failed: %s\n",
1448 rad_strerror(radius_state));
1449 return -1;
1450 }
1451
1452 return 0;
1453}
1454#endif
1455
1456int
1457isakmp_cfg_getconfig(iph1)
1458 struct ph1handle *iph1;
1459{
1460 vchar_t *buffer;
1461 struct isakmp_pl_attr *attrpl;
1462 struct isakmp_data *attr;
1463 size_t len;
1464 int error;
1465 int attrcount;
1466 int i;
1467 int attrlist[] = {
1468 INTERNAL_IP4_ADDRESS,
1469 INTERNAL_IP4_NETMASK,
1470 INTERNAL_IP4_DNS,
1471 INTERNAL_IP4_NBNS,
1472 UNITY_BANNER,
1473 APPLICATION_VERSION,
1474 };
1475
1476 attrcount = sizeof(attrlist) / sizeof(*attrlist);
1477 len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1478
1479 if ((buffer = vmalloc(len)) == NULL) {
1480 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1481 return -1;
1482 }
1483
1484 attrpl = (struct isakmp_pl_attr *)buffer->v;
1485 attrpl->h.len = htons(len);
1486 attrpl->type = ISAKMP_CFG_REQUEST;
1487 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1488
1489 attr = (struct isakmp_data *)(attrpl + 1);
1490
1491 for (i = 0; i < attrcount; i++) {
1492 attr->type = htons(attrlist[i]);
1493 attr->lorv = htons(0);
1494 attr++;
1495 }
1496
1497 error = isakmp_cfg_send(iph1, buffer,
1498 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
1499
1500 vfree(buffer);
1501
1502 return error;
1503}
1504
1505static void
1506isakmp_cfg_getaddr4(attr, ip)
1507 struct isakmp_data *attr;
1508 struct in_addr *ip;
1509{
1510 size_t alen = ntohs(attr->lorv);
1511 in_addr_t *addr;
1512
1513 if (alen != sizeof(*ip)) {
1514 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
1515 return;
1516 }
1517
1518 addr = (in_addr_t *)(attr + 1);
1519 ip->s_addr = *addr;
1520
1521 return;
1522}
1523
1524int
1525isakmp_cfg_setenv(iph1, envp, envc)
1526 struct ph1handle *iph1;
1527 char ***envp;
1528 int *envc;
1529{
1530#define IP_MAX 40
1531 char addrstr[IP_MAX];
1532
1533 /*
1534 * Internal IPv4 address, either if
1535 * we are a client or a server.
1536 */
1537 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
1538#ifdef HAVE_LIBRADIUS
1539 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS) ||
1540#endif
1541 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
1542 inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
1543 addrstr, IP_MAX);
1544 } else
1545 addrstr[0] = '\0';
1546
1547 if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
1548 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
1549 return -1;
1550 }
1551
1552 /* Internal IPv4 mask */
1553 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
1554 inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
1555 addrstr, IP_MAX);
1556 else
1557 addrstr[0] = '\0';
1558
1559 /*
1560 * During several releases, documentation adverised INTERNAL_NETMASK4
1561 * while code was using INTERNAL_MASK4. We now do both.
1562 */
1563 if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
1564 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
1565 return -1;
1566 }
1567
1568 if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
1569 plog(LLV_ERROR, LOCATION, NULL,
1570 "Cannot set INTERNAL_NETMASK4\n");
1571 return -1;
1572 }
1573
1574
1575 /* Internal IPv4 DNS */
1576 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4)
1577 inet_ntop(AF_INET, &iph1->mode_cfg->dns4,
1578 addrstr, IP_MAX);
1579 else
1580 addrstr[0] = '\0';
1581
1582 if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
1583 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
1584 return -1;
1585 }
1586
1587 /* Internal IPv4 WINS */
1588 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4)
1589 inet_ntop(AF_INET, &iph1->mode_cfg->wins4,
1590 addrstr, IP_MAX);
1591 else
1592 addrstr[0] = '\0';
1593
1594 if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
1595 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_WINS4\n");
1596 return -1;
1597 }
1598
1599 return 0;
1600}