Annotation of embedaddon/libpdel/ppp/test/main.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (c) 2001-2002 Packet Design, LLC.
        !             4:  * All rights reserved.
        !             5:  * 
        !             6:  * Subject to the following obligations and disclaimer of warranty,
        !             7:  * use and redistribution of this software, in source or object code
        !             8:  * forms, with or without modifications are expressly permitted by
        !             9:  * Packet Design; provided, however, that:
        !            10:  * 
        !            11:  *    (i)  Any and all reproductions of the source or object code
        !            12:  *         must include the copyright notice above and the following
        !            13:  *         disclaimer of warranties; and
        !            14:  *    (ii) No rights are granted, in any manner or form, to use
        !            15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
        !            16:  *         on advertising, endorsements, or otherwise except as such
        !            17:  *         appears in the above copyright notice or in the software.
        !            18:  * 
        !            19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
        !            20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
        !            21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
        !            22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
        !            23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
        !            24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
        !            25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
        !            26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
        !            27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
        !            28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
        !            29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
        !            30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
        !            31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
        !            32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
        !            33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
        !            35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
        !            36:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            37:  *
        !            38:  * Author: Archie Cobbs <archie@freebsd.org>
        !            39:  */
        !            40: 
        !            41: #include <sys/stat.h>
        !            42: #include <sys/param.h>
        !            43: #include <sys/socket.h>
        !            44: 
        !            45: #include <stdio.h>
        !            46: #include <stdlib.h>
        !            47: #include <signal.h>
        !            48: #include <stdarg.h>
        !            49: #include <string.h>
        !            50: #include <unistd.h>
        !            51: #include <syslog.h>
        !            52: #include <fetch.h>
        !            53: #include <errno.h>
        !            54: #include <assert.h>
        !            55: #include <netdb.h>
        !            56: #include <pthread.h>
        !            57: #include <err.h>
        !            58: #include <netgraph.h>
        !            59: 
        !            60: #include <netinet/in_systm.h>
        !            61: #include <netinet/in.h>
        !            62: #include <arpa/inet.h>
        !            63: 
        !            64: #include <netgraph/ng_message.h>
        !            65: #include <netgraph/ng_ksocket.h>
        !            66: #include <netgraph/ng_iface.h>
        !            67: 
        !            68: #include <openssl/ssl.h>
        !            69: 
        !            70: #include <pdel/structs/structs.h>
        !            71: #include <pdel/structs/type/array.h>
        !            72: #include <pdel/net/if_util.h>
        !            73: #include <pdel/util/typed_mem.h>
        !            74: #include <pdel/sys/alog.h>
        !            75: 
        !            76: #include <pdel/ppp/ppp_lib.h>
        !            77: #include <pdel/ppp/ppp_log.h>
        !            78: #include <pdel/ppp/ppp_auth.h>
        !            79: #include <pdel/ppp/ppp_auth_chap.h>
        !            80: #include <pdel/ppp/ppp_link.h>
        !            81: #include <pdel/ppp/ppp_bundle.h>
        !            82: #include <pdel/ppp/ppp_msoft.h>
        !            83: #include <pdel/ppp/ppp_engine.h>
        !            84: #include <pdel/ppp/ppp_manager.h>
        !            85: #include <pdel/ppp/ppp_pptp_server.h>
        !            86: #include <pdel/ppp/ppp_l2tp_server.h>
        !            87: 
        !            88: #define VENDOR_NAME    "PDEL library"
        !            89: 
        !            90: /*
        !            91:  * PPP manager definition.
        !            92:  *
        !            93:  * The PPP manager is the "application". The library defers to the
        !            94:  * manager for all "policy" decisions. The PPP engine is the thing
        !            95:  * that the application gets from the library which does all the
        !            96:  * PPP stuff.
        !            97:  */
        !            98: static ppp_manager_bundle_config_t     demo_manager_bundle_config;
        !            99: static ppp_manager_bundle_plumb_t      demo_manager_bundle_plumb;
        !           100: static ppp_manager_bundle_unplumb_t    demo_manager_bundle_unplumb;
        !           101: static ppp_manager_release_ip_t                demo_manager_release_ip;
        !           102: 
        !           103: static struct  ppp_manager_meth demo_manager_methods = {
        !           104:        demo_manager_bundle_config,
        !           105:        demo_manager_bundle_plumb,
        !           106:        demo_manager_bundle_unplumb,
        !           107:        demo_manager_release_ip,
        !           108: };
        !           109: 
        !           110: static struct  ppp_manager demo_manager = {
        !           111:        &demo_manager_methods
        !           112: };
        !           113: 
        !           114: /*
        !           115:  * PPP authorization callbacks and configuration.
        !           116:  */
        !           117: static ppp_auth_acquire_t              demo_auth_acquire;
        !           118: static ppp_auth_check_t                        demo_auth_check;
        !           119: 
        !           120: static struct  ppp_auth_meth demo_auth_meth = {
        !           121:        demo_auth_acquire,
        !           122:        demo_auth_check,
        !           123: };
        !           124: 
        !           125: static const   struct ppp_auth_config demo_auth_config = {
        !           126:        &demo_auth_meth,
        !           127:        {
        !           128:                0
        !           129: #if 0
        !           130:                | (1 << PPP_AUTH_PAP)
        !           131: #endif
        !           132:                | (1 << PPP_AUTH_CHAP_MSV1)
        !           133:                | (1 << PPP_AUTH_CHAP_MSV2)
        !           134:                | (1 << PPP_AUTH_CHAP_MD5)
        !           135:                ,
        !           136:                (1 << PPP_AUTH_NONE)
        !           137:        }
        !           138: };
        !           139: 
        !           140: /*
        !           141:  * PPTP server callbacks. Used for 'pptp_info' application info structure.
        !           142:  */
        !           143: static ppp_pptp_server_admit_t         demo_pptp_admit;
        !           144: static ppp_pptp_server_plumb_t         demo_pptp_plumb;
        !           145: static ppp_pptp_server_destroy_t       demo_pptp_destroy;
        !           146: 
        !           147: /*
        !           148:  * L2TP server callbacks. Used for 'l2tp_info' application info structure.
        !           149:  */
        !           150: static ppp_l2tp_server_admit_t         demo_l2tp_admit;
        !           151: static ppp_l2tp_server_destroy_t       demo_l2tp_destroy;
        !           152: 
        !           153: /*
        !           154:  * Logging callback, for when the PPP library needs to log something.
        !           155:  */
        !           156: static ppp_log_vput_t                  demo_log_vput;
        !           157: 
        !           158: /*
        !           159:  * Internal variables
        !           160:  */
        !           161: static struct  in_addr bind_ip;
        !           162: static struct  in_addr ppp_ip[2];
        !           163: static struct  in_addr dns_server;
        !           164: static int     pptp_port = PPTP_PORT;
        !           165: static int     l2tp_port = L2TP_PORT;
        !           166: 
        !           167: static u_char  mppe_40;                        /* want 40 bit mppe */
        !           168: static u_char  mppe_56;                        /* want 56 bit mppe */
        !           169: static u_char  mppe_128;                       /* want 128 bit mppe */
        !           170: static u_char  mppe_stateless;                 /* mppe stateless mode */
        !           171: static const   char *user = "foo";
        !           172: static const   char *password = "bar";
        !           173: static struct  ppp_log *log;                   /* where ppp stuff logs to */
        !           174: static struct  ppp_engine *engine;             /* library provided "engine" */
        !           175: 
        !           176: static const   struct in_addr fullmask = { 0xffffffff };
        !           177: 
        !           178: /*
        !           179:  * Internal functions
        !           180:  */
        !           181: static void    usage(void);
        !           182: 
        !           183: /*
        !           184:  * Demo for PPP code. This is a PPTP and L2TP server.
        !           185:  */
        !           186: int
        !           187: main(int argc, char **argv)
        !           188: {
        !           189:        struct ppp_pptp_server_info pptp_info;
        !           190:        struct ppp_l2tp_server_info l2tp_info;
        !           191:        struct alog_config ac;
        !           192:        struct ppp_log *elog;
        !           193:        sigset_t sigs;
        !           194:        int rtn = 1;
        !           195:        int sig;
        !           196:        int ch;
        !           197: 
        !           198:        /* Parse command line arguments */
        !           199:        while ((ch = getopt(argc, argv, "a:dD:e:s:p:P:SU:t:u:")) != -1) {
        !           200:                switch (ch) {
        !           201:                case 'a':
        !           202:                        if (!inet_aton(optarg, &bind_ip)) {
        !           203:                                fprintf(stderr,
        !           204:                                    "invalid bind IP address \"%s\"\n",
        !           205:                                    optarg);
        !           206:                                usage();
        !           207:                        }
        !           208:                        break;
        !           209:                case 'd':
        !           210:                        NgSetDebug(NgSetDebug(-1) + 1);
        !           211:                        break;
        !           212:                case 'D':
        !           213:                        if (!inet_aton(optarg, &dns_server)) {
        !           214:                                fprintf(stderr,
        !           215:                                    "invalid DNS server IP address \"%s\"\n",
        !           216:                                    optarg);
        !           217:                                usage();
        !           218:                        }
        !           219:                        break;
        !           220:                case 'e':
        !           221:                        switch (atoi(optarg)) {
        !           222:                        case 40:
        !           223:                                mppe_40 = 1;
        !           224:                                break;
        !           225:                        case 56:
        !           226:                                mppe_56 = 1;
        !           227:                                break;
        !           228:                        case 128:
        !           229:                                mppe_128 = 1;
        !           230:                                break;
        !           231:                        default:
        !           232:                                fprintf(stderr,
        !           233:                                    "invalid MPPE bits \"%s\"\n", optarg);
        !           234:                                usage();
        !           235:                        }
        !           236:                        break;
        !           237:                case 'S':
        !           238:                        mppe_stateless = 1;
        !           239:                        break;
        !           240:                case 's':
        !           241:                case 'p':
        !           242:                        if (!inet_aton(optarg,
        !           243:                            &ppp_ip[ch == 's' ? PPP_SELF : PPP_PEER])) {
        !           244:                                fprintf(stderr,
        !           245:                                    "invalid %s IP address \"%s\"\n",
        !           246:                                    ch == 's' ? "self" : "peer", optarg);
        !           247:                                usage();
        !           248:                        }
        !           249:                        break;
        !           250:                case 't':
        !           251:                        pptp_port = atoi(optarg);
        !           252:                        break;
        !           253:                case 'u':
        !           254:                        l2tp_port = atoi(optarg);
        !           255:                        break;
        !           256:                case 'U':
        !           257:                        user = optarg;
        !           258:                        break;
        !           259:                case 'P':
        !           260:                        password = optarg;
        !           261:                        break;
        !           262:                default:
        !           263:                        usage();
        !           264:                }
        !           265:        }
        !           266:        argc -= optind;
        !           267:        argv += optind;
        !           268:        switch (argc) {
        !           269:        default:
        !           270:                usage();
        !           271:                break;
        !           272:        case 0:
        !           273:                break;
        !           274:        }
        !           275: 
        !           276:        /* Enable typed memory */
        !           277:        if (typed_mem_enable() == -1)
        !           278:                err(1, "typed_mem_enable");
        !           279: 
        !           280:        /* Block SIGPIPE */
        !           281:        (void)signal(SIGPIPE, SIG_IGN);
        !           282: 
        !           283:        /* Initialize logging */
        !           284:        memset(&ac, 0, sizeof(ac));
        !           285:        ac.min_severity = LOG_DEBUG;
        !           286:        if (alog_configure(0, &ac) == -1) {
        !           287:                warn("alog_configure");
        !           288:                goto done;
        !           289:        }
        !           290: 
        !           291:        /* Create PPP log */
        !           292:        if ((log = ppp_log_create(NULL, demo_log_vput, NULL)) == NULL) {
        !           293:                warn("ppp_log_create");
        !           294:                goto done;
        !           295:        }
        !           296: 
        !           297:        /* Create new PPP engine */
        !           298:        elog = ppp_log_dup(log);
        !           299:        if ((engine = ppp_engine_create(&demo_manager, NULL, elog)) == NULL) {
        !           300:                warn("ppp_engine_create");
        !           301:                ppp_log_close(&elog);
        !           302:                ppp_log_close(&log);
        !           303:                goto done;
        !           304:        }
        !           305: 
        !           306:        /* Start PPTP server */
        !           307:        memset(&pptp_info, 0, sizeof(pptp_info));
        !           308:        pptp_info.arg = engine;
        !           309:        pptp_info.vendor = VENDOR_NAME;
        !           310:        pptp_info.admit = demo_pptp_admit;
        !           311:        pptp_info.plumb = demo_pptp_plumb;
        !           312:        pptp_info.destroy = demo_pptp_destroy;
        !           313:        if (ppp_pptp_server_start(engine,
        !           314:            &pptp_info, bind_ip, pptp_port, 0) == -1) {
        !           315:                warn("ppp_pptp_server_start");
        !           316:                ppp_engine_destroy(&engine, 1);
        !           317:                goto done;
        !           318:        }
        !           319: 
        !           320:        /* Start L2TP server */
        !           321:        memset(&l2tp_info, 0, sizeof(l2tp_info));
        !           322:        l2tp_info.arg = engine;
        !           323:        l2tp_info.vendor = VENDOR_NAME;
        !           324:        l2tp_info.admit = demo_l2tp_admit;
        !           325:        l2tp_info.natmap = NULL;
        !           326:        l2tp_info.destroy = demo_l2tp_destroy;
        !           327:        if (ppp_l2tp_server_start(engine,
        !           328:            &l2tp_info, bind_ip, l2tp_port, 0) == -1) {
        !           329:                warn("ppp_l2tp_server_start");
        !           330:                ppp_engine_destroy(&engine, 1);
        !           331:                goto done;
        !           332:        }
        !           333: 
        !           334:        /* Wait for interrupt */
        !           335:        alog(LOG_INFO, "waiting for connections...");
        !           336:        sigemptyset(&sigs);
        !           337:        sigaddset(&sigs, SIGINT);
        !           338:        sigaddset(&sigs, SIGTERM);
        !           339:        if (sigprocmask(SIG_BLOCK, &sigs, NULL) == -1) {
        !           340:                warn("sigprocmask");
        !           341:                goto done;
        !           342:        }
        !           343:        if (sigwait(&sigs, &sig) == -1) {
        !           344:                warn("sigwait");
        !           345:                goto done;
        !           346:        }
        !           347: 
        !           348:        /* Shut down server */
        !           349:        printf("\nRec'd signal %s, shutting down...\n", sys_signame[sig]);
        !           350: 
        !           351: done:
        !           352:        ppp_engine_destroy(&engine, 1);
        !           353:        ppp_log_close(&log);
        !           354:        typed_mem_dump(stdout);
        !           355:        return (rtn);
        !           356: }
        !           357: 
        !           358: /*
        !           359:  * Exit after printing usage string
        !           360:  */
        !           361: static void
        !           362: usage(void)
        !           363: {
        !           364:        (void)fprintf(stderr, "Usage: ppp_demo [options...]\n");
        !           365:        (void)fprintf(stderr, "\t-d\t\t\tIncrease netgraph debugging level\n");
        !           366:        (void)fprintf(stderr, "\t-a ipaddr\t\tIP address to listen on\n");
        !           367:        (void)fprintf(stderr, "\t-D ipaddr\t\tPeer's DNS server IP address\n");
        !           368:        (void)fprintf(stderr, "\t-e < 40 | 56 | 128 >\tEnable MPPE\n");
        !           369:        (void)fprintf(stderr, "\t-S\t\t\tEnable MPPE stateless mode\n");
        !           370:        (void)fprintf(stderr, "\t-s ipaddr\t\tSpecify self's inside IP\n");
        !           371:        (void)fprintf(stderr, "\t-p ipaddr\t\tSpecify peer's inside IP\n");
        !           372:        (void)fprintf(stderr, "\t-U username\t\tSpecify username\n");
        !           373:        (void)fprintf(stderr, "\t-P password\t\tSpecify password\n");
        !           374:        (void)fprintf(stderr, "\t-t port\t\t\tSpecify PPTP listen port\n");
        !           375:        (void)fprintf(stderr, "\t-u port\t\t\tSpecify L2TP listen port\n");
        !           376:        exit(1);
        !           377: }
        !           378: 
        !           379: /***********************************************************************
        !           380:                        MANAGER METHODS
        !           381: ***********************************************************************/
        !           382: 
        !           383: static int     ip_acquired;
        !           384: 
        !           385: static void *
        !           386: demo_manager_bundle_config(struct ppp_manager *manager,
        !           387:        struct ppp_link *link, struct ppp_bundle_config *conf)
        !           388: {
        !           389:        printf("[MANAGER] new link %p, peer=\"%s\"\n",
        !           390:            link, ppp_link_get_authname(link, PPP_PEER));
        !           391:        if (ip_acquired) {
        !           392:                errno = EALREADY;
        !           393:                return (NULL);
        !           394:        }
        !           395:        memset(conf, 0, sizeof(*conf));
        !           396:        conf->ip[PPP_SELF] = ppp_ip[PPP_SELF];
        !           397:        conf->ip[PPP_PEER] = ppp_ip[PPP_PEER];
        !           398:        ip_acquired = 1;
        !           399:        conf->dns_servers[0] = dns_server;
        !           400:        conf->vjc = 1;
        !           401:        conf->mppe_40 = mppe_40;
        !           402:        conf->mppe_56 = mppe_56;
        !           403:        conf->mppe_128 = mppe_128;
        !           404:        return ((void *)1);
        !           405: }
        !           406: 
        !           407: static void *
        !           408: demo_manager_bundle_plumb(struct ppp_manager *manager,
        !           409:        struct ppp_bundle *bundle, const char *path, const char *hook,
        !           410:        struct in_addr *ips, struct in_addr *dns, struct in_addr *nbns,
        !           411:        u_int mtu)
        !           412: {
        !           413:        union {
        !           414:            u_char buf[sizeof(struct ng_mesg)
        !           415:              + sizeof(struct ng_iface_ifname)];
        !           416:            struct ng_mesg reply;
        !           417:        } repbuf;
        !           418:        struct ng_mesg *const reply = &repbuf.reply;
        !           419:        struct ng_iface_ifname *const ifname
        !           420:            = (struct ng_iface_ifname *)reply->data;
        !           421:        char ifpath[64];
        !           422:        char ipbuf[16];
        !           423:        int csock = -1;
        !           424:        char *rtn;
        !           425:        int esave;
        !           426: 
        !           427:        /* Debug */
        !           428:        strlcpy(ipbuf, inet_ntoa(ips[PPP_SELF]), sizeof(ipbuf));
        !           429:        printf("[MANAGER] plumbing top side of bundle %p %s -> %s MTU=%u\n",
        !           430:            bundle, ipbuf, inet_ntoa(ips[PPP_PEER]), mtu);
        !           431: 
        !           432:        /* Get temporary socket node */
        !           433:        if (NgMkSockNode(NULL, &csock, NULL) == -1) {
        !           434:                warn("NgMkSockNode");
        !           435:                goto fail;
        !           436:        }
        !           437:        snprintf(ifpath, sizeof(ifpath), "%s%s", path, hook);
        !           438: 
        !           439:        /* Attach iface node */
        !           440:        if (NgSendAsciiMsg(csock, path, "mkpeer { type=\"%s\""
        !           441:            " ourhook=\"%s\" peerhook=\"%s\" }", NG_IFACE_NODE_TYPE,
        !           442:            hook, NG_IFACE_HOOK_INET) == -1) {
        !           443:                warn("mkpeer");
        !           444:                goto fail;
        !           445:        }
        !           446: 
        !           447:        /* Get node name */
        !           448:        if (NgSendMsg(csock, ifpath, NGM_IFACE_COOKIE, NGM_IFACE_GET_IFNAME,
        !           449:            NULL, 0) == -1) {
        !           450:                warn("NgSendMsg");
        !           451:                goto fail;
        !           452:        }
        !           453:        if (NgRecvMsg(csock, reply, sizeof(repbuf), NULL) == -1) {
        !           454:                warn("NgRecvMsg");
        !           455:                goto fail;
        !           456:        }
        !           457: 
        !           458:        /* Configure iface node */
        !           459:        if (if_add_ip_addr(ifname->ngif_name, ips[PPP_SELF],
        !           460:            fullmask, ips[PPP_PEER]) == -1) {
        !           461:                warn("if_add_ip(%s)", inet_ntoa(ips[PPP_SELF]));
        !           462:                goto fail;
        !           463:        }
        !           464:        if (if_set_mtu(ifname->ngif_name, mtu) == -1) {
        !           465:                warn("if_setmtu(%d)", mtu);
        !           466:                goto fail;
        !           467:        }
        !           468: 
        !           469:        /* Get return value */
        !           470:        ASPRINTF("ppp_demo.ifname", &rtn, "%s:", ifname->ngif_name);
        !           471:        if (rtn == NULL) {
        !           472:                warn("asprintf");
        !           473:                goto fail;
        !           474:        }
        !           475: 
        !           476:        /* Done */
        !           477:        (void)close(csock);
        !           478:        printf("[MANAGER] plumbing top side of bundle %p OK\n", bundle);
        !           479:        return (rtn);
        !           480: 
        !           481: fail:
        !           482:        /* Clean up after failure */
        !           483:        esave = errno;
        !           484:        printf("[MANAGER] plumbing top side of bundle %p failed: %s\n",
        !           485:            bundle, strerror(esave));
        !           486:        if (csock != -1) {
        !           487:                (void)NgSendMsg(csock, ifpath, NGM_GENERIC_COOKIE,
        !           488:                    NGM_SHUTDOWN, NULL, 0);
        !           489:                (void)close(csock);
        !           490:        }
        !           491:        errno = esave;
        !           492:        return (NULL);
        !           493: }
        !           494: 
        !           495: static void
        !           496: demo_manager_release_ip(struct ppp_manager *manager,
        !           497:        struct ppp_bundle *bundle, struct in_addr ip)
        !           498: {
        !           499:        printf("[MANAGER] releasing IP address for bundle %p\n", bundle);
        !           500:        ip_acquired = 0;
        !           501: }
        !           502: 
        !           503: static void
        !           504: demo_manager_bundle_unplumb(struct ppp_manager *manager, void *arg,
        !           505:        struct ppp_bundle *bundle)
        !           506: {
        !           507:        char *const ifpath = arg;
        !           508:        int csock;
        !           509: 
        !           510:        printf("[MANAGER] unplumb bundle %p (%s)\n", bundle, ifpath);
        !           511: 
        !           512:        /* Get temporary socket node */
        !           513:        if (NgMkSockNode(NULL, &csock, NULL) == -1) {
        !           514:                warn("NgMkSockNode");
        !           515:                return;
        !           516:        }
        !           517: 
        !           518:        /* Kill iface node */
        !           519:        if (NgSendMsg(csock, ifpath,
        !           520:            NGM_GENERIC_COOKIE, NGM_SHUTDOWN, NULL, 0) == -1)
        !           521:                warn("shutdown(%s)", ifpath);
        !           522: 
        !           523:        /* Free node name */
        !           524:        FREE("ppp_demo.ifname", ifpath);
        !           525:        (void)close(csock);
        !           526: }
        !           527: 
        !           528: /***********************************************************************
        !           529:                        PPTP SERVER CALLBACKS
        !           530: ***********************************************************************/
        !           531: 
        !           532: static struct          in_addr peer_ip;
        !           533: static u_int16_t       peer_port;
        !           534: 
        !           535: static void *
        !           536: demo_pptp_admit(void *arg, struct ppp_pptp_peer *peer,
        !           537:        struct in_addr ip, u_int16_t port,
        !           538:        struct ppp_auth_config *auth, char *name, size_t nsize)
        !           539: {
        !           540:        if (peer_ip.s_addr != 0)
        !           541:                return (NULL);
        !           542:        peer_ip = ip;
        !           543:        peer_port = port;
        !           544:        *auth = demo_auth_config;
        !           545:        printf("[DEMO] PPTP connection from %s:%u\n", inet_ntoa(ip), port);
        !           546:        snprintf(name, nsize, "[%s:%u]", inet_ntoa(ip), port);
        !           547:        return ((void *)1);
        !           548: }
        !           549: 
        !           550: static int
        !           551: demo_pptp_plumb(void *arg, void *carg, const char *path,
        !           552:        const char *hook, const struct in_addr *ips)
        !           553: {
        !           554:        struct sockaddr_in laddr;
        !           555:        struct sockaddr_in paddr;
        !           556:        char kpath[64];
        !           557:        int csock = -1;
        !           558:        int esave;
        !           559: 
        !           560:        strlcpy(kpath, inet_ntoa(ips[PPP_SELF]), sizeof(kpath));
        !           561:        printf("[DEMO] plumbing GRE %s -> %s\n",
        !           562:            kpath, inet_ntoa(ips[PPP_PEER]));
        !           563: 
        !           564:        /* Get temporary socket node */
        !           565:        if (NgMkSockNode(NULL, &csock, NULL) == -1) {
        !           566:                warn("NgMkSockNode");
        !           567:                goto fail;
        !           568:        }
        !           569:        snprintf(kpath, sizeof(kpath), "%s%s", path, hook);
        !           570: 
        !           571:        /* Attach ksocket node to pptpgre node */
        !           572:        if (NgSendAsciiMsg(csock, path, "mkpeer { type=\"%s\" ourhook=\"%s\""
        !           573:            " peerhook=\"%s\" }", NG_KSOCKET_NODE_TYPE, hook,
        !           574:            "inet/raw/gre") == -1) {
        !           575:                warn("mkpeer");
        !           576:                goto fail;
        !           577:        }
        !           578: 
        !           579:        /* Bind(2) ksocket node */
        !           580:        memset(&laddr, 0, sizeof(laddr));
        !           581:        laddr.sin_len = sizeof(laddr);
        !           582:        laddr.sin_family = AF_INET;
        !           583:        laddr.sin_addr = bind_ip;
        !           584:        if (NgSendMsg(csock, kpath, NGM_KSOCKET_COOKIE,
        !           585:            NGM_KSOCKET_BIND, &laddr, sizeof(laddr)) == -1) {
        !           586:                warn("bind");
        !           587:                goto fail;
        !           588:        }
        !           589: 
        !           590:        /* Connect(2) ksocket node to peer */
        !           591:        memset(&paddr, 0, sizeof(paddr));
        !           592:        paddr.sin_len = sizeof(paddr);
        !           593:        paddr.sin_family = AF_INET;
        !           594:        paddr.sin_addr = peer_ip;
        !           595:        if (NgSendMsg(csock, kpath, NGM_KSOCKET_COOKIE,
        !           596:            NGM_KSOCKET_CONNECT, &paddr, sizeof(paddr)) == -1) {
        !           597:                warn("connect");
        !           598:                goto fail;
        !           599:        }
        !           600: 
        !           601:        /* Done */
        !           602:        (void)close(csock);
        !           603:        return (0);
        !           604: 
        !           605: fail:
        !           606:        /* Clean up after failure */
        !           607:        esave = errno;
        !           608:        if (csock != -1) {
        !           609:                (void)NgSendMsg(csock, kpath, NGM_GENERIC_COOKIE,
        !           610:                    NGM_SHUTDOWN, NULL, 0);
        !           611:                (void)close(csock);
        !           612:        }
        !           613:        errno = esave;
        !           614:        return (-1);
        !           615: }
        !           616: 
        !           617: static void
        !           618: demo_pptp_destroy(void *arg, void *carg, const char *path)
        !           619: {
        !           620:        printf("[DEMO] closing GRE\n");
        !           621:        peer_ip.s_addr = 0;
        !           622:        peer_port = 0;
        !           623: }
        !           624: 
        !           625: /***********************************************************************
        !           626:                        L2TP SERVER CALLBACKS
        !           627: ***********************************************************************/
        !           628: 
        !           629: static void *
        !           630: demo_l2tp_admit(void *arg, struct ppp_l2tp_peer *peer, struct in_addr ip,
        !           631:        u_int16_t port, struct ppp_auth_config *auth, char *name, size_t nsize)
        !           632: {
        !           633:        if (peer_ip.s_addr != 0)
        !           634:                return (NULL);
        !           635:        peer_ip = ip;
        !           636:        peer_port = port;
        !           637:        *auth = demo_auth_config;
        !           638:        printf("[DEMO] L2TP connection from %s:%u\n", inet_ntoa(ip), port);
        !           639:        snprintf(name, nsize, "[%s:%u]", inet_ntoa(ip), port);
        !           640:        return ((void *)1);
        !           641: }
        !           642: 
        !           643: static void
        !           644: demo_l2tp_destroy(void *arg, void *carg)
        !           645: {
        !           646:        printf("[DEMO] closing L2TP\n");
        !           647:        peer_ip.s_addr = 0;
        !           648:        peer_port = 0;
        !           649: }
        !           650: 
        !           651: /***********************************************************************
        !           652:                    AUTHORIZATION CALLBACKS
        !           653: ***********************************************************************/
        !           654: 
        !           655: static int
        !           656: demo_auth_acquire(struct ppp_link *link,
        !           657:        struct ppp_auth_cred *creds, struct ppp_auth_resp *resp)
        !           658: {
        !           659:        printf("[DEMO] auth acquire, sleeping 1 second...\n");
        !           660:        sleep(1);
        !           661:        switch (creds->type) {
        !           662:        default:
        !           663:                errno = EPROTONOSUPPORT;
        !           664:                return (-1);
        !           665:        }
        !           666: }
        !           667: 
        !           668: static int
        !           669: demo_auth_check(struct ppp_link *link,
        !           670:        const struct ppp_auth_cred *creds, struct ppp_auth_resp *resp)
        !           671: {
        !           672:        int i;
        !           673: 
        !           674:        printf("[DEMO] auth check, sleeping 1 second...\n");
        !           675:        sleep(1);
        !           676:        switch (creds->type) {
        !           677:        case PPP_AUTH_PAP:
        !           678:            {
        !           679:                const struct ppp_auth_cred_pap *const pap = &creds->u.pap;
        !           680: 
        !           681:                printf("[DEMO] PAP auth check user=\"%s\"\n", pap->name);
        !           682:                if (strcmp(pap->name, user) != 0) {
        !           683:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           684:                            "wrong username");
        !           685:                        return (-1);
        !           686:                }
        !           687:                if (strcmp(pap->password, password) != 0) {
        !           688:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           689:                            "wrong password");
        !           690:                        return (-1);
        !           691:                }
        !           692:                return (0);
        !           693:            }
        !           694:        case PPP_AUTH_CHAP_MSV1:
        !           695:            {
        !           696:                const struct ppp_auth_cred_chap *const chap = &creds->u.chap;
        !           697:                const struct ppp_auth_cred_chap_msv1 *const rsp = &chap->u.msv1;
        !           698:                u_char buf[PPP_MSOFT_NT_HASH_LEN];
        !           699: 
        !           700:                printf("[DEMO] MSv1 auth check user=\"%s\"\n", chap->name);
        !           701: 
        !           702:                /* Check response */
        !           703:                if (strcmp(chap->name, user) != 0) {
        !           704:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           705:                            "wrong username");
        !           706:                        return (-1);
        !           707:                }
        !           708:                if (!rsp->use_nt) {             /* disallow lan-man hash */
        !           709:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           710:                            "LAN-MAN hash unacceptable");
        !           711:                        return (-1);
        !           712:                }
        !           713:                ppp_msoft_nt_challenge_response(chap->chal_data, password, buf);
        !           714:                if (memcmp(rsp->nt_hash, buf, sizeof(buf)) != 0) {
        !           715:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           716:                            "MSCHAPv1 hash is invalid");
        !           717:                        return (-1);
        !           718:                }
        !           719: 
        !           720:                /* Derive MPPE keys */
        !           721:                ppp_msoft_init_key_v1(0, password,
        !           722:                    chap->chal_data, resp->mppe.msv1.key_64);
        !           723:                ppp_msoft_init_key_v1(1, password,
        !           724:                    chap->chal_data, resp->mppe.msv1.key_128);
        !           725:                printf("[DEMO] MSv1 MPPE 64 BIT KEY:\n");
        !           726:                ppp_log_dump(log, LOG_DEBUG,
        !           727:                    resp->mppe.msv1.key_64, sizeof(resp->mppe.msv1.key_64));
        !           728:                printf("[DEMO] MSv1 MPPE 128 BIT KEY:\n");
        !           729:                ppp_log_dump(log, LOG_DEBUG,
        !           730:                    resp->mppe.msv1.key_128, sizeof(resp->mppe.msv1.key_128));
        !           731: 
        !           732:                /* Done */
        !           733:                return (0);
        !           734:            }
        !           735:        case PPP_AUTH_CHAP_MSV2:
        !           736:            {
        !           737:                const struct ppp_auth_cred_chap *const chap = &creds->u.chap;
        !           738:                const struct ppp_auth_cred_chap_msv2 *const rsp = &chap->u.msv2;
        !           739:                u_char buf[PPP_MSOFT_NT_HASH_LEN];
        !           740: 
        !           741:                printf("[DEMO] MSv2 auth check user=\"%s\"\n", chap->name);
        !           742: 
        !           743:                /* Check response */
        !           744:                if (strcmp(chap->name, user) != 0) {
        !           745:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           746:                            "wrong username");
        !           747:                        return (-1);
        !           748:                }
        !           749:                ppp_msoft_generate_nt_response(chap->chal_data,
        !           750:                    rsp->peer_chal, chap->name, password, buf);
        !           751:                if (memcmp(rsp->nt_response, buf, sizeof(buf)) != 0) {
        !           752:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           753:                            "MSCHAPv2 hash is invalid");
        !           754:                        return (-1);
        !           755:                }
        !           756: 
        !           757:                /* Generate expected authenticator response for reply */
        !           758:                ppp_msoft_generate_authenticator_response(password,
        !           759:                    rsp->nt_response, rsp->peer_chal, chap->chal_data,
        !           760:                    chap->name, resp->authresp);
        !           761: 
        !           762:                /* Derive MPPE keys */
        !           763:                for (i = 0; i < 2; i++) {
        !           764:                        ppp_msoft_init_key_v2(i, password,
        !           765:                            rsp->nt_response, resp->mppe.msv2.keys[i]);
        !           766:                        printf("[DEMO] MSv2 MPPE SERVER %s KEY:\n",
        !           767:                            i == 0 ? "XMIT" : "RECV");
        !           768:                        ppp_log_dump(log, LOG_DEBUG, resp->mppe.msv2.keys[i],
        !           769:                            sizeof(resp->mppe.msv2.keys[i]));
        !           770:                }
        !           771: 
        !           772:                /* Done */
        !           773:                return (0);
        !           774:            }
        !           775:        case PPP_AUTH_CHAP_MD5:
        !           776:            {
        !           777:                const struct ppp_auth_cred_chap *const chap = &creds->u.chap;
        !           778:                struct ppp_auth_cred_chap temp;
        !           779: 
        !           780:                printf("[DEMO] CHAP-MD5 auth check user=\"%s\"\n", chap->name);
        !           781:                strlcpy(temp.name, chap->name, sizeof(temp.name));
        !           782:                temp.chal_len = chap->chal_len;
        !           783:                memcpy(temp.chal_data, chap->chal_data, chap->chal_len);
        !           784:                temp.u.md5.id = chap->u.md5.id;
        !           785:                (*ppp_auth_chap_md5.hash)(&temp, password, strlen(password));
        !           786:                if (memcmp(temp.u.md5.hash,
        !           787:                    chap->u.md5.hash, sizeof(temp.u.md5.hash)) != 0) {
        !           788:                        snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           789:                            "invalid MD5 hash");
        !           790:                        return (-1);
        !           791:                }
        !           792:                return (0);
        !           793:            }
        !           794:        default:
        !           795:                snprintf(resp->errmsg, sizeof(resp->errmsg),
        !           796:                    "unsupported auth check");
        !           797:                errno = EPROTONOSUPPORT;
        !           798:                return (-1);
        !           799:        }
        !           800: }
        !           801: 
        !           802: /***********************************************************************
        !           803:                        LOG METHODS
        !           804: ***********************************************************************/
        !           805: 
        !           806: static void
        !           807: demo_log_vput(void *arg, int sev, const char *fmt, va_list args)
        !           808: {
        !           809:        valog(sev, fmt, args);
        !           810: }
        !           811: 

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