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>