source: rtems-libbsd/ipsec-tools/src/racoon/isakmp_cfg.c

6-freebsd-12
Last change on this file was b376ae1, checked in by Christian Mauderer <christian.mauderer@…>, on 05/03/18 at 12:15:11

ipsec-tools: Port libipsec, setkey and racoon.

Note that this replaces the libipsec from FreeBSD with the one provided
by ipsec-tools.

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