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>