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

55-freebsd-126-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on 05/30/18 at 12:27:35

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

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