Annotation of embedaddon/ipsec-tools/src/racoon/racoonctl.c, revision 1.1.1.1.2.1

1.1       misho       1: /*     $NetBSD: racoonctl.c,v 1.18 2010/11/12 09:08:26 tteras Exp $    */
                      2: 
                      3: /*     Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */
                      4: 
                      5: /*
                      6:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
                      7:  * Copyright (C) 2008 Timo Teras.
                      8:  * All rights reserved.
                      9:  * 
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the project nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  * 
                     22:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34: 
                     35: #include "config.h"
                     36: 
                     37: #include <sys/types.h>
                     38: #include <sys/param.h>
                     39: #include <sys/socket.h>
                     40: #include <sys/un.h>
                     41: 
                     42: #include <netinet/in.h>
                     43: #include <arpa/inet.h>
                     44: #include <net/pfkeyv2.h>
                     45: 
                     46: #include <stdlib.h>
                     47: #include <stdio.h>
                     48: #include <string.h>
                     49: #include <errno.h>
                     50: #if TIME_WITH_SYS_TIME
                     51: # include <sys/time.h>
                     52: # include <time.h>
                     53: #else
                     54: # if HAVE_SYS_TIME_H
                     55: #  include <sys/time.h>
                     56: # else
                     57: #  include <time.h>
                     58: # endif
                     59: #endif
                     60: #include <netdb.h>
                     61: #ifdef HAVE_UNISTD_H
                     62: #include <unistd.h>
                     63: #endif
                     64: #include <err.h>
                     65: #include <sys/ioctl.h> 
                     66: #include <resolv.h>
                     67: 
                     68: #include "var.h"
                     69: #include "vmbuf.h"
                     70: #include "misc.h"
                     71: #include "gcmalloc.h"
                     72: 
                     73: #include "racoonctl.h"
                     74: #include "admin.h"
                     75: #include "schedule.h"
                     76: #include "handler.h"
                     77: #include "sockmisc.h"
                     78: #include "vmbuf.h"
                     79: #include "plog.h"
                     80: #include "isakmp_var.h"
                     81: #include "isakmp.h"
                     82: #include "isakmp_xauth.h"
                     83: #include "isakmp_cfg.h"
                     84: #include "isakmp_unity.h"
                     85: #include "ipsec_doi.h"
                     86: #include "evt.h"
                     87: 
                     88: char *adminsock_path = ADMINSOCK_PATH;
                     89: 
                     90: static void usage __P((void));
                     91: static vchar_t *get_combuf __P((int, char **));
                     92: static int handle_recv __P((vchar_t *));
                     93: static vchar_t *f_reload __P((int, char **));
                     94: static vchar_t *f_getsched __P((int, char **));
                     95: static vchar_t *f_getsa __P((int, char **));
                     96: static vchar_t *f_getsacert __P((int, char **));
                     97: static vchar_t *f_flushsa __P((int, char **));
                     98: static vchar_t *f_deletesa __P((int, char **));
                     99: static vchar_t *f_exchangesa __P((int, char **));
                    100: static vchar_t *f_vpnc __P((int, char **));
                    101: static vchar_t *f_vpnd __P((int, char **));
                    102: static vchar_t *f_getevt __P((int, char **));
                    103: #ifdef ENABLE_HYBRID
                    104: static vchar_t *f_logoutusr __P((int, char **));
                    105: #endif
                    106: 
                    107: struct cmd_tag {
                    108:        vchar_t *(*func) __P((int, char **));
                    109:        char *str;
                    110: } cmdtab[] = {
                    111:        { f_reload,     "reload-config" },
                    112:        { f_reload,     "rc" },
                    113:        { f_getsched,   "show-schedule" },
                    114:        { f_getsched,   "sc" },
                    115:        { f_getsa,      "show-sa" },
                    116:        { f_getsa,      "ss" },
                    117:        { f_getsacert,  "get-cert" },
                    118:        { f_getsacert,  "gc" },
                    119:        { f_flushsa,    "flush-sa" },
                    120:        { f_flushsa,    "fs" },
                    121:        { f_deletesa,   "delete-sa" },
                    122:        { f_deletesa,   "ds" },
                    123:        { f_exchangesa, "establish-sa" },
                    124:        { f_exchangesa, "es" },
                    125:        { f_vpnc,       "vpn-connect" },
                    126:        { f_vpnc,       "vc" },
                    127:        { f_vpnd,       "vpn-disconnect" },
                    128:        { f_vpnd,       "vd" },
                    129:        { f_getevt,     "show-event" },
                    130:        { f_getevt,     "se" },
                    131: #ifdef ENABLE_HYBRID
                    132:        { f_logoutusr,  "logout-user" },
                    133:        { f_logoutusr,  "lu" },
                    134: #endif
                    135:        { NULL, NULL },
                    136: };
                    137: 
                    138: struct evtmsg {
                    139:        int type;
                    140:        char *msg;
                    141: } evtmsg[] = {
                    142:        { EVT_RACOON_QUIT,              "Racoon terminated" },
                    143: 
                    144:        { EVT_PHASE1_UP,                "Phase 1 established" },
                    145:        { EVT_PHASE1_DOWN,              "Phase 1 deleted" },
                    146:        { EVT_PHASE1_NO_RESPONSE,       "Phase 1 error: peer not responding" },
                    147:        { EVT_PHASE1_NO_PROPOSAL,       "Phase 1 error: no proposal chosen" },
                    148:        { EVT_PHASE1_AUTH_FAILED,
                    149:          "Phase 1 error: authentication failed (bad certificate?)" },
                    150:        { EVT_PHASE1_DPD_TIMEOUT,       "Phase 1 error: dead peer detected" },
                    151:        { EVT_PHASE1_MODE_CFG,          "Phase 1 mode configuration done" },
                    152:        { EVT_PHASE1_XAUTH_SUCCESS,     "Phase 1 Xauth succeeded" },
                    153:        { EVT_PHASE1_XAUTH_FAILED,      "Phase 1 Xauth failed" },
                    154: 
                    155:        { EVT_PHASE2_NO_PHASE1,         "Phase 2 error: no suitable phase 1" },
                    156:        { EVT_PHASE2_UP,                "Phase 2 established" },
                    157:        { EVT_PHASE2_DOWN,              "Phase 2 deleted" },
                    158:        { EVT_PHASE2_NO_RESPONSE,       "Phase 2 error: no response" },
                    159: };
                    160: 
                    161: static vchar_t *get_proto_and_index __P((int, char **, u_int16_t *));
                    162: static int get_proto __P((char *));
                    163: static vchar_t *get_index __P((int, char **));
                    164: static int get_family __P((char *));
                    165: static vchar_t *get_comindexes __P((int, int, char **));
                    166: static int get_comindex __P((char *, char **, char **, char **));
                    167: static int get_ulproto __P((char *));
                    168: 
                    169: struct proto_tag {
                    170:        int proto;
                    171:        char *str;
                    172: } prototab[] = {
                    173:        { ADMIN_PROTO_ISAKMP,   "isakmp" },
                    174:        { ADMIN_PROTO_IPSEC,    "ipsec" },
                    175:        { ADMIN_PROTO_AH,       "ah" },
                    176:        { ADMIN_PROTO_ESP,      "esp" },
                    177:        { ADMIN_PROTO_INTERNAL, "internal" },
                    178:        { 0, NULL },
                    179: };
                    180: 
                    181: struct ulproto_tag {
                    182:        int ul_proto;
                    183:        char *str;
                    184: } ulprototab[] = {
                    185:        { 0,            "any" },
                    186:        { IPPROTO_ICMP, "icmp" },
                    187:        { IPPROTO_TCP,  "tcp" },
                    188:        { IPPROTO_UDP,  "udp" },
                    189:        { IPPROTO_GRE,  "gre" },
                    190:        { 0, NULL },
                    191: };
                    192: 
                    193: int so;
                    194: 
                    195: static char _addr1_[NI_MAXHOST], _addr2_[NI_MAXHOST];
                    196: 
                    197: char *pname;
                    198: int long_format = 0;
                    199: int evt_quit_event = 0;
                    200: 
                    201: void dump_isakmp_sa __P((char *, int));
                    202: void dump_internal __P((char *, int));
                    203: char *pindex_isakmp __P((isakmp_index *));
                    204: void print_schedule __P((caddr_t, int));
                    205: void print_evt __P((struct evt_async *));
                    206: char * fixed_addr __P((char *, char *, int));
                    207: 
                    208: static void
                    209: usage()
                    210: {
                    211:        printf(
                    212: "Usage:\n"
                    213: "  %s [opts] reload-config\n"
                    214: "  %s [opts] show-schedule\n"
                    215: "  %s [opts] show-sa [protocol]\n"
                    216: "  %s [opts] flush-sa [protocol]\n"
                    217: "  %s [opts] delete-sa <saopts>\n"
                    218: "  %s [opts] establish-sa [-u identity] [-n remoteconf] [-w] <saopts>\n"
                    219: "  %s [opts] vpn-connect [-u identity] vpn_gateway\n"
                    220: "  %s [opts] vpn-disconnect vpn_gateway\n"
                    221: "  %s [opts] show-event\n"
                    222: "  %s [opts] logout-user login\n"
                    223: "\n"
                    224: "General options:\n"
                    225: "  -d          Debug: hexdump admin messages before sending\n"
                    226: "  -l          Increase output verbosity (mainly for show-sa)\n"
                    227: "  -s <socket> Specify adminport socket to use (default: %s)\n"
                    228: "\n"
                    229: "Parameter specifications:\n"
                    230: "    <protocol>: \"isakmp\", \"esp\" or \"ah\".\n"
                    231: "        In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n"
                    232: "\n"
                    233: "    <saopts>: \"isakmp\" <family> <src> <dst>\n"
                    234: "            : {\"esp\",\"ah\"} <family> <src/prefixlen/port> <dst/prefixlen/port>\n"
                    235: "                              <ul_proto>\n"
                    236: "    <family>: \"inet\" or \"inet6\"\n"
                    237: "    <ul_proto>: \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n"
                    238: "\n",
                    239:                pname, pname, pname, pname, pname, pname, pname, pname, pname, pname,
                    240:                ADMINSOCK_PATH);
                    241: }
                    242: 
                    243: /*
                    244:  * Check for proper racoonctl interface
                    245:  */
                    246: #if ((RACOONCTL_INTERFACE_MAJOR != 1) || (RACOONCTL_INTERFACE < 20041230))
                    247: #error "Incompatible racoonctl interface"
                    248: #endif
                    249: 
                    250: int
                    251: main(ac, av)
                    252:        int ac;
                    253:        char **av;
                    254: {
                    255:        vchar_t *combuf;
                    256:        int c;
                    257: 
                    258:        pname = *av;
                    259: 
                    260:        /*
                    261:         * Check for proper racoonctl interface
                    262:         */
                    263:        if ((racoonctl_interface_major != RACOONCTL_INTERFACE_MAJOR) ||
                    264:            (racoonctl_interface < RACOONCTL_INTERFACE))
                    265:                errx(1, "Incompatible racoonctl interface");
                    266: 
                    267: #ifdef __linux__
                    268:        /*
                    269:         * Disable GNU extensions that will prevent racoonct vc -u login
                    270:         * from working (GNU getopt(3) does not like options after vc)
                    271:         */
                    272:        setenv("POSIXLY_CORRECT", "1", 0);
                    273: #endif
                    274:        while ((c = getopt(ac, av, "lds:")) != -1) {
                    275:                switch(c) {
                    276:                case 'l':
                    277:                        long_format++;
                    278:                        break;
                    279: 
                    280:                case 'd':
                    281:                        loglevel++;
                    282:                        break;
                    283: 
                    284:                case 's':
                    285:                        adminsock_path = optarg;
                    286:                        break;
                    287: 
                    288:                default:
                    289:                        usage();
                    290:                        exit(0);
                    291:                }
                    292:        }
                    293: 
                    294:        ac -= optind;
                    295:        av += optind;
                    296: 
                    297:        combuf = get_combuf(ac, av);
                    298:        if (!combuf)
                    299:                err(1, "kmpstat");
                    300: 
                    301:        if (loglevel)
                    302:                racoon_hexdump(combuf, ((struct admin_com *)combuf)->ac_len);
                    303: 
                    304:        com_init();
                    305: 
                    306:        if (com_send(combuf) != 0)
                    307:                goto bad;
                    308: 
                    309:        vfree(combuf);
                    310: 
                    311:        do {
                    312:                if (com_recv(&combuf) != 0)
                    313:                        goto bad;
                    314:                if (handle_recv(combuf) != 0)
                    315:                        goto bad;
                    316:                vfree(combuf);
                    317:        } while (evt_quit_event != 0);
                    318: 
                    319:        close(so);
                    320:        exit(0);
                    321: 
                    322: bad:
                    323:        close(so);
                    324:        if (errno == EEXIST)
                    325:                exit(0);
                    326:        exit(1);
                    327: }
                    328: 
                    329: /* %%% */
                    330: /*
                    331:  * return command buffer.
                    332:  */
                    333: static vchar_t *
                    334: get_combuf(ac, av)
                    335:        int ac;
                    336:        char **av;
                    337: {
                    338:        struct cmd_tag *cp;
                    339: 
                    340:        if (ac == 0) {
                    341:                usage();
                    342:                exit(0);
                    343:        }
                    344: 
                    345:        /* checking the string of command. */
                    346:        for (cp = &cmdtab[0]; cp->str; cp++) {
                    347:                if (strcmp(*av, cp->str) == 0) {
                    348:                        break;
                    349:                }
                    350:        }
                    351:        if (!cp->str) {
                    352:                printf("Invalid command [%s]\n", *av);
                    353:                errno = EINVAL;
                    354:                return NULL;
                    355:        }
                    356: 
                    357:        ac--;
                    358:        av++;
                    359:        return (cp->func)(ac, av);
                    360: }
                    361: 
                    362: static vchar_t *
                    363: make_request(u_int16_t cmd, u_int16_t proto, size_t len)
                    364: {
                    365:        vchar_t *buf;
                    366:        struct admin_com *head;
                    367: 
                    368:        buf = vmalloc(sizeof(struct admin_com) + len);
                    369:        if (buf == NULL)
                    370:                errx(1, "not enough core");
                    371: 
                    372:        head = (struct admin_com *) buf->v;
                    373:        head->ac_len = buf->l;
                    374:        head->ac_cmd = ADMIN_FLAG_VERSION | cmd;
                    375:        head->ac_version = 1;
                    376:        head->ac_proto = proto;
                    377: 
                    378:        return buf;
                    379: }
                    380: 
                    381: static vchar_t *
                    382: f_reload(ac, av)
                    383:        int ac;
                    384:        char **av;
                    385: {
                    386:        return make_request(ADMIN_RELOAD_CONF, 0, 0);
                    387: }
                    388: 
                    389: static vchar_t *
                    390: f_getevt(ac, av)
                    391:        int ac;
                    392:        char **av;
                    393: {
                    394:        evt_quit_event = -1;
                    395:        if (ac >= 1)
                    396:                errx(1, "too many arguments");
                    397: 
                    398:        return make_request(ADMIN_SHOW_EVT, 0, 0);
                    399: }
                    400: 
                    401: static vchar_t *
                    402: f_getsched(ac, av)
                    403:        int ac;
                    404:        char **av;
                    405: {
                    406:        return make_request(ADMIN_SHOW_SCHED, 0, 0);
                    407: }
                    408: 
                    409: static vchar_t *
                    410: f_getsa(ac, av)
                    411:        int ac;
                    412:        char **av;
                    413: {
                    414:        int proto;
                    415: 
                    416:        /* need protocol */
                    417:        if (ac != 1)
                    418:                errx(1, "insufficient arguments");
                    419:        proto = get_proto(*av);
                    420:        if (proto == -1)
                    421:                errx(1, "unknown protocol %s", *av);
                    422: 
                    423:        return make_request(ADMIN_SHOW_SA, proto, 0);
                    424: }
                    425: 
                    426: static vchar_t *
                    427: f_getsacert(ac, av)
                    428:        int ac;
                    429:        char **av;
                    430: {
                    431:        vchar_t *buf, *index;
                    432:        struct admin_com_indexes *com;
                    433: 
                    434:        index = get_index(ac, av);
                    435:        if (index == NULL)
                    436:                return NULL;
                    437: 
                    438:        com = (struct admin_com_indexes *) index->v;
                    439:        buf = make_request(ADMIN_GET_SA_CERT, ADMIN_PROTO_ISAKMP, index->l);
                    440:        if (buf == NULL)
                    441:                errx(1, "Cannot allocate buffer");
                    442: 
                    443:        memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
                    444: 
                    445:        vfree(index);
                    446: 
                    447:        return buf;
                    448: }
                    449: 
                    450: static vchar_t *
                    451: f_flushsa(ac, av)
                    452:        int ac;
                    453:        char **av;
                    454: {
                    455:        vchar_t *buf;
                    456:        struct admin_com *head;
                    457:        int proto;
                    458: 
                    459:        /* need protocol */
                    460:        if (ac != 1)
                    461:                errx(1, "insufficient arguments");
                    462:        proto = get_proto(*av);
                    463:        if (proto == -1)
                    464:                errx(1, "unknown protocol %s", *av);
                    465: 
                    466:        return make_request(ADMIN_FLUSH_SA, proto, 0);
                    467: }
                    468: 
                    469: static vchar_t *
                    470: f_deletesa(ac, av)
                    471:        int ac;
                    472:        char **av;
                    473: {
                    474:        vchar_t *buf, *index;
                    475:        int proto;
                    476: 
                    477:        /* need protocol */
                    478:        if (ac < 1)
                    479:                errx(1, "insufficient arguments");
                    480:        proto = get_proto(*av);
                    481:        if (proto == -1)
                    482:                errx(1, "unknown protocol %s", *av);
                    483: 
                    484:        /* get index(es) */
                    485:        av++;
                    486:        ac--;
                    487:        switch (proto) {
                    488:        case ADMIN_PROTO_ISAKMP:
                    489:                index = get_index(ac, av);
                    490:                if (index == NULL)
                    491:                        return NULL;
                    492:                break;
                    493:        case ADMIN_PROTO_AH:
                    494:        case ADMIN_PROTO_ESP:
                    495:                index = get_index(ac, av);
                    496:                if (index == NULL)
                    497:                        return NULL;
                    498:                break;
                    499:        default:
                    500:                errno = EPROTONOSUPPORT;
                    501:                return NULL;
                    502:        }
                    503: 
                    504:        buf = make_request(ADMIN_DELETE_SA, proto, index->l);
                    505:        if (buf == NULL)
                    506:                goto out;
                    507: 
                    508:        memcpy(buf->v + sizeof(struct admin_com), index->v, index->l);
                    509: 
                    510: out:
                    511:        if (index != NULL)
                    512:                vfree(index);
                    513: 
                    514:        return buf;
                    515: }
                    516: 
                    517: static vchar_t *
                    518: f_deleteallsadst(ac, av)
                    519:        int ac;
                    520:        char **av;
                    521: {
                    522:        vchar_t *buf, *index;
                    523:        u_int16_t proto;
                    524: 
                    525:        index = get_proto_and_index(ac, av, &proto);
                    526:        if (index == NULL)
                    527:                return NULL;
                    528: 
                    529:        buf = make_request(ADMIN_DELETE_ALL_SA_DST, proto, index->l);
                    530:        if (buf == NULL)
                    531:                goto out;
                    532: 
                    533:        memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
                    534: 
                    535: out:
                    536:        if (index != NULL)
                    537:                vfree(index);
                    538: 
                    539:        return buf;
                    540: }
                    541: 
                    542: static vchar_t *
                    543: f_exchangesa(ac, av)
                    544:        int ac;
                    545:        char **av;
                    546: {
                    547:        vchar_t *buf, *index;
                    548:        u_int16_t proto;
                    549:        int cmd = ADMIN_ESTABLISH_SA;
                    550:        size_t com_len = 0;
                    551:        char *id = NULL;
                    552:        char *key = NULL;
                    553:        char *remoteconf = NULL;
                    554:        struct admin_com_psk *acp;
                    555:        int wait = 0;
                    556: 
                    557:        if (ac < 1)
                    558:                errx(1, "insufficient arguments");
                    559: 
                    560:        /* Optional -u identity */
                    561:        if (strcmp(av[0], "-u") == 0) {
                    562:                if (ac < 2)
                    563:                        errx(1, "-u require an argument");
                    564: 
                    565:                id = av[1];
                    566:                if ((key = getpass("Password: ")) == NULL)
                    567:                        errx(1, "getpass() failed: %s", strerror(errno));
                    568:                
                    569:                com_len += sizeof(*acp) + strlen(id) + 1 + strlen(key) + 1;
                    570:                cmd = ADMIN_ESTABLISH_SA_PSK;
                    571: 
                    572:                av += 2;
                    573:                ac -= 2;
                    574:        }
                    575: 
                    576:        if (ac >= 2 && strcmp(av[0], "-n") == 0) {
                    577:                /* Remoteconf name */
                    578:                remoteconf = av[1];
                    579:                av += 2;
                    580:                ac -= 2;
                    581:        }
                    582: 
                    583:        if (ac >= 1 && strcmp(av[0], "-w") == 0) {
                    584:                wait = 1;
                    585:                av++;
                    586:                ac--;
                    587:        }
                    588: 
                    589:        index = get_proto_and_index(ac, av, &proto);
                    590:        if (index == NULL)
                    591:                return NULL;
                    592: 
                    593:        if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
                    594:            remoteconf != NULL)
                    595:                com_len += strlen(remoteconf) + 1;
                    596: 
                    597:        if (wait) {
                    598:                switch (proto) {
                    599:                case ADMIN_PROTO_ISAKMP:
                    600:                        evt_quit_event = EVT_PHASE1_MODE_CFG;
                    601:                        break;
                    602:                case ADMIN_PROTO_AH:
                    603:                case ADMIN_PROTO_ESP:
                    604:                        evt_quit_event = EVT_PHASE2_UP;
                    605:                        break;
                    606:                default:
                    607:                        errno = EPROTONOSUPPORT;
                    608:                        return NULL;
                    609:                }
                    610:        }
                    611: 
                    612:        com_len += index->l;
                    613:        buf = make_request(cmd, proto, com_len);
                    614:        if (buf == NULL)
                    615:                errx(1, "Cannot allocate buffer");
                    616: 
                    617:        memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
                    618: 
                    619:        if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
                    620:            remoteconf != NULL) {
                    621:                strcpy(buf->v + sizeof(struct admin_com) + index->l,
                    622:                       remoteconf);
                    623:        } else if (id && key) {
                    624:                char *data;
                    625:                acp = (struct admin_com_psk *)
                    626:                    (buf->v + sizeof(struct admin_com) + index->l);
                    627: 
                    628:                acp->id_type = IDTYPE_USERFQDN;
                    629:                acp->id_len = strlen(id) + 1;
                    630:                acp->key_len = strlen(key) + 1;
                    631: 
                    632:                data = (char *)(acp + 1);
                    633:                strcpy(data, id);
                    634: 
                    635:                data = (char *)(data + acp->id_len);
                    636:                strcpy(data, key);
                    637:        }
                    638: 
                    639:        vfree(index);
                    640: 
                    641:        return buf;
                    642: }
                    643: 
                    644: static vchar_t *
                    645: f_vpnc(ac, av)
                    646:        int ac;
                    647:        char **av;
                    648: {
                    649:        char *nav[] = {NULL, NULL, NULL, NULL, NULL, NULL};
                    650:        int nac = 0;
                    651:        char *isakmp = "isakmp";
                    652:        char *inet = "inet";
                    653:        char *srcaddr;
                    654:        struct addrinfo hints, *res;
                    655:        struct sockaddr *src;
                    656:        char *idx;
                    657: 
                    658:        if (ac < 1)
                    659:                errx(1, "insufficient arguments");
                    660: 
                    661:        evt_quit_event = EVT_PHASE1_MODE_CFG;
                    662:        
                    663:        /* Optional -u identity */
                    664:        if (strcmp(av[0], "-u") == 0) {
                    665:                if (ac < 2)
                    666:                        errx(1, "-u require an argument");
                    667: 
                    668:                nav[nac++] = av[0];
                    669:                nav[nac++] = av[1];
                    670: 
                    671:                ac -= 2;
                    672:                av += 2;
                    673:        }
                    674: 
                    675:        if (ac < 1)
                    676:                errx(1, "VPN gateway required");
                    677:        if (ac > 1)
                    678:                warnx("Extra arguments");
                    679: 
                    680:        /*
                    681:         * Find the source address
                    682:         */
                    683:        memset(&hints, 0, sizeof(hints));
                    684:        hints.ai_family = PF_UNSPEC;
                    685:        hints.ai_socktype = SOCK_DGRAM;
                    686:        if (getaddrinfo(av[0], "4500", &hints, &res) != 0)
                    687:                errx(1, "Cannot resolve destination address");
                    688: 
                    689:        if ((src = getlocaladdr(res->ai_addr)) == NULL)
                    690:                errx(1, "cannot find source address");
                    691: 
                    692:        if ((srcaddr = saddr2str(src)) == NULL)
                    693:                errx(1, "cannot read source address");
                    694: 
                    695:        /* We get "ip[port]" strip the port */
                    696:        if ((idx = index(srcaddr, '[')) == NULL) 
                    697:                errx(1, "unexpected source address format");
                    698:        *idx = '\0';
                    699: 
                    700:        nav[nac++] = isakmp;
                    701:        nav[nac++] = inet;
                    702:        nav[nac++] = srcaddr;
                    703:        nav[nac++] = av[0];
                    704: 
                    705:        return f_exchangesa(nac, nav);
                    706: }
                    707: 
                    708: static vchar_t *
                    709: f_vpnd(ac, av)
                    710:        int ac;
                    711:        char **av;
                    712: {
                    713:        char *nav[] = {NULL, NULL, NULL, NULL};
                    714:        int nac = 0;
                    715:        char *isakmp = "isakmp";
                    716:        char *inet = "inet";
                    717:        char *anyaddr = "0.0.0.0";
                    718:        char *idx;
                    719: 
                    720:        if (ac < 1)
                    721:                errx(1, "VPN gateway required");
                    722:        if (ac > 1)
                    723:                warnx("Extra arguments");
                    724: 
                    725:        evt_quit_event = EVT_PHASE1_DOWN;
                    726: 
                    727:        nav[nac++] = isakmp;
                    728:        nav[nac++] = inet;
                    729:        nav[nac++] = anyaddr;
                    730:        nav[nac++] = av[0];
                    731: 
                    732:        return f_deleteallsadst(nac, nav);
                    733: }
                    734: 
                    735: #ifdef ENABLE_HYBRID
                    736: static vchar_t *
                    737: f_logoutusr(ac, av)
                    738:        int ac;
                    739:        char **av;
                    740: {
                    741:        vchar_t *buf;
                    742:        char *user;
                    743:        size_t userlen;
                    744: 
                    745:        /* need username */
                    746:        if (ac < 1)
                    747:                errx(1, "insufficient arguments");
                    748:        user = av[0];
                    749:        userlen = strlen(user);
                    750:        if ((user == NULL) || (userlen > LOGINLEN))
                    751:                errx(1, "bad login (too long?)");
                    752: 
                    753:        buf = make_request(ADMIN_LOGOUT_USER, 0, userlen);
                    754:        if (buf == NULL)
                    755:                return NULL;
                    756: 
                    757:        strncpy(buf->v + sizeof(struct admin_com), user, userlen);
                    758: 
                    759:        return buf;
                    760: }
                    761: #endif /* ENABLE_HYBRID */
                    762: 
                    763: static vchar_t *
                    764: get_proto_and_index(ac, av, proto)
                    765:        int ac;
                    766:        char **av;
                    767:        u_int16_t *proto;
                    768: {
                    769:        vchar_t *index = NULL;
                    770: 
                    771:        /* need protocol */
                    772:        if (ac < 1)
                    773:                errx(1, "insufficient arguments");
                    774:        *proto = get_proto(*av);
                    775:        if (*proto == (u_int16_t) -1)
                    776:                errx(1, "unknown protocol %s", *av);
                    777: 
                    778:        /* get index(es) */
                    779:        av++;
                    780:        ac--;
                    781:        switch (*proto) {
                    782:        case ADMIN_PROTO_ISAKMP:
                    783:        case ADMIN_PROTO_AH:
                    784:        case ADMIN_PROTO_ESP:
                    785:                index = get_index(ac, av);
                    786:                break;
                    787:        default:
                    788:                errno = EPROTONOSUPPORT;
                    789:                break;
                    790:        }
                    791:        return index;
                    792: }
                    793: 
                    794: static int
                    795: get_proto(str)
                    796:        char *str;
                    797: {
                    798:        struct proto_tag *cp;
                    799: 
                    800:        if (str == NULL) {
                    801:                errno = EINVAL;
                    802:                return -1;
                    803:        }
                    804: 
                    805:        /* checking the string of command. */
                    806:        for (cp = &prototab[0]; cp->str; cp++) {
                    807:                if (strcmp(str, cp->str) == 0)
                    808:                        return cp->proto;
                    809:        }
                    810: 
                    811:        errno = EINVAL;
                    812:        return -1;
                    813: }
                    814: 
                    815: static vchar_t *
                    816: get_index(ac, av)
                    817:        int ac;
                    818:        char **av;
                    819: {
                    820:        int family;
                    821: 
                    822:        if (ac != 3 && ac != 4) {
                    823:                errno = EINVAL;
                    824:                return NULL;
                    825:        }
                    826: 
                    827:        /* checking the string of family */
                    828:        family = get_family(*av);
                    829:        if (family == -1)
                    830:                return NULL;
                    831:        av++;
                    832:        ac--;
                    833: 
                    834:        return get_comindexes(family, ac, av);
                    835: }
                    836: 
                    837: static int
                    838: get_family(str)
                    839:        char *str;
                    840: {
                    841:        if (strcmp("inet", str) == 0)
                    842:                return AF_INET;
                    843: #ifdef INET6
                    844:        else if (strcmp("inet6", str) == 0)
                    845:                return AF_INET6;
                    846: #endif
                    847:        errno = EAFNOSUPPORT;
                    848:        return -1;
                    849: }
                    850: 
                    851: static vchar_t *
                    852: get_comindexes(family, ac, av)
                    853:        int family;
                    854:        int ac;
                    855:        char **av;
                    856: {
                    857:        vchar_t *buf;
                    858:        struct admin_com_indexes *ci;
                    859:        char *p_name = NULL, *p_port = NULL;
                    860:        char *p_prefs = NULL, *p_prefd = NULL;
                    861:        struct sockaddr *src = NULL, *dst = NULL;
                    862:        int ulproto;
                    863: 
                    864:        if (ac != 2 && ac != 3) {
                    865:                errno = EINVAL;
                    866:                return NULL;
                    867:        }
                    868: 
                    869:        if (get_comindex(*av, &p_name, &p_port, &p_prefs) == -1)
                    870:                goto bad;
                    871:        src = get_sockaddr(family, p_name, p_port);
                    872:        if (p_name) {
                    873:                racoon_free(p_name);
                    874:                p_name = NULL;
                    875:        }
                    876:        if (p_port) {
                    877:                racoon_free(p_port);
                    878:                p_port = NULL;
                    879:        }
                    880:        if (src == NULL)
                    881:                goto bad;
                    882:        av++;
                    883:        ac--;
                    884:        if (get_comindex(*av, &p_name, &p_port, &p_prefd) == -1)
                    885:                goto bad;
                    886:        dst = get_sockaddr(family, p_name, p_port);
                    887:        if (p_name) {
                    888:                racoon_free(p_name);
                    889:                p_name = NULL;
                    890:        }
                    891:        if (p_port) {
                    892:                racoon_free(p_port);
                    893:                p_port = NULL;
                    894:        }
                    895:        if (dst == NULL)
                    896:                goto bad;
                    897: 
                    898:        buf = vmalloc(sizeof(*ci));
                    899:        if (buf == NULL)
                    900:                goto bad;
                    901: 
                    902:        av++;
                    903:        ac--;
                    904:        if(ac){
                    905:                ulproto = get_ulproto(*av);
                    906:                if (ulproto == -1)
                    907:                        goto bad;
                    908:        }else
                    909:                ulproto=0;
                    910: 
                    911:        ci = (struct admin_com_indexes *)buf->v;
                    912:        if(p_prefs)
                    913:                ci->prefs = (u_int8_t)atoi(p_prefs); /* XXX should be handled error. */
                    914:        else
                    915:                ci->prefs = 32;
                    916:        if(p_prefd)
                    917:                ci->prefd = (u_int8_t)atoi(p_prefd); /* XXX should be handled error. */
                    918:        else
                    919:                ci->prefd = 32;
                    920:        ci->ul_proto = ulproto;
                    921:        memcpy(&ci->src, src, sysdep_sa_len(src));
                    922:        memcpy(&ci->dst, dst, sysdep_sa_len(dst));
                    923: 
                    924:        if (p_name)
                    925:                racoon_free(p_name);
                    926: 
                    927:        return buf;
                    928: 
                    929:    bad:
                    930:        if (p_name)
                    931:                racoon_free(p_name);
                    932:        if (p_port)
                    933:                racoon_free(p_port);
                    934:        if (p_prefs)
                    935:                racoon_free(p_prefs);
                    936:        if (p_prefd)
                    937:                racoon_free(p_prefd);
                    938:        return NULL;
                    939: }
                    940: 
                    941: static int
                    942: get_comindex(str, name, port, pref)
                    943:        char *str, **name, **port, **pref;
                    944: {
                    945:        char *p;
                    946: 
                    947:        *name = *port = *pref = NULL;
                    948: 
                    949:        *name = racoon_strdup(str);
                    950:        STRDUP_FATAL(*name);
                    951:        p = strpbrk(*name, "/[");
                    952:        if (p != NULL) {
                    953:                if (*(p + 1) == '\0')
                    954:                        goto bad;
                    955:                if (*p == '/') {
                    956:                        *p = '\0';
                    957:                        *pref = racoon_strdup(p + 1);
                    958:                        STRDUP_FATAL(*pref);
                    959:                        p = strchr(*pref, '[');
                    960:                        if (p != NULL) {
                    961:                                if (*(p + 1) == '\0')
                    962:                                        goto bad;
                    963:                                *p = '\0';
                    964:                                *port = racoon_strdup(p + 1);
                    965:                                STRDUP_FATAL(*port);
                    966:                                p = strchr(*pref, ']');
                    967:                                if (p == NULL)
                    968:                                        goto bad;
                    969:                                *p = '\0';
                    970:                        }
                    971:                } else if (*p == '[') {
                    972:                        if (*pref == NULL)
                    973:                                goto bad;
                    974:                        *p = '\0';
                    975:                        *port = racoon_strdup(p + 1);
                    976:                        STRDUP_FATAL(*port);
                    977:                        p = strchr(*pref, ']');
                    978:                        if (p == NULL)
                    979:                                goto bad;
                    980:                        *p = '\0';
                    981:                } else {
                    982:                        /* XXX */
                    983:                }
                    984:        }
                    985: 
                    986:        return 0;
                    987: 
                    988:     bad:
                    989: 
                    990:        if (*name)
                    991:                racoon_free(*name);
                    992:        if (*port)
                    993:                racoon_free(*port);
                    994:        if (*pref)
                    995:                racoon_free(*pref);
                    996:        *name = *port = *pref = NULL;
                    997:        return -1;
                    998: }
                    999: 
                   1000: static int
                   1001: get_ulproto(str)
                   1002:        char *str;
                   1003: {
                   1004:        struct ulproto_tag *cp;
                   1005: 
                   1006:        if(str == NULL){
                   1007:                errno = EINVAL;
                   1008:                return -1;
                   1009:        }
                   1010: 
                   1011:        /* checking the string of upper layer protocol. */
                   1012:        for (cp = &ulprototab[0]; cp->str; cp++) {
                   1013:                if (strcmp(str, cp->str) == 0)
                   1014:                        return cp->ul_proto;
                   1015:        }
                   1016: 
                   1017:        errno = EINVAL;
                   1018:        return -1;
                   1019: }
                   1020: 
                   1021: /* %%% */
                   1022: void
                   1023: dump_isakmp_sa(buf, len)
                   1024:        char *buf;
                   1025:        int len;
                   1026: {
                   1027:        struct ph1dump *pd;
                   1028:        struct tm *tm;
                   1029:        char tbuf[56];
                   1030:        caddr_t p = NULL;
                   1031: 
                   1032: /* isakmp status header */
                   1033: /* short header;
                   1034:  1234567890123456789012 0000000000000000:0000000000000000 000000000000
                   1035: */
                   1036: char *header1 = 
                   1037: "Destination            Cookies                           Created";
                   1038: 
                   1039: /* semi long header;
                   1040:  1234567890123456789012 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
                   1041: */
                   1042: char *header2 = 
                   1043: "Destination            Cookies                           ST S  V E Created             Phase2";
                   1044: 
                   1045: /* long header;
                   1046:  0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
                   1047: */
                   1048: char *header3 =
                   1049: "Source                                        Destination                                   Cookies                           ST S  V E Created             Phase2";
                   1050: 
                   1051: /* phase status header */
                   1052: /* short format;
                   1053:    side stats source address         destination address   
                   1054:    xxx  xxxxx 1234567890123456789012 1234567890123456789012
                   1055: */
                   1056: 
                   1057:        static char *estr[] = { "", "B", "M", "U", "A", "I", };
                   1058: 
                   1059:        switch (long_format) {
                   1060:        case 0:
                   1061:                printf("%s\n", header1);
                   1062:                break;
                   1063:        case 1:
                   1064:                printf("%s\n", header2);
                   1065:                break;
                   1066:        case 2:
                   1067:        default:
                   1068:                printf("%s\n", header3);
                   1069:                break;
                   1070:        }
                   1071: 
                   1072:        if (len % sizeof(*pd))
                   1073:                printf("invalid length %d\n", len);
                   1074:        len /= sizeof(*pd);
                   1075: 
                   1076:        pd = (struct ph1dump *)buf;
                   1077: 
                   1078:        while (len-- > 0) {
                   1079:                /* source address */
                   1080:                if (long_format >= 2) {
                   1081:                        GETNAMEINFO((struct sockaddr *)&pd->local, _addr1_, _addr2_);
                   1082:                        switch (long_format) {
                   1083:                        case 0:
                   1084:                                break;
                   1085:                        case 1:
                   1086:                                p = fixed_addr(_addr1_, _addr2_, 22);
                   1087:                                break;
                   1088:                        case 2:
                   1089:                        default:
                   1090:                                p = fixed_addr(_addr1_, _addr2_, 45);
                   1091:                                break;
                   1092:                        }
                   1093:                        printf("%s ", p);
                   1094:                }
                   1095: 
                   1096:                /* destination address */
                   1097:                GETNAMEINFO((struct sockaddr *)&pd->remote, _addr1_, _addr2_);
                   1098:                switch (long_format) {
                   1099:                case 0:
                   1100:                case 1:
                   1101:                        p = fixed_addr(_addr1_, _addr2_, 22);
                   1102:                        break;
                   1103:                case 2:
                   1104:                default:
                   1105:                        p = fixed_addr(_addr1_, _addr2_, 45);
                   1106:                        break;
                   1107:                }
                   1108:                printf("%s ", p);
                   1109: 
                   1110:                printf("%s ", pindex_isakmp(&pd->index));
                   1111: 
                   1112:                /* statuc, side and version */
                   1113:                if (long_format >= 1) {
                   1114:                        printf("%2d %c %2x ",
                   1115:                                pd->status,
                   1116:                                pd->side == INITIATOR ? 'I' : 'R',
                   1117:                                pd->version);
                   1118:                        if (ARRAYLEN(estr) > pd->etype)
                   1119:                                printf("%s ", estr[pd->etype]);
                   1120:                }
                   1121: 
                   1122:                /* created date */
                   1123:                if (pd->created) {
                   1124:                        tm = localtime(&pd->created);
                   1125:                        strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);
                   1126:                } else
                   1127:                        snprintf(tbuf, sizeof(tbuf), "                   ");
                   1128:                printf("%s ", tbuf);
                   1129: 
                   1130:                /* counter of phase 2 */
                   1131:                if (long_format >= 1)
                   1132:                        printf("%6d ", pd->ph2cnt);
                   1133: 
                   1134:                printf("\n");
                   1135: 
                   1136:                pd++;
                   1137:        }
                   1138: 
                   1139:        return;
                   1140: }
                   1141: 
                   1142: /* %%% */
                   1143: void
                   1144: dump_internal(buf, tlen)
                   1145:        char *buf;
                   1146:        int tlen;
                   1147: {
                   1148:        struct ph2handle *iph2;
                   1149:        struct sockaddr *addr;
                   1150: 
                   1151: /*
                   1152: short header;
                   1153:  source address         destination address    
                   1154:  1234567890123456789012 1234567890123456789012 
                   1155: */
                   1156: char *short_h1 = 
                   1157: "Source                 Destination            ";
                   1158: 
                   1159: /*
                   1160: long header;
                   1161:  source address                                destination address                           
                   1162:  123456789012345678901234567890123456789012345 123456789012345678901234567890123456789012345 
                   1163:  0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000
                   1164: */
                   1165: char *long_h1 = 
                   1166: "Source                                        Destination                                  ";
                   1167: 
                   1168:        printf("%s\n", long_format ? long_h1 : short_h1);
                   1169: 
                   1170:        while (tlen > 0) {
                   1171:                iph2 = (struct ph2handle *)buf;
                   1172:                addr = (struct sockaddr *)(++iph2);
                   1173: 
                   1174:                GETNAMEINFO(addr, _addr1_, _addr2_);
                   1175:                printf("%s ", long_format ?
                   1176:                          fixed_addr(_addr1_, _addr2_, 45)
                   1177:                        : fixed_addr(_addr1_, _addr2_, 22));
                   1178:                addr++;
                   1179:                tlen -= sysdep_sa_len(addr);
                   1180: 
                   1181:                GETNAMEINFO(addr, _addr1_, _addr2_);
                   1182:                printf("%s ", long_format ?
                   1183:                          fixed_addr(_addr1_, _addr2_, 45)
                   1184:                        : fixed_addr(_addr1_, _addr2_, 22));
                   1185:                addr++;
                   1186:                tlen -= sysdep_sa_len(addr);
                   1187: 
                   1188:                printf("\n");
                   1189:        }
                   1190: 
                   1191:        return;
                   1192: }
                   1193: 
                   1194: /* %%% */
                   1195: char *
                   1196: pindex_isakmp(index)
                   1197:        isakmp_index *index;
                   1198: {
                   1199:        static char buf[64];
                   1200:        u_char *p;
                   1201:        int i, j;
                   1202: 
                   1203:        memset(buf, 0, sizeof(buf));
                   1204: 
                   1205:        /* copy index */
                   1206:        p = (u_char *)index;
                   1207:        for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
                   1208:                snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
                   1209:                j += 2;
                   1210:                switch (i) {
                   1211:                case 7:
                   1212: #if 0
                   1213:                case 15:
                   1214: #endif
                   1215:                        buf[j++] = ':';
                   1216:                }
                   1217:        }
                   1218: 
                   1219:        return buf;
                   1220: }
                   1221: 
                   1222: /* print schedule */
                   1223: char *str_sched_stat[] = {
                   1224: "off",
                   1225: "on",
                   1226: "dead",
                   1227: };
                   1228: 
                   1229: char *str_sched_id[] = {
                   1230: "PH1resend",
                   1231: "PH1lifetime",
                   1232: "PH2resend",
                   1233: "PSTacquire",
                   1234: "PSTlifetime",
                   1235: };
                   1236: 
                   1237: void
                   1238: print_schedule(buf, len)
                   1239:        caddr_t buf;
                   1240:        int len;
                   1241: {
                   1242:        struct scheddump *sc = (struct scheddump *)buf;
                   1243:        struct tm *tm;
                   1244:        char tbuf[56];
                   1245: 
                   1246:        if (len % sizeof(*sc))
                   1247:                printf("invalid length %d\n", len);
                   1248:        len /= sizeof(*sc);
                   1249: 
                   1250:        /*      00000000 00000000 00000000 xxx........*/
                   1251:        printf("index    tick     xtime    created\n");
                   1252: 
                   1253:        while (len-- > 0) {
                   1254:                tm = localtime(&sc->created);
                   1255:                strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);
                   1256: 
                   1257:                printf("%-8ld %-8ld %-8ld %s\n",
                   1258:                        sc->id,
                   1259:                        (long)sc->tick,
                   1260:                        (long)sc->xtime,
                   1261:                        tbuf);
                   1262:                sc++;
                   1263:        }
                   1264: 
                   1265:        return;
                   1266: }
                   1267: 
                   1268: 
                   1269: void
                   1270: print_evt(evtdump)
                   1271:        struct evt_async *evtdump;
                   1272: {
                   1273:        int i;
                   1274:        char *srcstr;
                   1275:        char *dststr;
                   1276:        
                   1277:        for (i = 0; i < sizeof(evtmsg) / sizeof(evtmsg[0]); i++)
                   1278:                if (evtmsg[i].type == evtdump->ec_type)
                   1279:                        break;
                   1280: 
                   1281:        if (evtmsg[i].msg == NULL)
                   1282:                printf("Event %d: ", evtdump->ec_type);
                   1283:        else
                   1284:                printf("%s : ", evtmsg[i].msg);
                   1285: 
                   1286:        if ((srcstr = saddr2str((struct sockaddr *)&evtdump->ec_ph1src)) == NULL)
                   1287:                printf("unknown");
                   1288:        else
                   1289:                printf("%s", srcstr);
                   1290:        printf(" -> ");
                   1291:        if ((dststr = saddr2str((struct sockaddr *)&evtdump->ec_ph1dst)) == NULL)
                   1292:                printf("unknown");
                   1293:        else
                   1294:                printf("%s", dststr);
                   1295:        printf("\n");
                   1296: }
                   1297: 
                   1298: /*
                   1299:  * Print ISAKMP mode config info (IP and banner)
                   1300:  */
                   1301: void
                   1302: print_cfg(buf, len)
                   1303:        caddr_t buf;
                   1304:        int len;
                   1305: {
                   1306:        struct evt_async *evtdump = (struct evt_async *)buf;
                   1307:        struct isakmp_data *attr;
                   1308:        char *banner = NULL;
                   1309:        struct in_addr addr4;
                   1310:        
                   1311:        memset(&addr4, 0, sizeof(addr4));
                   1312: 
                   1313:        if (evtdump->ec_type != EVT_PHASE1_MODE_CFG)
                   1314:                return;
                   1315: 
                   1316:        len -= sizeof(*evtdump);
                   1317:        attr = (struct isakmp_data *)(evtdump + 1);
                   1318: 
                   1319:        while (len > 0) {
                   1320:                if (len < sizeof(*attr)) {
                   1321:                        printf("short attribute too short\n");
                   1322:                        break;
                   1323:                }
                   1324: 
                   1325:                if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
                   1326:                        /* Short attribute, skip */
                   1327:                        len -= sizeof(*attr);
                   1328:                        attr++;
                   1329:                } else { /* Long attribute */
                   1330:                        char *n;
                   1331: 
                   1332:                        if (len < (sizeof(*attr) + ntohs(attr->lorv))) {
                   1333:                                printf("long attribute too long\n");
                   1334:                                break;
                   1335:                        }
                   1336: 
                   1337:                        switch (ntohs(attr->type) & ~ISAKMP_GEN_MASK) {
                   1338:                        case INTERNAL_IP4_ADDRESS:
                   1339:                                if (ntohs(attr->lorv) < sizeof(addr4)) {
                   1340:                                        printf("addr4 attribute too short\n");
                   1341:                                        break;
                   1342:                                }
                   1343:                                memcpy(&addr4, attr + 1, sizeof(addr4));
                   1344:                                break;
                   1345: 
                   1346:                        case UNITY_BANNER:
                   1347:                                banner = racoon_malloc(ntohs(attr->lorv) + 1);
                   1348:                                if (banner == NULL) {
                   1349:                                        printf("malloc failed\n");
                   1350:                                        break;
                   1351:                                }
                   1352:                                memcpy(banner, attr + 1, ntohs(attr->lorv));
                   1353:                                banner[ntohs(attr->lorv)] = '\0';
                   1354:                                break;
                   1355: 
                   1356:                        default:
                   1357:                                break;
                   1358:                        }
                   1359: 
                   1360:                        len -= (sizeof(*attr) + ntohs(attr->lorv));
                   1361:                        n = (char *)attr;
                   1362:                        attr = (struct isakmp_data *)
                   1363:                            (n + sizeof(*attr) + ntohs(attr->lorv));
                   1364:                }
                   1365:        }
                   1366: 
                   1367:        if (len > 0)
                   1368:                printf("Bound to address %s\n", inet_ntoa(addr4));
                   1369:        else
                   1370:                printf("VPN connexion established\n");
                   1371: 
                   1372:        if (banner) {
                   1373:                struct winsize win;
                   1374:                int col = 0;
                   1375:                int i;
                   1376: 
                   1377:                if (ioctl(1, TIOCGWINSZ, &win) != 1) 
                   1378:                        col = win.ws_col;
                   1379:                        
                   1380:                for (i = 0; i < col; i++)
                   1381:                        printf("%c", '=');
                   1382:                printf("\n%s\n", banner);
                   1383:                for (i = 0; i < col; i++)
                   1384:                        printf("%c", '=');
                   1385:                printf("\n");
                   1386:                racoon_free(banner);
                   1387:        }
                   1388: }
                   1389: 
                   1390: 
                   1391: char *
                   1392: fixed_addr(addr, port, len)
                   1393:        char *addr, *port;
                   1394:        int len;
                   1395: {
                   1396:        static char _addr_buf_[BUFSIZ];
                   1397:        char *p;
                   1398:        int plen, i;
                   1399: 
                   1400:        /* initialize */
                   1401:        memset(_addr_buf_, ' ', sizeof(_addr_buf_));
                   1402: 
                   1403:        plen = strlen(port);
                   1404:        if (len < plen + 1)
                   1405:                return NULL;
                   1406: 
                   1407:        p = _addr_buf_;
                   1408:        for (i = 0; i < len - plen - 1 && addr[i] != '\0'; /*noting*/)
                   1409:                *p++ = addr[i++];
                   1410:        *p++ = '.';
                   1411: 
                   1412:        for (i = 0; i < plen && port[i] != '\0'; /*noting*/)
                   1413:                *p++ = port[i++];
                   1414: 
                   1415:        _addr_buf_[len] = '\0';
                   1416: 
                   1417:        return _addr_buf_;
                   1418: }
                   1419: 
                   1420: static int
                   1421: handle_recv(combuf)
                   1422:        vchar_t *combuf;
                   1423: {
                   1424:         struct admin_com *com;
                   1425:         caddr_t buf;
                   1426:         int len;
                   1427: 
                   1428:        com = (struct admin_com *)combuf->v;
                   1429:        if (com->ac_cmd & ADMIN_FLAG_LONG_REPLY)
                   1430:                len = ((u_int32_t)com->ac_len) + (((u_int32_t)com->ac_len_high) << 16);
                   1431:        else
                   1432:                len = com->ac_len;
                   1433:        len -= sizeof(*com);
                   1434:        buf = combuf->v + sizeof(*com);
                   1435: 
                   1436:        switch (com->ac_cmd & ~ADMIN_FLAG_LONG_REPLY) {
                   1437:        case ADMIN_SHOW_SCHED:
                   1438:                print_schedule(buf, len);
                   1439:                break;
                   1440: 
                   1441:        case ADMIN_SHOW_EVT: {
                   1442:                struct evt_async *ec;
                   1443: 
                   1444:                /* We got no event? */
                   1445:                if (len == 0)
                   1446:                        break;
                   1447: 
                   1448:                if (len < sizeof(struct evt_async))
                   1449:                        errx(1, "Short buffer\n");
                   1450: 
                   1451:                ec = (struct evt_async *) buf;
                   1452:                if (evt_quit_event <= 0)
                   1453:                        print_evt(ec);
                   1454:                else if (evt_quit_event == ec->ec_type) {
                   1455:                        switch (ec->ec_type) {
                   1456:                        case EVT_PHASE1_MODE_CFG:
1.1.1.1.2.1! misho    1457:                                print_cfg((caddr_t) ec, len);
1.1       misho    1458:                                break;
                   1459:                        default:
                   1460:                                print_evt(ec);
                   1461:                                break;
                   1462:                        }
                   1463:                        evt_quit_event = 0;
                   1464:                }
                   1465:                break;
                   1466:        }
                   1467: 
                   1468:        case ADMIN_GET_SA_CERT:
                   1469:                fwrite(buf, len, 1, stdout);
                   1470:                break;
                   1471: 
                   1472:        case ADMIN_SHOW_SA:
                   1473:           {
                   1474:                switch (com->ac_proto) {
                   1475:                case ADMIN_PROTO_ISAKMP:
                   1476:                        dump_isakmp_sa(buf, len);
                   1477:                        break;
                   1478:                case ADMIN_PROTO_IPSEC:
                   1479:                case ADMIN_PROTO_AH:
                   1480:                case ADMIN_PROTO_ESP:
                   1481:                    {
                   1482:                        struct sadb_msg *msg = (struct sadb_msg *)buf;
                   1483: 
                   1484:                        switch (msg->sadb_msg_errno) {
                   1485:                        case ENOENT:
                   1486:                                switch (msg->sadb_msg_type) {
                   1487:                                case SADB_DELETE:
                   1488:                                case SADB_GET:
                   1489:                                        printf("No entry.\n");
                   1490:                                        break;
                   1491:                                case SADB_DUMP:
                   1492:                                        printf("No SAD entries.\n");
                   1493:                                        break;
                   1494:                                }
                   1495:                                break;
                   1496:                        case 0:
                   1497:                                while (1) {
                   1498:                                        pfkey_sadump(msg);
                   1499:                                        if (msg->sadb_msg_seq == 0)
                   1500:                                                break;
                   1501:                                        msg = (struct sadb_msg *)((caddr_t)msg +
                   1502:                                                     PFKEY_UNUNIT64(msg->sadb_msg_len));
                   1503:                                }
                   1504:                                break;
                   1505:                        default:
                   1506:                                printf("%s.\n", strerror(msg->sadb_msg_errno));
                   1507:                        }
                   1508:                    }
                   1509:                        break;
                   1510:                case ADMIN_PROTO_INTERNAL:
                   1511:                        dump_internal(buf, len);
                   1512:                        break;
                   1513:                default:
                   1514:                        printf("Invalid proto [%d]\n", com->ac_proto);
                   1515:                }
                   1516: 
                   1517:            }
                   1518:                break;
                   1519: 
                   1520:        default:
                   1521:                /* IGNORE */
                   1522:                break;
                   1523:        }
                   1524: 
                   1525:        return 0;
                   1526: 
                   1527: bad:
                   1528:        return -1;
                   1529: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>