Annotation of embedaddon/libpdel/ppp/test/main.c, revision 1.1.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>