home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / SUN / PPP / SUNOS_OL / DDP_PPP.TAR / upap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-03  |  9.8 KB  |  444 lines

  1. /*
  2.  * upap.c - User/Password Authentication Protocol.
  3.  *
  4.  * Copyright (c) 1989 Carnegie Mellon University.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by Carnegie Mellon University.  The name of the
  13.  * University may not be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. /*
  21.  * TODO:
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <sys/types.h>
  26. #include <sys/time.h>
  27.  
  28. #include "ppp.h"
  29. #include "upap.h"
  30.  
  31.  
  32. upap_state upap[NPPP];        /* UPAP state; one for each unit */
  33.  
  34.  
  35. void upap_timeout(), upap_rauth(), upap_rauthack(), upap_rauthnak();
  36. void upap_sauth(), upap_sresp();
  37.  
  38.  
  39. /*
  40.  * upap_init - Initialize a UPAP unit.
  41.  */
  42. void upap_init(unit)
  43.     int unit;
  44. {
  45.     upap_state *u = &upap[unit];
  46.  
  47.     u->us_unit = unit;
  48.     u->us_user = NULL;
  49.     u->us_userlen = 0;
  50.     u->us_passwd = NULL;
  51.     u->us_passwdlen = 0;
  52.     u->us_clientstate = UPAPCS_CLOSED;
  53.     u->us_serverstate = UPAPSS_CLOSED;
  54.     u->us_flags = 0;
  55.     u->us_id = 0;
  56.     u->us_timeouttime = UPAP_DEFTIMEOUT;
  57. }
  58.  
  59.  
  60. /*
  61.  * upap_authwithpeer - Authenticate us with our peer (start client).
  62.  *
  63.  * Set new state and send authenticate's.
  64.  */
  65. void upap_authwithpeer(unit)
  66.     int unit;
  67. {
  68.     upap_state *u = &upap[unit];
  69.  
  70.     u->us_flags &= ~UPAPF_AWPPENDING;    /* Clear pending flag */
  71.  
  72.     /* Protect against programming errors that compromise security */
  73.     if (u->us_serverstate != UPAPSS_CLOSED ||
  74.     u->us_flags & UPAPF_APPENDING) {
  75.     UPAPDEBUG((stderr,
  76.            "ppp: upap_authwithpeer: upap_authpeer already called!\n"));
  77.     return;
  78.     }
  79.  
  80.     /* Already authenticat{ed,ing}? */
  81.     if (u->us_clientstate == UPAPCS_AUTHSENT ||
  82.     u->us_clientstate == UPAPCS_OPEN)
  83.     return;
  84.  
  85.     /* Lower layer up? */
  86.     if (!(u->us_flags & UPAPF_LOWERUP)) {
  87.     u->us_flags |= UPAPF_AWPPENDING; /* Wait */
  88.     return;
  89.     }
  90.  
  91.     /* User/passwd values valid? */
  92.     if (!(u->us_flags & UPAPF_UPVALID)) {
  93.     GETUSERPASSWD(unit);        /* Start getting user and passwd */
  94.     if (!(u->us_flags & UPAPF_UPVALID)) {
  95.         u->us_flags |= UPAPF_UPPENDING;    /* Wait */
  96.         return;
  97.     }
  98.     }
  99.  
  100.     upap_sauth(u);            /* Start protocol */
  101.     TIMEOUT(upap_timeout, u, u->us_timeouttime);
  102.     u->us_clientstate = UPAPCS_AUTHSENT;
  103.     u->us_retransmits = 0;
  104. }
  105.  
  106.  
  107. /*
  108.  * upap_authpeer - Authenticate our peer (start server).
  109.  *
  110.  * Set new state.
  111.  */
  112. void upap_authpeer(unit)
  113.     int unit;
  114. {
  115.     upap_state *u = &upap[unit];
  116.  
  117.     u->us_flags &= ~UPAPF_APPENDING;    /* Clear pending flag */
  118.  
  119.     /* Already authenticat{ed,ing}? */
  120.     if (u->us_serverstate == UPAPSS_LISTEN ||
  121.     u->us_serverstate == UPAPSS_OPEN)
  122.     return;
  123.  
  124.     /* Lower layer up? */
  125.     if (!(u->us_flags & UPAPF_LOWERUP)) {
  126.     u->us_flags |= UPAPF_APPENDING;    /* Wait for desired event */
  127.     return;
  128.     }
  129.     u->us_serverstate = UPAPSS_LISTEN;
  130. }
  131.  
  132.  
  133. /*
  134.  * upap_timeout - Timeout expired.
  135.  */
  136. void upap_timeout(u)
  137.     upap_state *u;
  138. {
  139.     if (u->us_clientstate != UPAPCS_AUTHSENT)
  140.     return;
  141.  
  142.     /* XXX Print warning after many retransmits? */
  143.  
  144.     upap_sauth(u);            /* Send Configure-Request */
  145.     TIMEOUT(upap_timeout, u, u->us_timeouttime);
  146.     ++u->us_retransmits;
  147. }
  148.  
  149.  
  150. /*
  151.  * upap_lowerup - The lower layer is up.
  152.  *
  153.  * Start authenticating if pending.
  154.  */
  155. void upap_lowerup(unit)
  156.     int unit;
  157. {
  158.     upap_state *u = &upap[unit];
  159.  
  160.     u->us_flags |= UPAPF_LOWERUP;
  161.     if (u->us_flags & UPAPF_AWPPENDING)    /* Attempting authwithpeer? */
  162.     upap_authwithpeer(unit);    /* Try it now */
  163.     if (u->us_flags & UPAPF_APPENDING)    /* Attempting authpeer? */
  164.     upap_authpeer(unit);        /* Try it now */
  165. }
  166.  
  167.  
  168. /*
  169.  * upap_lowerdown - The lower layer is down.
  170.  *
  171.  * Cancel all timeouts.
  172.  */
  173. void upap_lowerdown(unit)
  174.     int unit;
  175. {
  176.     upap_state *u = &upap[unit];
  177.  
  178.     u->us_flags &= ~UPAPF_LOWERUP;    /* XXX UPAP_UPVALID? */
  179.  
  180.     if (u->us_clientstate == UPAPCS_AUTHSENT) /* Timeout pending? */
  181.     UNTIMEOUT(upap_timeout, u);    /* Cancel timeout */
  182.  
  183.     if (u->us_serverstate == UPAPSS_OPEN) /* User logged in? */
  184.     LOGOUT(unit);
  185.     u->us_clientstate = UPAPCS_CLOSED;
  186.     u->us_serverstate = UPAPSS_CLOSED;
  187. }
  188.  
  189.  
  190. /*
  191.  * upap_protrej - Peer doesn't speak this protocol.
  192.  *
  193.  * This shouldn't happen.  In any case, pretend lower layer went down.
  194.  */
  195. void upap_protrej(unit)
  196.     int unit;
  197. {
  198.     upap_lowerdown(unit);
  199. }
  200.  
  201.  
  202. /*
  203.  * upap_input - Input UPAP packet.
  204.  */
  205. void upap_input(unit, inpacket, l)
  206.     int unit;
  207.     PACKET *inpacket;
  208.     int l;
  209. {
  210.     upap_state *u = &upap[unit];
  211.     u_char *inp;
  212.     u_char code, id;
  213.     int len;
  214.  
  215.     /*
  216.      * Parse header (code, id and length).
  217.      * If packet too short, drop it.
  218.      */
  219.     inp = PACKET_DATA(inpacket);
  220.     if (l < UPAP_HEADERLEN) {
  221.     UPAPDEBUG((stderr, "ppp: upap_input: rcvd short header.\n"));
  222.     goto freepacket;
  223.     }
  224.     GETCHAR(code, inp);
  225.     GETCHAR(id, inp);
  226.     GETSHORT(len, inp);
  227.     if (len < UPAP_HEADERLEN) {
  228.     UPAPDEBUG((stderr, "ppp: upap_input: rcvd illegal length.\n"));
  229.     goto freepacket;
  230.     }
  231.     if (len > l) {
  232.     UPAPDEBUG((stderr, "ppp: upap_input: rcvd short packet.\n"));
  233.     goto freepacket;
  234.     }
  235.     len -= UPAP_HEADERLEN;
  236.  
  237.     /*
  238.      * Action depends on code.
  239.      */
  240.     switch (code) {
  241.       case UPAP_AUTH:
  242.     upap_rauth(u, inp, id, len);
  243.     break;
  244.  
  245.       case UPAP_AUTHACK:
  246.     upap_rauthack(u, inp, id, len);
  247.     break;
  248.  
  249.       case UPAP_AUTHNAK:
  250.     upap_rauthnak(u, inp, id, len);
  251.     break;
  252.  
  253.       default:                /* XXX Need code reject */
  254.     break;
  255.     }
  256.  
  257. freepacket:
  258.     PACKET_FREE(inpacket);
  259. }
  260.  
  261.  
  262. /*
  263.  * upap_rauth - Receive Authenticate.
  264.  */
  265. void upap_rauth(u, inp, id, len)
  266.     upap_state *u;
  267.     u_char *inp;
  268.     u_char id;
  269.     int len;
  270. {
  271.     u_char ruserlen, rpasswdlen;
  272.     u_char *ruser, *rpasswd;
  273.     u_char retcode;
  274.     u_char *msg;
  275.     int msglen;
  276.  
  277.     UPAPDEBUG((stderr, "ppp: upap_rauth: Rcvd id %d.\n", id));
  278.     if (u->us_serverstate != UPAPSS_LISTEN) /* XXX Reset connection? */
  279.     return;
  280.  
  281.     /*
  282.      * Parse user/passwd.
  283.      */
  284.     if (len < sizeof (u_char)) {
  285.     UPAPDEBUG((stderr, "ppp: upap_rauth: rcvd short packet.\n"));
  286.     return;
  287.     }
  288.     GETCHAR(ruserlen, inp);
  289.     len -= sizeof (u_char) + ruserlen + sizeof (u_char);;
  290.     if (len < 0) {
  291.     UPAPDEBUG((stderr, "ppp: upap_rauth: rcvd short packet.\n"));
  292.     return;
  293.     }
  294.     ruser = inp;
  295.     INCPTR(ruserlen, inp);
  296.     GETCHAR(rpasswdlen, inp);
  297.     if (len < rpasswdlen) {
  298.     UPAPDEBUG((stderr, "ppp: upap_rauth: rcvd short packet.\n"));
  299.     return;
  300.     }
  301.     rpasswd = inp;
  302.  
  303.     retcode = LOGIN(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen,
  304.             &msg, &msglen);
  305.  
  306.     upap_sresp(u, retcode, id, msg, msglen);
  307.     if (retcode == UPAP_AUTHACK) {
  308.     u->us_serverstate = UPAPSS_OPEN;
  309.     ipcp_activeopen(u->us_unit);    /* Start IPCP */
  310.     }
  311. }
  312.  
  313.  
  314. /*
  315.  * upap_rauthack - Receive Authenticate-Ack.
  316.  */
  317. void upap_rauthack(u, inp, id, len)
  318.     upap_state *u;
  319.     u_char *inp;
  320.     u_char id;
  321.     int len;
  322. {
  323.     u_char msglen;
  324.     u_char *msg;
  325.  
  326.     UPAPDEBUG((stderr, "ppp: upap_rauthack: Rcvd id %d.\n", id));
  327.     if (u->us_clientstate != UPAPCS_AUTHSENT) /* XXX */
  328.     return;
  329.  
  330.     /*
  331.      * Parse message.
  332.      */
  333.     if (len < sizeof (u_char)) {
  334.     UPAPDEBUG((stderr, "ppp: upap_rauthack: rcvd short packet.\n"));
  335.     return;
  336.     }
  337.     GETCHAR(msglen, inp);
  338.     len -= sizeof (u_char);
  339.     if (len < msglen) {
  340.     UPAPDEBUG((stderr, "ppp: upap_rauthack: rcvd short packet.\n"));
  341.     return;
  342.     }
  343.     msg = inp;
  344.     PRINTMSG(msg, msglen);
  345.  
  346.     u->us_clientstate = UPAPCS_OPEN;
  347.     ipcp_activeopen(u->us_unit);    /* Start IPCP */
  348. }
  349.  
  350.  
  351. /*
  352.  * upap_rauthnak - Receive Authenticate-Nakk.
  353.  */
  354. void upap_rauthnak(u, inp, id, len)
  355.     upap_state *u;
  356.     u_char *inp;
  357.     u_char id;
  358.     int len;
  359. {
  360.     u_char msglen;
  361.     u_char *msg;
  362.  
  363.     UPAPDEBUG((stderr, "ppp: upap_rauthnak: Rcvd id %d.\n", id));
  364.     if (u->us_clientstate != UPAPCS_AUTHSENT) /* XXX */
  365.     return;
  366.  
  367.     /*
  368.      * Parse message.
  369.      */
  370.     if (len < sizeof (u_char)) {
  371.     UPAPDEBUG((stderr, "ppp: upap_rauthnak: rcvd short packet.\n"));
  372.     return;
  373.     }
  374.     GETCHAR(msglen, inp);
  375.     len -= sizeof (u_char);
  376.     if (len < msglen) {
  377.     UPAPDEBUG((stderr, "ppp: upap_rauthnak: rcvd short packet.\n"));
  378.     return;
  379.     }
  380.     msg = inp;
  381.     PRINTMSG(msg, msglen);
  382.  
  383.     u->us_flags &= ~UPAPF_UPVALID;    /* Clear valid flag */
  384.     u->us_clientstate = UPAPCS_CLOSED;    /* Pretend for a moment */
  385.     upap_authwithpeer(u->us_unit);    /* Restart */
  386. }
  387.  
  388.  
  389. /*
  390.  * upap_sauth - Send an Authenticate.
  391.  */
  392. void upap_sauth(u)
  393.     upap_state *u;
  394. {
  395.     PACKET *outpacket;
  396.     u_char *outp;
  397.     int outlen;
  398.  
  399.     outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
  400.     u->us_userlen + u->us_passwdlen;
  401.     outpacket = PACKET_ALLOC(outlen);
  402.     outp = PACKET_DATA(outpacket);
  403.  
  404.     PUTCHAR(UPAP_AUTH, outp);
  405.     PUTCHAR(++u->us_id, outp);
  406.     PUTSHORT(outlen, outp);
  407.     PUTCHAR(u->us_userlen, outp);
  408.     BCOPY(u->us_user, outp, u->us_userlen);
  409.     INCPTR(u->us_userlen, outp);
  410.     PUTCHAR(u->us_passwdlen, outp);
  411.     BCOPY(u->us_passwd, outp, u->us_passwdlen);
  412.     OUTPUT(u->us_unit, outpacket, outlen, UPAP);
  413.  
  414.     UPAPDEBUG((stderr, "ppp: upap_sauth: Sent id %d.\n", u->us_id));
  415. }
  416.  
  417.  
  418. /*
  419.  * upap_sresp - Send a response (ack or nak).
  420.  */
  421. void upap_sresp(u, code, id, msg, msglen)
  422.     upap_state *u;
  423.     u_char code, id;
  424.     u_char *msg;
  425.     int msglen;
  426. {
  427.     PACKET *outpacket;
  428.     u_char *outp;
  429.     int outlen;
  430.  
  431.     outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
  432.     outpacket = PACKET_ALLOC(outlen);
  433.     outp = PACKET_DATA(outpacket);
  434.  
  435.     PUTCHAR(code, outp);
  436.     PUTCHAR(id, outp);
  437.     PUTSHORT(outlen, outp);
  438.     PUTCHAR(msglen, outp);
  439.     BCOPY(msg, outp, msglen);
  440.     OUTPUT(u->us_unit, outpacket, outlen, UPAP);
  441.  
  442.     UPAPDEBUG((stderr, "ppp: upap_sresp: Sent code %d, id %d.\n", code, id));
  443. }
  444.