upap.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:13k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* upap.c - User/Password Authentication Protocol */
  2. /* Copyright 1994-1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1989 Carnegie Mellon University.
  6.  * All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms are permitted
  9.  * provided that the above copyright notice and this paragraph are
  10.  * duplicated in all such forms and that any documentation,
  11.  * advertising materials, and other materials related to such
  12.  * distribution and use acknowledge that the software was developed
  13.  * by Carnegie Mellon University.  The name of the
  14.  * University may not be used to endorse or promote products derived
  15.  * from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20. /*
  21. modification history
  22. --------------------
  23. 01c,16jun95,dzb  header file consolidation.
  24.                  changed [UN]TIMEOUT macros to PPP_[UN]TIMEOUT.
  25. 01b,16dec94,dab  removed misleading log message in upap_rauthack().
  26. 01a,21dec94,dab  VxWorks port - first WRS version.
  27.    +dzb  added: path for ppp header files, WRS copyright.
  28. */
  29. #include "vxWorks.h"
  30. #include "string.h"
  31. #include "stdio.h"
  32. #include "sys/types.h"
  33. #include "sys/times.h"
  34. #include "pppLib.h"
  35. static void upap_timeout __ARGS((caddr_t));
  36. static void upap_rauthreq __ARGS((upap_state *, u_char *, int, int));
  37. static void upap_rauthack __ARGS((upap_state *, u_char *, int, int));
  38. static void upap_rauthnak __ARGS((upap_state *, u_char *, int, int));
  39. static void upap_sauthreq __ARGS((upap_state *));
  40. static void upap_sresp __ARGS((upap_state *, int, int, char *, int));
  41. /*
  42.  * upap_init - Initialize a UPAP unit.
  43.  */
  44. void
  45. upap_init(unit)
  46.     int unit;
  47. {
  48.     upap_state *u = &ppp_if[unit]->upap;
  49.     u->us_unit = unit;
  50.     u->us_user = NULL;
  51.     u->us_userlen = 0;
  52.     u->us_passwd = NULL;
  53.     u->us_passwdlen = 0;
  54.     u->us_clientstate = UPAPCS_INITIAL;
  55.     u->us_serverstate = UPAPSS_INITIAL;
  56.     u->us_id = 0;
  57.     u->us_timeouttime = UPAP_DEFTIMEOUT;
  58.     u->us_maxtransmits = 10;
  59. }
  60. /*
  61.  * upap_authwithpeer - Authenticate us with our peer (start client).
  62.  *
  63.  * Set new state and send authenticate's.
  64.  */
  65. void
  66. upap_authwithpeer(unit, user, password)
  67.     int unit;
  68.     char *user, *password;
  69. {
  70.     upap_state *u = &ppp_if[unit]->upap;
  71.     /* Save the username and password we're given */
  72.     u->us_user = user;
  73.     u->us_userlen = strlen(user);
  74.     u->us_passwd = password;
  75.     u->us_passwdlen = strlen(password);
  76.     u->us_transmits = 0;
  77.     /* Lower layer up yet? */
  78.     if (u->us_clientstate == UPAPCS_INITIAL ||
  79. u->us_clientstate == UPAPCS_PENDING) {
  80. u->us_clientstate = UPAPCS_PENDING;
  81. return;
  82.     }
  83.     upap_sauthreq(u); /* Start protocol */
  84. }
  85. /*
  86.  * upap_authpeer - Authenticate our peer (start server).
  87.  *
  88.  * Set new state.
  89.  */
  90. void
  91. upap_authpeer(unit)
  92.     int unit;
  93. {
  94.     upap_state *u = &ppp_if[unit]->upap;
  95.     /* Lower layer up yet? */
  96.     if (u->us_serverstate == UPAPSS_INITIAL ||
  97. u->us_serverstate == UPAPSS_PENDING) {
  98. u->us_serverstate = UPAPSS_PENDING;
  99. return;
  100.     }
  101.     u->us_serverstate = UPAPSS_LISTEN;
  102. }
  103. /*
  104.  * upap_timeout - Timeout expired.
  105.  */
  106. static void
  107. upap_timeout(arg)
  108.     caddr_t arg;
  109. {
  110.     upap_state *u = (upap_state *) arg;
  111.     if (u->us_clientstate != UPAPCS_AUTHREQ)
  112. return;
  113.     if (u->us_transmits >= u->us_maxtransmits) {
  114. /* give up in disgust */
  115. syslog(LOG_ERR, "No response to PAP authenticate-requests");
  116. u->us_clientstate = UPAPCS_BADAUTH;
  117. auth_withpeer_fail(u->us_unit, UPAP);
  118. return;
  119.     }
  120.     upap_sauthreq(u); /* Send Authenticate-Request */
  121. }
  122. /*
  123.  * upap_lowerup - The lower layer is up.
  124.  *
  125.  * Start authenticating if pending.
  126.  */
  127. void
  128. upap_lowerup(unit)
  129.     int unit;
  130. {
  131.     upap_state *u = &ppp_if[unit]->upap;
  132.     if (u->us_clientstate == UPAPCS_INITIAL)
  133. u->us_clientstate = UPAPCS_CLOSED;
  134.     else if (u->us_clientstate == UPAPCS_PENDING) {
  135. upap_sauthreq(u); /* send an auth-request */
  136.     }
  137.     if (u->us_serverstate == UPAPSS_INITIAL)
  138. u->us_serverstate = UPAPSS_CLOSED;
  139.     else if (u->us_serverstate == UPAPSS_PENDING)
  140. u->us_serverstate = UPAPSS_LISTEN;
  141. }
  142. /*
  143.  * upap_lowerdown - The lower layer is down.
  144.  *
  145.  * Cancel all timeouts.
  146.  */
  147. void
  148. upap_lowerdown(unit)
  149.     int unit;
  150. {
  151.     upap_state *u = &ppp_if[unit]->upap;
  152.     if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
  153. PPP_UNTIMEOUT(upap_timeout, (caddr_t) u); /* Cancel timeout */
  154.     u->us_clientstate = UPAPCS_INITIAL;
  155.     u->us_serverstate = UPAPSS_INITIAL;
  156. }
  157. /*
  158.  * upap_protrej - Peer doesn't speak this protocol.
  159.  *
  160.  * This shouldn't happen.  In any case, pretend lower layer went down.
  161.  */
  162. void
  163. upap_protrej(unit)
  164.     int unit;
  165. {
  166.     upap_state *u = &ppp_if[unit]->upap;
  167.     if (u->us_clientstate == UPAPCS_AUTHREQ) {
  168. syslog(LOG_ERR, "PAP authentication failed due to protocol-reject");
  169. auth_withpeer_fail(unit, UPAP);
  170.     }
  171.     if (u->us_serverstate == UPAPSS_LISTEN) {
  172. syslog(LOG_ERR, "PAP authentication of peer failed (protocol-reject)");
  173. auth_peer_fail(unit, UPAP);
  174.     }
  175.     upap_lowerdown(unit);
  176. }
  177. /*
  178.  * upap_input - Input UPAP packet.
  179.  */
  180. void
  181. upap_input(unit, inpacket, l)
  182.     int unit;
  183.     u_char *inpacket;
  184.     int l;
  185. {
  186.     upap_state *u = &ppp_if[unit]->upap;
  187.     u_char *inp;
  188.     u_char code, id;
  189.     int len;
  190.     /*
  191.      * Parse header (code, id and length).
  192.      * If packet too short, drop it.
  193.      */
  194.     inp = inpacket;
  195.     if (l < UPAP_HEADERLEN) {
  196. UPAPDEBUG((LOG_INFO, "upap_input: rcvd short header."));
  197. return;
  198.     }
  199.     GETCHAR(code, inp);
  200.     GETCHAR(id, inp);
  201.     GETSHORT(len, inp);
  202.     if (len < UPAP_HEADERLEN) {
  203. UPAPDEBUG((LOG_INFO, "upap_input: rcvd illegal length."));
  204. return;
  205.     }
  206.     if (len > l) {
  207. UPAPDEBUG((LOG_INFO, "upap_input: rcvd short packet."));
  208. return;
  209.     }
  210.     len -= UPAP_HEADERLEN;
  211.     /*
  212.      * Action depends on code.
  213.      */
  214.     switch (code) {
  215.     case UPAP_AUTHREQ:
  216. upap_rauthreq(u, inp, id, len);
  217. break;
  218.     case UPAP_AUTHACK:
  219. upap_rauthack(u, inp, id, len);
  220. break;
  221.     case UPAP_AUTHNAK:
  222. upap_rauthnak(u, inp, id, len);
  223. break;
  224.     default: /* XXX Need code reject */
  225. break;
  226.     }
  227. }
  228. /*
  229.  * upap_rauth - Receive Authenticate.
  230.  */
  231. static void
  232. upap_rauthreq(u, inp, id, len)
  233.     upap_state *u;
  234.     u_char *inp;
  235.     int id;
  236.     int len;
  237. {
  238.     u_char ruserlen, rpasswdlen;
  239.     char *ruser, *rpasswd;
  240.     int retcode;
  241.     char *msg;
  242.     int msglen;
  243.     UPAPDEBUG((LOG_INFO, "upap_rauth: Rcvd id %d.", id));
  244.     if (u->us_serverstate < UPAPSS_LISTEN)
  245. return;
  246.     /*
  247.      * If we receive a duplicate authenticate-request, we are
  248.      * supposed to return the same status as for the first request.
  249.      */
  250.     if (u->us_serverstate == UPAPSS_OPEN) {
  251. upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
  252. return;
  253.     }
  254.     if (u->us_serverstate == UPAPSS_BADAUTH) {
  255. upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
  256. return;
  257.     }
  258.     /*
  259.      * Parse user/passwd.
  260.      */
  261.     if (len < sizeof (u_char)) {
  262. UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
  263. return;
  264.     }
  265.     GETCHAR(ruserlen, inp);
  266.     len -= sizeof (u_char) + ruserlen + sizeof (u_char);
  267.     if (len < 0) {
  268. UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
  269. return;
  270.     }
  271.     ruser = (char *) inp;
  272.     INCPTR(ruserlen, inp);
  273.     GETCHAR(rpasswdlen, inp);
  274.     if (len < rpasswdlen) {
  275. UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
  276. return;
  277.     }
  278.     rpasswd = (char *) inp;
  279.     /*
  280.      * Check the username and password given.
  281.      */
  282.     retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
  283.    rpasswdlen, &msg, &msglen);
  284.     upap_sresp(u, retcode, id, msg, msglen);
  285.     if (retcode == UPAP_AUTHACK) {
  286. u->us_serverstate = UPAPSS_OPEN;
  287. auth_peer_success(u->us_unit, UPAP);
  288.     } else {
  289. u->us_serverstate = UPAPSS_BADAUTH;
  290. auth_peer_fail(u->us_unit, UPAP);
  291.     }
  292. }
  293. /*
  294.  * upap_rauthack - Receive Authenticate-Ack.
  295.  */
  296. static void
  297. upap_rauthack(u, inp, id, len)
  298.     upap_state *u;
  299.     u_char *inp;
  300.     int id;
  301.     int len;
  302. {
  303.     u_char msglen;
  304.     char *msg;
  305.     UPAPDEBUG((LOG_INFO, "upap_rauthack: Rcvd id %d.", id));
  306.     if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
  307. return;
  308.     /*
  309.      * Parse message.
  310.      */
  311.     if (len < sizeof (u_char)) {
  312. UPAPDEBUG((LOG_INFO, "upap_rauthack: rcvd short packet."));
  313. return;
  314.     }
  315.     GETCHAR(msglen, inp);
  316.     len -= sizeof (u_char);
  317.     if (len < msglen) {
  318. UPAPDEBUG((LOG_INFO, "upap_rauthack: rcvd short packet."));
  319. return;
  320.     }
  321.     msg = (char *) inp;
  322.     PRINTMSG(msg, msglen);
  323.     u->us_clientstate = UPAPCS_OPEN;
  324.     auth_withpeer_success(u->us_unit, UPAP);
  325. }
  326. /*
  327.  * upap_rauthnak - Receive Authenticate-Nakk.
  328.  */
  329. static void
  330. upap_rauthnak(u, inp, id, len)
  331.     upap_state *u;
  332.     u_char *inp;
  333.     int id;
  334.     int len;
  335. {
  336.     u_char msglen;
  337.     char *msg;
  338.     UPAPDEBUG((LOG_INFO, "upap_rauthnak: Rcvd id %d.", id));
  339.     if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
  340. return;
  341.     /*
  342.      * Parse message.
  343.      */
  344.     if (len < sizeof (u_char)) {
  345. UPAPDEBUG((LOG_INFO, "upap_rauthnak: rcvd short packet."));
  346. return;
  347.     }
  348.     GETCHAR(msglen, inp);
  349.     len -= sizeof (u_char);
  350.     if (len < msglen) {
  351. UPAPDEBUG((LOG_INFO, "upap_rauthnak: rcvd short packet."));
  352. return;
  353.     }
  354.     msg = (char *) inp;
  355.     PRINTMSG(msg, msglen);
  356.     u->us_clientstate = UPAPCS_BADAUTH;
  357.     syslog(LOG_ERR, "PAP authentication failed");
  358.     auth_withpeer_fail(u->us_unit, UPAP);
  359. }
  360. /*
  361.  * upap_sauthreq - Send an Authenticate-Request.
  362.  */
  363. static void
  364. upap_sauthreq(u)
  365.     upap_state *u;
  366. {
  367.     u_char *outp;
  368.     int outlen;
  369.     outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
  370. u->us_userlen + u->us_passwdlen;
  371.     outp = ppp_if[u->us_unit]->outpacket_buf;
  372.     
  373.     MAKEHEADER(outp, UPAP);
  374.     PUTCHAR(UPAP_AUTHREQ, outp);
  375.     PUTCHAR(++u->us_id, outp);
  376.     PUTSHORT(outlen, outp);
  377.     PUTCHAR(u->us_userlen, outp);
  378.     BCOPY(u->us_user, (char *)outp, u->us_userlen);
  379.     INCPTR(u->us_userlen, outp);
  380.     PUTCHAR(u->us_passwdlen, outp);
  381.     BCOPY(u->us_passwd, (char *)outp, u->us_passwdlen);
  382.     output(u->us_unit, ppp_if[u->us_unit]->outpacket_buf, outlen + DLLHEADERLEN);
  383.     UPAPDEBUG((LOG_INFO, "upap_sauth: Sent id %d.", u->us_id));
  384.     PPP_TIMEOUT(upap_timeout, (caddr_t) u, u->us_timeouttime);
  385.     ++u->us_transmits;
  386.     u->us_clientstate = UPAPCS_AUTHREQ;
  387. }
  388. /*
  389.  * upap_sresp - Send a response (ack or nak).
  390.  */
  391. static void
  392. upap_sresp(u, code, id, msg, msglen)
  393.     upap_state *u;
  394.     u_char code, id;
  395.     char *msg;
  396.     int msglen;
  397. {
  398.     u_char *outp;
  399.     int outlen;
  400.     outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
  401.     outp = ppp_if[u->us_unit]->outpacket_buf;
  402.     MAKEHEADER(outp, UPAP);
  403.     PUTCHAR(code, outp);
  404.     PUTCHAR(id, outp);
  405.     PUTSHORT(outlen, outp);
  406.     PUTCHAR(msglen, outp);
  407.     BCOPY(msg, (char *)outp, msglen);
  408.     output(u->us_unit, ppp_if[u->us_unit]->outpacket_buf, outlen + DLLHEADERLEN);
  409.     UPAPDEBUG((LOG_INFO, "upap_sresp: Sent code %d, id %d.", code, id));
  410. }
  411. /*
  412.  * upap_printpkt - print the contents of a PAP packet.
  413.  */
  414. char *upap_codenames[] = {
  415.     "AuthReq", "AuthAck", "AuthNak"
  416. };
  417. int
  418. upap_printpkt(p, plen, printer, arg)
  419.     u_char *p;
  420.     int plen;
  421.     void (*printer) __ARGS((void *, char *, ...));
  422.     void *arg;
  423. {
  424.     int code, id, len;
  425.     int mlen, ulen, wlen;
  426.     char *user, *pwd, *msg;
  427.     u_char *pstart;
  428.     if (plen < UPAP_HEADERLEN)
  429.         return 0;
  430.     pstart = p;
  431.     GETCHAR(code, p);
  432.     GETCHAR(id, p);
  433.     GETSHORT(len, p);
  434.     if (len < UPAP_HEADERLEN || len > plen)
  435.         return 0;
  436.     if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *))
  437.         printer(arg, " %s", upap_codenames[code-1]);
  438.     else
  439.         printer(arg, " code=0x%x", code);
  440.     printer(arg, " id=0x%x", id);
  441.     len -= UPAP_HEADERLEN;
  442.     switch (code) {
  443.     case UPAP_AUTHREQ:
  444.         if (len < 1)
  445.             break;
  446.         ulen = p[0];
  447.         if (len < ulen + 2)
  448.             break;
  449.         wlen = p[ulen + 1];
  450.         if (len < ulen + wlen + 2)
  451.             break;
  452.         user = (char *) (p + 1);
  453.         pwd = (char *) (p + ulen + 2);
  454.         p += ulen + wlen + 2;
  455.         len -= ulen + wlen + 2;
  456.         printer(arg, " user=");
  457.         print_string(user, ulen, printer, arg);
  458.         printer(arg, " password=");
  459.         print_string(pwd, wlen, printer, arg);
  460.         break;
  461.     case UPAP_AUTHACK:
  462.     case UPAP_AUTHNAK:
  463.         if (len < 1)
  464.             break;
  465.         mlen = p[0];
  466.         if (len < mlen + 1)
  467.             break;
  468.         msg = (char *) (p + 1);
  469.         p += mlen + 1;
  470.         len -= mlen + 1;
  471.         printer(arg, "msg=");
  472.         print_string(msg, mlen, printer, arg);
  473.         break;
  474.     }
  475.     /* print the rest of the bytes in the packet */
  476.     for (; len > 0; --len) {
  477.         GETCHAR(code, p);
  478.         printer(arg, " %.2x", code);
  479.     }
  480.     return p - pstart;
  481. }