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

5-freebsd-12
Last change on this file since 8645c9d7 was 8645c9d7, checked in by Christian Mauderer <christian.mauderer@…>, on Jun 6, 2018 at 9:11:52 AM

ipsec-tools: Apply patches from FreeBSD ports.

Source: https://svnweb.freebsd.org/ports/head/security/ipsec-tools/files/ revision 468617.

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