home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / misc / 9q920411 / ppppap.c < prev    next >
C/C++ Source or Header  |  1992-03-28  |  16KB  |  726 lines

  1. /*
  2.  *  PPPPAP.C    -- Password Authentication Protocol for PPP
  3.  *
  4.  *    This implementation of PPP is declared to be in the public domain.
  5.  *
  6.  *    Jan 91    Bill_Simpson@um.cc.umich.edu
  7.  *        Computer Systems Consulting Services
  8.  *
  9.  *    Acknowledgements and correction history may be found in PPP.C
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "global.h"
  14. #include "mbuf.h"
  15. #include "proc.h"
  16. #include "iface.h"
  17. #include "session.h"
  18. #include "socket.h"
  19. #include "ppp.h"
  20. #include "pppfsm.h"
  21. #include "ppplcp.h"
  22. #include "ppppap.h"
  23. #include "cmdparse.h"
  24. #include "files.h"
  25. #include "trace.h"
  26. #include "main.h"
  27.  
  28. static int dopap_user        __ARGS((int argc, char *argv[], void *p));
  29.  
  30. static void pap_monitor __ARGS((int mustask, void *v1, void *v2));
  31. static void pap_pwdlookup __ARGS((struct pap_s *pap_p));
  32.  
  33. static struct mbuf *pap_makereq __ARGS((struct fsm_s *fsm_p));
  34.  
  35. static int pap_verify __ARGS((char *username, char *password));
  36. static void pap_shutdown __ARGS((struct fsm_s *fsm_p));
  37. static void pap_opening __ARGS((struct fsm_s *fsm_p, int flag));
  38.  
  39. static int pap_request    __ARGS((struct fsm_s *fsm_p,
  40.             struct config_hdr *hdr,
  41.             struct mbuf *data));
  42. static int pap_check    __ARGS((struct fsm_s *fsm_p,
  43.             struct config_hdr *hdr,
  44.             struct mbuf *data));
  45. static void pap_timeout    __ARGS((void *vp));
  46.  
  47. static void pap_free    __ARGS((struct fsm_s *fsm_p));
  48.  
  49.  
  50. static struct fsm_constant_s pap_constants = {
  51.     "Pap",
  52.     PPP_PAP_PROTOCOL,
  53.     0x000E,                /* codes 1-3 recognized */
  54.  
  55.     Pap,
  56.     PAP_REQ_TRY,
  57.     PAP_FAIL_MAX,
  58.     0,
  59.     PAP_TIMEOUT * 1000L,
  60.  
  61.     pap_free,
  62.  
  63.     fsm_no_action,        /* pap_reset, */
  64.     fsm_no_action,        /* pap_starting, */
  65.     fsm_no_action,        /* pap_opening, */
  66.     fsm_no_action,        /* pap_closing, */
  67.     fsm_no_action,        /* pap_stopping, */
  68.  
  69.     pap_makereq,
  70.     fsm_no_check,        /* pap_request, */
  71.     fsm_no_check,        /* pap_ack, */
  72.     fsm_no_check,        /* pap_nak, */
  73.     fsm_no_check,        /* pap_reject */
  74. };
  75.  
  76.  
  77. /****************************************************************************/
  78.  
  79. /* "ppp <iface> pap" subcommands */
  80. static struct cmds Papcmds[] = {
  81.     "timeout",    doppp_timeout,    0,    0,    NULLCHAR,
  82.     "try",        doppp_try,    0,    0,    NULLCHAR,
  83.     "user",        dopap_user,    0,    0,    NULLCHAR,
  84.     NULLCHAR,
  85. };
  86.  
  87.  
  88. int
  89. doppp_pap(argc,argv,p)
  90. int argc;
  91. char *argv[];
  92. void *p;
  93. {
  94.     register struct iface *ifp = p;
  95.     register struct ppp_s *ppp_p = ifp->edv;
  96.  
  97.     return subcmd(Papcmds, argc, argv, &(ppp_p->fsm[Pap]));
  98. }
  99.  
  100.  
  101. /* Set user/password */
  102. int
  103. dopap_user(argc,argv,p)
  104. int argc;
  105. char *argv[];
  106. void *p;
  107. {
  108.     register struct fsm_s *fsm_p = p;
  109.     register struct pap_s *pap_p = fsm_p->pdv;
  110.  
  111.     if (argc < 2) {
  112.         tprintf("%s\n",
  113.             (pap_p->username == NULLCHAR) ? "None" : pap_p->username);
  114.         return 0;
  115.     }
  116.     free(pap_p->username);
  117.     pap_p->username = NULLCHAR;
  118.     free(pap_p->password);
  119.     pap_p->password = NULLCHAR;
  120.  
  121.     if (stricmp(argv[1],"none") != 0) {
  122.         pap_p->username = strdup(argv[1]);
  123.         if (argc > 2) {
  124.             pap_p->password = strdup(argv[2]);
  125.         } else {
  126.             pap_pwdlookup( pap_p );
  127.         }
  128.     }
  129.     return 0;
  130. }
  131.  
  132.  
  133. /****************************************************************************/
  134. /* Bring up a session on the console for for the username/password.
  135.  * Return a NULLCHAR in either username or password if aborted.
  136.  */
  137. static void
  138. pap_monitor(unused, v1, v2)
  139. int unused;
  140. void *v1;
  141. void *v2;
  142. {
  143.     struct iface *iface = v1;
  144.     struct fsm_s *fsm_p = v2;
  145.     struct pap_s *pap_p = fsm_p->pdv;
  146.     char buf[21];
  147.     struct session *sp;
  148.     int wait_code = 0;
  149.  
  150.     /* Allocate a session control block */
  151.     if((sp = newsession("PPP/PAP",PPPPASS,1)) == NULLSESSION){
  152.         tprintf("Too many sessions\n");
  153.         return;
  154.     }
  155.  
  156.     while ( !main_exit && wait_code == 0 ) {
  157.         /* get user name */
  158.         if (pap_p->username == NULLCHAR) {
  159.             tprintf ("%s: PPP/PAP  Username: ", iface->name);
  160.             usflush(sp->output);
  161.             if (recvline(sp->input,buf,20) > 0) {
  162.                 rip(buf);
  163.                 if (strlen(buf) > 0) {
  164.                     pap_p->username = strdup(buf);
  165.                 }
  166.             }
  167.         } else {
  168.             tprintf ("%s: PPP/PAP  Username: %s\n",
  169.                 iface->name, pap_p->username);
  170.             usflush(sp->output);
  171.         }
  172.  
  173.         /* get pass word */
  174.         if (pap_p->username != NULLCHAR
  175.          && pap_p->password == NULLCHAR) {
  176.             /* turn off echo */
  177.             sp->ttystate.echo = 0;
  178.             tprintf("%s: PPP/PAP  Password: ",iface->name);
  179.             usflush(sp->output);
  180.             if (recvline(sp->input,buf,20) > 0) {
  181.                 rip(buf);
  182.                 if ( strlen(buf) > 0 ) {
  183.                     pap_p->password = strdup(buf);
  184.                 }
  185.             }
  186.             tprintf("\n");
  187.             usflush(sp->output);
  188.             /* Turn echo back on */
  189.             sp->ttystate.echo = 1;
  190.         }
  191.  
  192.         /* send pap request */
  193.         fsm_sendreq(fsm_p);
  194.         wait_code = pwait ( pap_p );
  195.  
  196.         /* show ack/nak reply */
  197.         if ( wait_code != EABORT && pap_p->message != NULLCHAR ) {
  198.             tprintf ("%s: PPP/PAP  %s\n",
  199.                 iface->name, pap_p->message );
  200.         }
  201.         tprintf ( "\n" );
  202.         usflush(sp->output);
  203.  
  204.     }
  205.  
  206.     /* clean up */
  207.     if ( wait_code != EABORT ) {
  208.         pause ( 10000L );
  209.     }
  210.     freesession(sp);
  211.     pap_p->pp = NULLPROC;
  212. }
  213.  
  214.  
  215. /* Check the FTP userfile for this user; get password if available */
  216. static void
  217. pap_pwdlookup(pap_p)
  218. struct pap_s *pap_p;
  219. {
  220.     char *buf;
  221.     char *password;
  222.     int permission;
  223.  
  224.     if ( pap_p->username == NULLCHAR )
  225.         return;
  226.  
  227.     if ( (buf = userlookup( pap_p->username, &password, NULLCHARP,
  228.             &permission, NULL )) == NULLCHAR )
  229.         return;
  230.  
  231.     /* Check permissions for this user */
  232.     if ( (permission & PPP_PWD_LOOKUP) == 0 ) {
  233.         /* Not in ftpuser file for password lookup */
  234.         free(buf);
  235.         return;
  236.     }
  237.  
  238.     /* Save the password from this userfile record */
  239.     if ( strlen(password) != 0 )
  240.         pap_p->password = strdup(password);
  241.     free(buf);
  242. }
  243.  
  244.  
  245. /*******************************************/
  246. /* Verify user and password sent by remote host */
  247. static int
  248. pap_verify(username,password)
  249. char *username;
  250. char *password;
  251. {
  252.     int privs;
  253.     char *path;
  254.     int anony = 0;
  255.  
  256.     /* Use same login as FTP server */
  257.     path = mallocw(128);
  258.     privs = userlogin(username,password,&path,128,&anony);
  259.     free(path);
  260.  
  261.     /* Check privs for this user */
  262.     if (privs == -1) {
  263.         trace_log(PPPiface,"PAP: username/password incorrect or not found: %s",
  264.                 username);
  265.         return -1;
  266.     }
  267.  
  268.     if ((privs & PPP_ACCESS_PRIV) == 0) {
  269.         trace_log(PPPiface,"PAP: no permission for PPP access: %s",
  270.                 username);
  271.         return -1;
  272.     }
  273.     return 0;
  274. }
  275.  
  276.  
  277. /****************************************************************************/
  278. /* Build a request to send to remote host */
  279. static struct mbuf *
  280. pap_makereq(fsm_p)
  281. struct fsm_s *fsm_p;
  282. {
  283.     struct pap_s *pap_p = fsm_p->pdv;
  284.     struct mbuf *req_bp = NULLBUF;
  285.     register char *cp;
  286.     int len;
  287.  
  288.     PPP_DEBUG_ROUTINES("pap_makereq()");
  289.  
  290.     if ( pap_p->username == NULLCHAR
  291.      ||  pap_p->password == NULLCHAR ) {
  292.         fsm_log( fsm_p, "NULL username or password" );
  293.         return NULLBUF;
  294.     }
  295.  
  296. #ifdef PPP_DEBUG_OPTIONS
  297.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  298.         trace_log(PPPiface, "    making user id %s", pap_p->username);
  299. #endif
  300.  
  301.     /* Get buffer for authenticate request packet */
  302.     len = 2 + strlen(pap_p->username) + strlen(pap_p->password);
  303.     if ((req_bp = alloc_mbuf(len)) == NULLBUF)
  304.         return NULLBUF;
  305.  
  306.     /* Load user id and password for authenticate packet */
  307.     cp = req_bp->data;
  308.     *cp++ = (char)strlen(pap_p->username);
  309.     if ( strlen(pap_p->username) > 0 )
  310.         cp = stpcpy(cp, pap_p->username);
  311.  
  312.     *cp++ = (char)strlen(pap_p->password);
  313.     if ( strlen(pap_p->password) > 0 )
  314.         cp = stpcpy(cp, pap_p->password);
  315.  
  316.     req_bp->cnt += len;
  317.     return(req_bp);
  318. }
  319.  
  320.  
  321. /****************************************************************************/
  322.  
  323. /* abandon PAP attempt; shutdown LCP layer */
  324. static void
  325. pap_shutdown(fsm_p)
  326. struct fsm_s *fsm_p;
  327. {
  328.     struct ppp_s *ppp_p = fsm_p->ppp_p;
  329.  
  330.     PPP_DEBUG_ROUTINES("pap_shutdown()");
  331.  
  332.     if (PPPtrace > 1)
  333.         fsm_log( fsm_p, "Failed; close connection" );
  334.  
  335.     fsm_close( &(ppp_p->fsm[Lcp]) );
  336. }
  337.  
  338.  
  339. /* Configuration negotiation complete */
  340. static void
  341. pap_opening(fsm_p, flag)
  342. struct fsm_s *fsm_p;
  343. int flag;
  344. {
  345.     register struct ppp_s *ppp_p = fsm_p->ppp_p;
  346.  
  347.     fsm_log(fsm_p, "Open");
  348.  
  349.     stop_timer(&(fsm_p->timer));
  350.  
  351.     if ( !((fsm_p->flags &= ~flag) & (PPP_AP_LOCAL | PPP_AP_REMOTE)) ) {
  352.         fsm_p->state = fsmOPENED;
  353.     }
  354.     ppp_p->flags &= ~flag;
  355.     ppp_ready(ppp_p);
  356. }
  357.  
  358.  
  359. /****************************************************************************/
  360. /* Check request from remote host */
  361. static int
  362. pap_request(fsm_p, hdr, data)
  363. struct fsm_s *fsm_p;
  364. struct config_hdr *hdr;
  365. struct mbuf *data;
  366. {
  367.     struct mbuf *reply_bp;
  368.     int result;
  369.     char *message;
  370.     int mess_length;
  371.     char *username = NULLCHAR;
  372.     int userlen;
  373.     char *password = NULLCHAR;
  374.     int passwordlen;
  375.  
  376.     PPP_DEBUG_ROUTINES("pap_request()");
  377.  
  378.     /* Extract userID/password sent by remote host */
  379.     if ( (userlen = pullchar(&data)) != -1 ) {
  380.         register int i;
  381.         register char *cp;
  382.  
  383.         cp = username = mallocw(userlen+1);
  384.         for ( i = userlen; i-- > 0; ) {
  385.             *cp++ = PULLCHAR(&data);
  386.         }
  387.         *cp = '\0';
  388.     }
  389.  
  390. #ifdef PPP_DEBUG_OPTIONS
  391.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  392.         trace_log(PPPiface,"    checking user: %s", username);
  393. #endif
  394.  
  395.     if ( (passwordlen = pullchar(&data)) != -1 ) {
  396.         register int i;
  397.         register char *cp;
  398.  
  399.         cp = password = mallocw(passwordlen+1);
  400.         for ( i = passwordlen; i-- > 0; ) {
  401.             *cp++ = PULLCHAR(&data);
  402.         }
  403.         *cp = '\0';
  404.     }
  405.  
  406. #ifdef PPP_DEBUG_OPTIONS
  407.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  408.         trace_log(PPPiface,"    checking password: %s", password);
  409. #endif
  410.  
  411.     if (pap_verify(username,password) == 0) {
  412.         free( fsm_p->ppp_p->peername );
  413.         fsm_p->ppp_p->peername = strdup(username);
  414.         result = CONFIG_ACK;
  415.         message = " Welcome";
  416.     } else {
  417.         result = CONFIG_NAK;
  418.         message = " Invalid username or password";
  419.     }
  420.  
  421.     /* the space at the beginning of the message is crucial */
  422.     /* it is replaced with the length of the message */
  423.     mess_length = strlen(message);
  424.     reply_bp = qdata(message,mess_length);
  425.     reply_bp->data[0] = (char)(mess_length - 1);
  426.  
  427.     fsm_send(fsm_p, result, hdr->id, reply_bp);
  428.  
  429.     if (result == CONFIG_NAK) {
  430.         if ( fsm_p->retry_nak > 0 ) {
  431.             fsm_p->retry_nak--;
  432.         } else {
  433.             pap_shutdown(fsm_p);
  434.         }
  435.     }
  436.     free_p(data);
  437.     free(username);
  438.     free(password);
  439.     return (result != CONFIG_ACK);
  440. }
  441.  
  442.  
  443. /* Check acknowledgement from remote host */
  444. static int
  445. pap_check(fsm_p, hdr, data)
  446. struct fsm_s *fsm_p;
  447. struct config_hdr *hdr;
  448. struct mbuf *data;
  449. {
  450.     struct pap_s *pap_p = fsm_p->pdv;
  451.     char *message;
  452.     int mess_length;
  453.     int full_length;
  454.     int len;
  455.  
  456.     PPP_DEBUG_ROUTINES("pap_check()");
  457.  
  458.     /* ID field must match last request we sent */
  459.     if (hdr->id != fsm_p->lastid) {
  460.         PPP_DEBUG_CHECKS("PAP: wrong ID");
  461.         tprintf ("id mismatch hdrid=%d, lastid=%d\n",
  462.             hdr->id, fsm_p->lastid);
  463.         free_p(data);
  464.         return -1;
  465.     }
  466.  
  467.     /* Log ASCII message from remote host, if any */
  468.     if ( (mess_length = pullchar(&data)) != -1 ) {
  469.         message = mallocw( mess_length+1 );
  470.         full_length = len_p(data);
  471.         len = dqdata(data, message, mess_length);
  472.         message[len] = '\0';
  473.  
  474.         free( pap_p->message );
  475.         pap_p->message = message;
  476.  
  477.         if (PPPtrace) {
  478.             trace_log(PPPiface,"%s PPP/PAP %s %s: %s",
  479.                 fsm_p->ppp_p->iface->name,
  480.                 (len < mess_length) ? "Short"
  481.                    : (mess_length < full_length) ? "Long"
  482.                     : "Valid",
  483.                 (hdr->code == CONFIG_ACK) ? "Ack" : "Nak",
  484.                 message);
  485.         }
  486.         return (len < mess_length  ||  mess_length < full_length);
  487.     }
  488.     free_p(data);
  489.     PPP_DEBUG_CHECKS( "PAP: missing message count" );
  490.     return -1;
  491. }
  492.  
  493.  
  494. /************************************************************************/
  495. /*            E V E N T   P R O C E S S I N G            */
  496. /************************************************************************/
  497.  
  498. /* Process incoming packet */
  499. void
  500. pap_proc(fsm_p,bp)
  501. struct fsm_s *fsm_p;
  502. struct mbuf *bp;
  503. {
  504.     struct pap_s *pap_p = fsm_p->pdv;
  505.     struct config_hdr hdr;
  506.  
  507.     PPPtrace = fsm_p->ppp_p->trace;
  508.     PPPiface = fsm_p->ppp_p->iface;
  509.  
  510.     if ( ntohcnf(&hdr, &bp) == -1 )
  511.         fsm_log( fsm_p, "short authentication packet" );
  512.  
  513.     if (PPPtrace > 1)
  514.         trace_log(PPPiface, "%s PPP/%s Recv,"
  515.             "  option: %s, id: %d, len: %d",
  516.             fsm_p->ppp_p->iface->name,
  517.             fsm_p->pdc->name,
  518.             fsmCodes[hdr.code],
  519.             hdr.id,    hdr.len);
  520.  
  521.     hdr.len -= CONFIG_HDR_LEN;        /* Length includes envelope */
  522.     trim_mbuf(&bp, hdr.len);        /* Trim off padding */
  523.  
  524.     switch(hdr.code) {
  525.     case CONFIG_REQ:
  526.         if ( pap_request(fsm_p, &hdr, bp) == 0) {
  527.             pap_opening(fsm_p, PPP_AP_LOCAL);
  528.         }
  529.         break;
  530.  
  531.     case CONFIG_ACK:
  532.         if (pap_check(fsm_p, &hdr, bp) == 0) {
  533.             alert ( pap_p->pp, -1 );
  534.             pap_opening(fsm_p, PPP_AP_REMOTE);
  535.         }
  536.         break;
  537.  
  538.     case CONFIG_NAK:
  539.         if (pap_check(fsm_p, &hdr, bp) == 0) {
  540.             stop_timer(&(fsm_p->timer));
  541.  
  542.             /* Must have sent a bad username or password */
  543.             free ( pap_p->username );
  544.             pap_p->username = NULLCHAR;
  545.             free ( pap_p->password );
  546.             pap_p->password = NULLCHAR;
  547.  
  548.             psignal ( pap_p, 1 );
  549.         }
  550.         break;
  551.  
  552.     default:
  553.         if (PPPtrace)
  554.             trace_log(PPPiface, "%s PPP/Pap Unknown packet type: %d;"
  555.                 " dropping packet",
  556.                 fsm_p->ppp_p->iface->name,
  557.                 hdr.code);
  558.         free_p(bp);
  559.         break;
  560.     }
  561. }
  562.  
  563.  
  564. /* Timeout while waiting for reply from remote host */
  565. static void
  566. pap_timeout(vp)
  567. void *vp;
  568. {
  569.     struct fsm_s *fsm_p = (struct fsm_s *)vp;
  570.     struct pap_s *pap_p = fsm_p->pdv;
  571.  
  572.     PPPtrace = fsm_p->ppp_p->trace;
  573.     PPPiface = fsm_p->ppp_p->iface;
  574.  
  575.     fsm_log( fsm_p, "Timeout" );
  576.  
  577.     if (fsm_p->retry > 0) {
  578.         free ( pap_p->message );
  579.         pap_p->message = strdup("Request timeout");
  580.         psignal ( pap_p, 1 );
  581.     } else {
  582.         free ( pap_p->message );
  583.         pap_p->message = strdup("Request retry exceeded");
  584.         psignal ( pap_p, 1 );
  585.         pwait ( NULL );
  586.         fsm_log(fsm_p, "Request retry exceeded");
  587.         pap_shutdown(fsm_p);
  588.     }
  589. }
  590.  
  591.  
  592. /************************************************************************/
  593. /*            I N I T I A L I Z A T I O N            */
  594. /************************************************************************/
  595.  
  596. void
  597. pap_down(fsm_p)
  598. struct fsm_s *fsm_p;
  599. {
  600.     struct pap_s *pap_p = fsm_p->pdv;
  601.  
  602.     if ( pap_p == NULL )
  603.         return;
  604.  
  605.     PPPtrace = fsm_p->ppp_p->trace;
  606.     PPPiface = fsm_p->ppp_p->iface;
  607.  
  608.     fsm_log(fsm_p, "Down");
  609.  
  610.     fsm_p->flags = FALSE;
  611.  
  612.     switch ( fsm_p->state ) {
  613.     case fsmREQ_Sent:
  614.         stop_timer(&(fsm_p->timer));
  615.         alert ( pap_p->pp, EABORT );
  616.         /* fallthru */
  617.     case fsmOPENED:
  618.     case fsmLISTEN:
  619.     case fsmTERM_Sent:
  620.         fsm_p->state = fsmCLOSED;
  621.         break;
  622.  
  623.     case fsmCLOSED:
  624.         /* Already closed; nothing to do */
  625.         break;
  626.     };
  627. }
  628.  
  629.  
  630. static void
  631. pap_free(fsm_p)
  632. struct fsm_s *fsm_p;
  633. {
  634.     struct pap_s *pap_p = fsm_p->pdv;
  635.  
  636.     free( pap_p->username );
  637.     free( pap_p->password );
  638.     free( pap_p->message );
  639. }
  640.  
  641.  
  642. /* Initialize configuration structure */
  643. void
  644. pap_init(ppp_p)
  645. struct ppp_s *ppp_p;
  646. {
  647.     struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  648.     struct timer *t;
  649.  
  650.     PPPtrace = ppp_p->trace;
  651.     PPPiface = ppp_p->iface;
  652.  
  653.     PPP_DEBUG_ROUTINES("pap_init()");
  654.  
  655.     if (fsm_p->pdv != NULL)
  656.         return;        /* already initialized */
  657.  
  658.     fsm_p->ppp_p = ppp_p;
  659.     fsm_p->pdc = &pap_constants;
  660.     fsm_p->pdv = callocw(1,sizeof(struct pap_s));
  661.  
  662.     fsm_p->try_req = fsm_p->pdc->try_req;
  663.     fsm_p->try_nak = fsm_p->pdc->try_nak;
  664.     fsm_p->try_terminate = fsm_p->pdc->try_terminate;
  665.  
  666.     fsm_p->state = fsmCLOSED;
  667.     fsm_p->retry = fsm_p->try_req;
  668.     fsm_p->retry_nak = fsm_p->try_nak;
  669.  
  670.     /* Initialize timer */
  671.     t = &(fsm_p->timer);
  672.     t->func = (void (*)())pap_timeout;
  673.     t->arg = (void *)fsm_p;
  674.     set_timer(t, fsm_p->pdc->timeout);
  675.     fsm_timer(fsm_p);
  676.     stop_timer(t);
  677. }
  678.  
  679.  
  680. /* Initialize state machine for local */
  681. int
  682. pap_local(ppp_p)
  683. struct ppp_s *ppp_p;
  684. {
  685.     struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  686.  
  687.     PPPtrace = ppp_p->trace;
  688.  
  689.     PPP_DEBUG_ROUTINES("pap_local()");
  690.  
  691.     fsm_p->state = fsmLISTEN;
  692.     fsm_p->flags |= PPP_AP_LOCAL;
  693.     ppp_p->flags |= PPP_AP_LOCAL;
  694.     fsm_p->retry = fsm_p->try_req;
  695.     return 0;
  696. }
  697.  
  698.  
  699. /* Initialize state machine for remote */
  700. int
  701. pap_remote(ppp_p)
  702. struct ppp_s *ppp_p;
  703. {
  704.     struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  705.     struct pap_s *pap_p = fsm_p->pdv;
  706.     char *ifn;
  707.  
  708.     PPPtrace = ppp_p->trace;
  709.  
  710.     PPP_DEBUG_ROUTINES("pap_remote()");
  711.  
  712.     fsm_p->state = fsmREQ_Sent;
  713.     fsm_p->flags |= PPP_AP_REMOTE;
  714.     ppp_p->flags |= PPP_AP_REMOTE;
  715.  
  716.     /* build a process/session to monitor user/password progress */
  717.     ifn = if_name( ppp_p->iface, " PAP" );
  718.     pap_p->pp = newproc( ifn,
  719.         512, pap_monitor, 0, ppp_p->iface, fsm_p, 0);
  720.     free( ifn );
  721.  
  722.     return 0;
  723. }
  724.  
  725.  
  726.