ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

auth.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * auth.c - Network Authentication and Phase Control program file.
00003 *
00004 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
00005 * Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
00006 *
00007 * The authors hereby grant permission to use, copy, modify, distribute,
00008 * and license this software and its documentation for any purpose, provided
00009 * that existing copyright notices are retained in all copies and that this
00010 * notice and the following disclaimer are included verbatim in any 
00011 * distributions. No written agreement, license, or royalty fee is required
00012 * for any of the authorized uses.
00013 *
00014 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
00015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00017 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024 *
00025 ******************************************************************************
00026 * REVISION HISTORY
00027 *
00028 * 03-01-01 Marc Boucher <marc@mbsi.ca>
00029 *   Ported to lwIP.
00030 * 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
00031 *   Ported from public pppd code.
00032 *****************************************************************************/
00033 /*
00034  * auth.c - PPP authentication and phase control.
00035  *
00036  * Copyright (c) 1993 The Australian National University.
00037  * All rights reserved.
00038  *
00039  * Redistribution and use in source and binary forms are permitted
00040  * provided that the above copyright notice and this paragraph are
00041  * duplicated in all such forms and that any documentation,
00042  * advertising materials, and other materials related to such
00043  * distribution and use acknowledge that the software was developed
00044  * by the Australian National University.  The name of the University
00045  * may not be used to endorse or promote products derived from this
00046  * software without specific prior written permission.
00047  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00048  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00049  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00050  *
00051  * Copyright (c) 1989 Carnegie Mellon University.
00052  * All rights reserved.
00053  *
00054  * Redistribution and use in source and binary forms are permitted
00055  * provided that the above copyright notice and this paragraph are
00056  * duplicated in all such forms and that any documentation,
00057  * advertising materials, and other materials related to such
00058  * distribution and use acknowledge that the software was developed
00059  * by Carnegie Mellon University.  The name of the
00060  * University may not be used to endorse or promote products derived
00061  * from this software without specific prior written permission.
00062  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00063  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00064  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00065  */
00066 
00067 #include "lwip/opt.h"
00068 
00069 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
00070 
00071 #include "ppp.h"
00072 #include "pppdebug.h"
00073 
00074 #include "fsm.h"
00075 #include "lcp.h"
00076 #include "pap.h"
00077 #include "chap.h"
00078 #include "auth.h"
00079 #include "ipcp.h"
00080 
00081 #if CBCP_SUPPORT
00082 #include "cbcp.h"
00083 #endif /* CBCP_SUPPORT */
00084 
00085 #include "lwip/inet.h"
00086 
00087 #include <string.h>
00088 
00089 #if 0 /* UNUSED */
00090 /* Bits in scan_authfile return value */
00091 #define NONWILD_SERVER  1
00092 #define NONWILD_CLIENT  2
00093 
00094 #define ISWILD(word)  (word[0] == '*' && word[1] == 0)
00095 #endif /* UNUSED */
00096 
00097 #if PAP_SUPPORT || CHAP_SUPPORT
00098 /* The name by which the peer authenticated itself to us. */
00099 static char peer_authname[MAXNAMELEN];
00100 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
00101 
00102 /* Records which authentication operations haven't completed yet. */
00103 static int auth_pending[NUM_PPP];
00104 
00105 /* Set if we have successfully called plogin() */
00106 static int logged_in;
00107 
00108 /* Set if we have run the /etc/ppp/auth-up script. */
00109 static int did_authup; /* @todo, we don't need this in lwip*/
00110 
00111 /* List of addresses which the peer may use. */
00112 static struct wordlist *addresses[NUM_PPP];
00113 
00114 #if 0 /* UNUSED */
00115 /* Wordlist giving addresses which the peer may use
00116    without authenticating itself. */
00117 static struct wordlist *noauth_addrs;
00118 
00119 /* Extra options to apply, from the secrets file entry for the peer. */
00120 static struct wordlist *extra_options;
00121 #endif /* UNUSED */
00122 
00123 /* Number of network protocols which we have opened. */
00124 static int num_np_open;
00125 
00126 /* Number of network protocols which have come up. */
00127 static int num_np_up;
00128 
00129 #if PAP_SUPPORT || CHAP_SUPPORT
00130 /* Set if we got the contents of passwd[] from the pap-secrets file. */
00131 static int passwd_from_file;
00132 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
00133 
00134 #if 0 /* UNUSED */
00135 /* Set if we require authentication only because we have a default route. */
00136 static bool default_auth;
00137 
00138 /* Hook to enable a plugin to control the idle time limit */
00139 int (*idle_time_hook) __P((struct ppp_idle *)) = NULL;
00140 
00141 /* Hook for a plugin to say whether we can possibly authenticate any peer */
00142 int (*pap_check_hook) __P((void)) = NULL;
00143 
00144 /* Hook for a plugin to check the PAP user and password */
00145 int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp,
00146         struct wordlist **paddrs,
00147         struct wordlist **popts)) = NULL;
00148 
00149 /* Hook for a plugin to know about the PAP user logout */
00150 void (*pap_logout_hook) __P((void)) = NULL;
00151 
00152 /* Hook for a plugin to get the PAP password for authenticating us */
00153 int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL;
00154 
00155 /*
00156  * This is used to ensure that we don't start an auth-up/down
00157  * script while one is already running.
00158  */
00159 enum script_state {
00160     s_down,
00161     s_up
00162 };
00163 
00164 static enum script_state auth_state = s_down;
00165 static enum script_state auth_script_state = s_down;
00166 static pid_t auth_script_pid = 0;
00167 
00168 /*
00169  * Option variables.
00170  * lwip: some of these are present in the ppp_settings structure
00171  */
00172 bool uselogin = 0;            /* Use /etc/passwd for checking PAP */
00173 bool cryptpap = 0;            /* Passwords in pap-secrets are encrypted */
00174 bool refuse_pap = 0;          /* Don't wanna auth. ourselves with PAP */
00175 bool refuse_chap = 0;         /* Don't wanna auth. ourselves with CHAP */
00176 bool usehostname = 0;         /* Use hostname for our_name */
00177 bool auth_required = 0;       /* Always require authentication from peer */
00178 bool allow_any_ip = 0;        /* Allow peer to use any IP address */
00179 bool explicit_remote = 0;     /* User specified explicit remote name */
00180 char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
00181 
00182 #endif /* UNUSED */
00183 
00184 /* Bits in auth_pending[] */
00185 #define PAP_WITHPEER    1
00186 #define PAP_PEER        2
00187 #define CHAP_WITHPEER   4
00188 #define CHAP_PEER       8
00189 
00190 /* @todo, move this somewhere */
00191 /* Used for storing a sequence of words.  Usually malloced. */
00192 struct wordlist {
00193   struct wordlist *next;
00194   char        word[1];
00195 };
00196 
00197 
00198 extern char *crypt (const char *, const char *);
00199 
00200 /* Prototypes for procedures local to this file. */
00201 
00202 static void network_phase (int);
00203 static void check_idle (void *);
00204 static void connect_time_expired (void *);
00205 #if 0
00206 static int  plogin (char *, char *, char **, int *);
00207 #endif
00208 static void plogout (void);
00209 static int  null_login (int);
00210 static int  get_pap_passwd (int, char *, char *);
00211 static int  have_pap_secret (void);
00212 static int  have_chap_secret (char *, char *, u32_t);
00213 static int  ip_addr_check (u32_t, struct wordlist *);
00214 
00215 #if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
00216 static int  scan_authfile (FILE *, char *, char *, char *,
00217              struct wordlist **, struct wordlist **,
00218              char *);
00219 static void free_wordlist (struct wordlist *);
00220 static void auth_script (char *);
00221 static void auth_script_done (void *);
00222 static void set_allowed_addrs (int unit, struct wordlist *addrs);
00223 static int  some_ip_ok (struct wordlist *);
00224 static int  setupapfile (char **);
00225 static int  privgroup (char **);
00226 static int  set_noauth_addr (char **);
00227 static void check_access (FILE *, char *);
00228 #endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
00229 
00230 #if 0 /* UNUSED */
00231 /*
00232  * Authentication-related options.
00233  */
00234 option_t auth_options[] = {
00235     { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap,
00236       "Require PAP authentication from peer", 1, &auth_required },
00237     { "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
00238       "Require PAP authentication from peer", 1, &auth_required },
00239     { "refuse-pap", o_bool, &refuse_pap,
00240       "Don't agree to auth to peer with PAP", 1 },
00241     { "-pap", o_bool, &refuse_pap,
00242       "Don't allow PAP authentication with peer", 1 },
00243     { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
00244       "Require CHAP authentication from peer", 1, &auth_required },
00245     { "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
00246       "Require CHAP authentication from peer", 1, &auth_required },
00247     { "refuse-chap", o_bool, &refuse_chap,
00248       "Don't agree to auth to peer with CHAP", 1 },
00249     { "-chap", o_bool, &refuse_chap,
00250       "Don't allow CHAP authentication with peer", 1 },
00251     { "name", o_string, our_name,
00252       "Set local name for authentication",
00253       OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN },
00254     { "user", o_string, user,
00255       "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN },
00256     { "usehostname", o_bool, &usehostname,
00257       "Must use hostname for authentication", 1 },
00258     { "remotename", o_string, remote_name,
00259       "Set remote name for authentication", OPT_STATIC,
00260       &explicit_remote, MAXNAMELEN },
00261     { "auth", o_bool, &auth_required,
00262       "Require authentication from peer", 1 },
00263     { "noauth", o_bool, &auth_required,
00264       "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip },
00265     {  "login", o_bool, &uselogin,
00266       "Use system password database for PAP", 1 },
00267     { "papcrypt", o_bool, &cryptpap,
00268       "PAP passwords are encrypted", 1 },
00269     { "+ua", o_special, (void *)setupapfile,
00270       "Get PAP user and password from file" },
00271     { "password", o_string, passwd,
00272       "Password for authenticating us to the peer", OPT_STATIC,
00273       NULL, MAXSECRETLEN },
00274     { "privgroup", o_special, (void *)privgroup,
00275       "Allow group members to use privileged options", OPT_PRIV },
00276     { "allow-ip", o_special, (void *)set_noauth_addr,
00277       "Set IP address(es) which can be used without authentication",
00278       OPT_PRIV },
00279     { NULL }
00280 };
00281 #endif /* UNUSED */
00282 #if 0 /* UNUSED */
00283 /*
00284  * setupapfile - specifies UPAP info for authenticating with peer.
00285  */
00286 static int
00287 setupapfile(char **argv)
00288 {
00289     FILE * ufile;
00290     int l;
00291 
00292     lcp_allowoptions[0].neg_upap = 1;
00293 
00294     /* open user info file */
00295     seteuid(getuid());
00296     ufile = fopen(*argv, "r");
00297     seteuid(0);
00298     if (ufile == NULL) {
00299       option_error("unable to open user login data file %s", *argv);
00300       return 0;
00301     }
00302     check_access(ufile, *argv);
00303 
00304     /* get username */
00305     if (fgets(user, MAXNAMELEN - 1, ufile) == NULL
00306         || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){
00307       option_error("unable to read user login data file %s", *argv);
00308       return 0;
00309     }
00310     fclose(ufile);
00311 
00312     /* get rid of newlines */
00313     l = strlen(user);
00314     if (l > 0 && user[l-1] == '\n')
00315       user[l-1] = 0;
00316     l = strlen(passwd);
00317     if (l > 0 && passwd[l-1] == '\n')
00318       passwd[l-1] = 0;
00319 
00320     return (1);
00321 }
00322 #endif /* UNUSED */
00323 
00324 #if 0 /* UNUSED */
00325 /*
00326  * privgroup - allow members of the group to have privileged access.
00327  */
00328 static int
00329 privgroup(char **argv)
00330 {
00331     struct group *g;
00332     int i;
00333 
00334     g = getgrnam(*argv);
00335     if (g == 0) {
00336       option_error("group %s is unknown", *argv);
00337       return 0;
00338     }
00339     for (i = 0; i < ngroups; ++i) {
00340       if (groups[i] == g->gr_gid) {
00341         privileged = 1;
00342         break;
00343       }
00344     }
00345     return 1;
00346 }
00347 #endif
00348 
00349 #if 0 /* UNUSED */
00350 /*
00351  * set_noauth_addr - set address(es) that can be used without authentication.
00352  * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets.
00353  */
00354 static int
00355 set_noauth_addr(char **argv)
00356 {
00357     char *addr = *argv;
00358     int l = strlen(addr);
00359     struct wordlist *wp;
00360 
00361     wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1);
00362     if (wp == NULL)
00363       novm("allow-ip argument");
00364     wp->word = (char *) (wp + 1);
00365     wp->next = noauth_addrs;
00366     BCOPY(addr, wp->word, l);
00367     noauth_addrs = wp;
00368     return 1;
00369 }
00370 #endif /* UNUSED */
00371 
00372 /*
00373  * An Open on LCP has requested a change from Dead to Establish phase.
00374  * Do what's necessary to bring the physical layer up.
00375  */
00376 void
00377 link_required(int unit)
00378 {
00379   LWIP_UNUSED_ARG(unit);
00380 
00381   AUTHDEBUG(LOG_INFO, ("link_required: %d\n", unit));
00382 }
00383 
00384 /*
00385  * LCP has terminated the link; go to the Dead phase and take the
00386  * physical layer down.
00387  */
00388 void
00389 link_terminated(int unit)
00390 {
00391   AUTHDEBUG(LOG_INFO, ("link_terminated: %d\n", unit));
00392   if (lcp_phase[unit] == PHASE_DEAD) {
00393     return;
00394   }
00395   if (logged_in) {
00396     plogout();
00397   }
00398   lcp_phase[unit] = PHASE_DEAD;
00399   AUTHDEBUG(LOG_NOTICE, ("Connection terminated.\n"));
00400   pppLinkTerminated(unit);
00401 }
00402 
00403 /*
00404  * LCP has gone down; it will either die or try to re-establish.
00405  */
00406 void
00407 link_down(int unit)
00408 {
00409   int i;
00410   struct protent *protp;
00411 
00412   AUTHDEBUG(LOG_INFO, ("link_down: %d\n", unit));
00413 
00414   if (did_authup) {
00415     /* XXX Do link down processing. */
00416     did_authup = 0;
00417   }
00418   for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
00419     if (!protp->enabled_flag) {
00420       continue;
00421     }
00422     if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) {
00423       (*protp->lowerdown)(unit);
00424     }
00425     if (protp->protocol < 0xC000 && protp->close != NULL) {
00426       (*protp->close)(unit, "LCP down");
00427     }
00428   }
00429   num_np_open = 0;  /* number of network protocols we have opened */
00430   num_np_up = 0;    /* Number of network protocols which have come up */
00431 
00432   if (lcp_phase[unit] != PHASE_DEAD) {
00433     lcp_phase[unit] = PHASE_TERMINATE;
00434   }
00435   pppLinkDown(unit);
00436 }
00437 
00438 /*
00439  * The link is established.
00440  * Proceed to the Dead, Authenticate or Network phase as appropriate.
00441  */
00442 void
00443 link_established(int unit)
00444 {
00445   int auth;
00446   int i;
00447   struct protent *protp;
00448   lcp_options *wo = &lcp_wantoptions[unit];
00449   lcp_options *go = &lcp_gotoptions[unit];
00450 #if PAP_SUPPORT || CHAP_SUPPORT
00451   lcp_options *ho = &lcp_hisoptions[unit];
00452 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
00453 
00454   AUTHDEBUG(LOG_INFO, ("link_established: unit %d; Lowering up all protocols...\n", unit));
00455   /*
00456    * Tell higher-level protocols that LCP is up.
00457    */
00458   for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
00459     if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) {
00460       (*protp->lowerup)(unit);
00461     }
00462   }
00463   if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {
00464     /*
00465      * We wanted the peer to authenticate itself, and it refused:
00466      * treat it as though it authenticated with PAP using a username
00467      * of "" and a password of "".  If that's not OK, boot it out.
00468      */
00469     if (!wo->neg_upap || !null_login(unit)) {
00470       AUTHDEBUG(LOG_WARNING, ("peer refused to authenticate\n"));
00471       lcp_close(unit, "peer refused to authenticate");
00472       return;
00473     }
00474   }
00475 
00476   lcp_phase[unit] = PHASE_AUTHENTICATE;
00477   auth = 0;
00478 #if CHAP_SUPPORT
00479   if (go->neg_chap) {
00480     ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);
00481     auth |= CHAP_PEER;
00482   } 
00483 #endif /* CHAP_SUPPORT */
00484 #if PAP_SUPPORT && CHAP_SUPPORT
00485   else
00486 #endif /* PAP_SUPPORT && CHAP_SUPPORT */
00487 #if PAP_SUPPORT
00488   if (go->neg_upap) {
00489     upap_authpeer(unit);
00490     auth |= PAP_PEER;
00491   }
00492 #endif /* PAP_SUPPORT */
00493 #if CHAP_SUPPORT
00494   if (ho->neg_chap) {
00495     ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);
00496     auth |= CHAP_WITHPEER;
00497   }
00498 #endif /* CHAP_SUPPORT */
00499 #if PAP_SUPPORT && CHAP_SUPPORT
00500   else
00501 #endif /* PAP_SUPPORT && CHAP_SUPPORT */
00502 #if PAP_SUPPORT
00503   if (ho->neg_upap) {
00504     if (ppp_settings.passwd[0] == 0) {
00505       passwd_from_file = 1;
00506       if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) {
00507         AUTHDEBUG(LOG_ERR, ("No secret found for PAP login\n"));
00508       }
00509     }
00510     upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);
00511     auth |= PAP_WITHPEER;
00512   }
00513 #endif /* PAP_SUPPORT */
00514   auth_pending[unit] = auth;
00515 
00516   if (!auth) {
00517     network_phase(unit);
00518   }
00519 }
00520 
00521 /*
00522  * Proceed to the network phase.
00523  */
00524 static void
00525 network_phase(int unit)
00526 {
00527   int i;
00528   struct protent *protp;
00529   lcp_options *go = &lcp_gotoptions[unit];
00530 
00531   /*
00532    * If the peer had to authenticate, run the auth-up script now.
00533    */
00534   if ((go->neg_chap || go->neg_upap) && !did_authup) {
00535     /* XXX Do setup for peer authentication. */
00536     did_authup = 1;
00537   }
00538 
00539 #if CBCP_SUPPORT
00540   /*
00541    * If we negotiated callback, do it now.
00542    */
00543   if (go->neg_cbcp) {
00544     lcp_phase[unit] = PHASE_CALLBACK;
00545     (*cbcp_protent.open)(unit);
00546     return;
00547   }
00548 #endif /* CBCP_SUPPORT */
00549 
00550   lcp_phase[unit] = PHASE_NETWORK;
00551   for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
00552     if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) {
00553       (*protp->open)(unit);
00554       if (protp->protocol != PPP_CCP) {
00555         ++num_np_open;
00556       }
00557     }
00558   }
00559 
00560   if (num_np_open == 0) {
00561     /* nothing to do */
00562     lcp_close(0, "No network protocols running");
00563   }
00564 }
00565 /* @todo: add void start_networks(void) here (pppd 2.3.11) */
00566 
00567 /*
00568  * The peer has failed to authenticate himself using `protocol'.
00569  */
00570 void
00571 auth_peer_fail(int unit, u16_t protocol)
00572 {
00573   LWIP_UNUSED_ARG(protocol);
00574 
00575   AUTHDEBUG(LOG_INFO, ("auth_peer_fail: %d proto=%X\n", unit, protocol));
00576   /*
00577    * Authentication failure: take the link down
00578    */
00579   lcp_close(unit, "Authentication failed");
00580 }
00581 
00582 
00583 #if PAP_SUPPORT || CHAP_SUPPORT
00584 /*
00585  * The peer has been successfully authenticated using `protocol'.
00586  */
00587 void
00588 auth_peer_success(int unit, u16_t protocol, char *name, int namelen)
00589 {
00590   int pbit;
00591 
00592   AUTHDEBUG(LOG_INFO, ("auth_peer_success: %d proto=%X\n", unit, protocol));
00593   switch (protocol) {
00594     case PPP_CHAP:
00595       pbit = CHAP_PEER;
00596       break;
00597     case PPP_PAP:
00598       pbit = PAP_PEER;
00599       break;
00600     default:
00601       AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol));
00602       return;
00603   }
00604 
00605   /*
00606    * Save the authenticated name of the peer for later.
00607    */
00608   if (namelen > (int)sizeof(peer_authname) - 1) {
00609     namelen = sizeof(peer_authname) - 1;
00610   }
00611   BCOPY(name, peer_authname, namelen);
00612   peer_authname[namelen] = 0;
00613   
00614   /*
00615    * If there is no more authentication still to be done,
00616    * proceed to the network (or callback) phase.
00617    */
00618   if ((auth_pending[unit] &= ~pbit) == 0) {
00619     network_phase(unit);
00620   }
00621 }
00622 
00623 /*
00624  * We have failed to authenticate ourselves to the peer using `protocol'.
00625  */
00626 void
00627 auth_withpeer_fail(int unit, u16_t protocol)
00628 {
00629   int errCode = PPPERR_AUTHFAIL;
00630 
00631   LWIP_UNUSED_ARG(protocol);
00632 
00633   AUTHDEBUG(LOG_INFO, ("auth_withpeer_fail: %d proto=%X\n", unit, protocol));
00634   if (passwd_from_file) {
00635     BZERO(ppp_settings.passwd, MAXSECRETLEN);
00636   }
00637 
00638   /*
00639    * We've failed to authenticate ourselves to our peer.
00640    * He'll probably take the link down, and there's not much
00641    * we can do except wait for that.
00642    */
00643   pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);
00644   lcp_close(unit, "Failed to authenticate ourselves to peer");
00645 }
00646 
00647 /*
00648  * We have successfully authenticated ourselves with the peer using `protocol'.
00649  */
00650 void
00651 auth_withpeer_success(int unit, u16_t protocol)
00652 {
00653   int pbit;
00654 
00655   AUTHDEBUG(LOG_INFO, ("auth_withpeer_success: %d proto=%X\n", unit, protocol));
00656   switch (protocol) {
00657     case PPP_CHAP:
00658       pbit = CHAP_WITHPEER;
00659       break;
00660     case PPP_PAP:
00661       if (passwd_from_file) {
00662         BZERO(ppp_settings.passwd, MAXSECRETLEN);
00663       }
00664       pbit = PAP_WITHPEER;
00665       break;
00666     default:
00667       AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol));
00668       pbit = 0;
00669   }
00670 
00671   /*
00672    * If there is no more authentication still being done,
00673    * proceed to the network (or callback) phase.
00674    */
00675   if ((auth_pending[unit] &= ~pbit) == 0) {
00676     network_phase(unit);
00677   }
00678 }
00679 #endif /* PAP_SUPPORT || CHAP_SUPPORT */
00680 
00681 
00682 /*
00683  * np_up - a network protocol has come up.
00684  */
00685 void
00686 np_up(int unit, u16_t proto)
00687 {
00688   LWIP_UNUSED_ARG(unit);
00689   LWIP_UNUSED_ARG(proto);
00690 
00691   AUTHDEBUG(LOG_INFO, ("np_up: %d proto=%X\n", unit, proto));
00692   if (num_np_up == 0) {
00693     AUTHDEBUG(LOG_INFO, ("np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));
00694     /*
00695      * At this point we consider that the link has come up successfully.
00696      */
00697     if (ppp_settings.idle_time_limit > 0) {
00698       TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);
00699     }
00700 
00701     /*
00702      * Set a timeout to close the connection once the maximum
00703      * connect time has expired.
00704      */
00705     if (ppp_settings.maxconnect > 0) {
00706       TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);
00707     }
00708   }
00709   ++num_np_up;
00710 }
00711 
00712 /*
00713  * np_down - a network protocol has gone down.
00714  */
00715 void
00716 np_down(int unit, u16_t proto)
00717 {
00718   LWIP_UNUSED_ARG(unit);
00719   LWIP_UNUSED_ARG(proto);
00720 
00721   AUTHDEBUG(LOG_INFO, ("np_down: %d proto=%X\n", unit, proto));
00722   if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {
00723     UNTIMEOUT(check_idle, NULL);
00724   }
00725 }
00726 
00727 /*
00728  * np_finished - a network protocol has finished using the link.
00729  */
00730 void
00731 np_finished(int unit, u16_t proto)
00732 {
00733   LWIP_UNUSED_ARG(unit);
00734   LWIP_UNUSED_ARG(proto);
00735 
00736   AUTHDEBUG(LOG_INFO, ("np_finished: %d proto=%X\n", unit, proto));
00737   if (--num_np_open <= 0) {
00738     /* no further use for the link: shut up shop. */
00739     lcp_close(0, "No network protocols running");
00740   }
00741 }
00742 
00743 /*
00744  * check_idle - check whether the link has been idle for long
00745  * enough that we can shut it down.
00746  */
00747 static void
00748 check_idle(void *arg)
00749 {
00750   struct ppp_idle idle;
00751   u_short itime;
00752   
00753   LWIP_UNUSED_ARG(arg);
00754   if (!get_idle_time(0, &idle)) {
00755     return;
00756   }
00757   itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);
00758   if (itime >= ppp_settings.idle_time_limit) {
00759     /* link is idle: shut it down. */
00760     AUTHDEBUG(LOG_INFO, ("Terminating connection due to lack of activity.\n"));
00761     lcp_close(0, "Link inactive");
00762   } else {
00763     TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);
00764   }
00765 }
00766 
00767 /*
00768  * connect_time_expired - log a message and close the connection.
00769  */
00770 static void
00771 connect_time_expired(void *arg)
00772 {
00773   LWIP_UNUSED_ARG(arg);
00774 
00775   AUTHDEBUG(LOG_INFO, ("Connect time expired\n"));
00776   lcp_close(0, "Connect time expired");   /* Close connection */
00777 }
00778 
00779 #if 0 /* UNUSED */
00780 /*
00781  * auth_check_options - called to check authentication options.
00782  */
00783 void
00784 auth_check_options(void)
00785 {
00786   lcp_options *wo = &lcp_wantoptions[0];
00787   int can_auth;
00788   ipcp_options *ipwo = &ipcp_wantoptions[0];
00789   u32_t remote;
00790 
00791   /* Default our_name to hostname, and user to our_name */
00792   if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) {
00793       strcpy(ppp_settings.our_name, ppp_settings.hostname);
00794   }
00795 
00796   if (ppp_settings.user[0] == 0) {
00797     strcpy(ppp_settings.user, ppp_settings.our_name);
00798   }
00799 
00800   /* If authentication is required, ask peer for CHAP or PAP. */
00801   if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {
00802     wo->neg_chap = 1;
00803     wo->neg_upap = 1;
00804   }
00805   
00806   /*
00807    * Check whether we have appropriate secrets to use
00808    * to authenticate the peer.
00809    */
00810   can_auth = wo->neg_upap && have_pap_secret();
00811   if (!can_auth && wo->neg_chap) {
00812     remote = ipwo->accept_remote? 0: ipwo->hisaddr;
00813     can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);
00814   }
00815 
00816   if (ppp_settings.auth_required && !can_auth) {
00817     ppp_panic("No auth secret");
00818   }
00819 }
00820 #endif /* UNUSED */
00821 
00822 /*
00823  * auth_reset - called when LCP is starting negotiations to recheck
00824  * authentication options, i.e. whether we have appropriate secrets
00825  * to use for authenticating ourselves and/or the peer.
00826  */
00827 void
00828 auth_reset(int unit)
00829 {
00830   lcp_options *go = &lcp_gotoptions[unit];
00831   lcp_options *ao = &lcp_allowoptions[0];
00832   ipcp_options *ipwo = &ipcp_wantoptions[0];
00833   u32_t remote;
00834 
00835   AUTHDEBUG(LOG_INFO, ("auth_reset: %d\n", unit));
00836   ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));
00837   ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/;
00838 
00839   if (go->neg_upap && !have_pap_secret()) {
00840     go->neg_upap = 0;
00841   }
00842   if (go->neg_chap) {
00843     remote = ipwo->accept_remote? 0: ipwo->hisaddr;
00844     if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) {
00845       go->neg_chap = 0;
00846     }
00847   }
00848 }
00849 
00850 #if PAP_SUPPORT
00851 /*
00852  * check_passwd - Check the user name and passwd against the PAP secrets
00853  * file.  If requested, also check against the system password database,
00854  * and login the user if OK.
00855  *
00856  * returns:
00857  *  UPAP_AUTHNAK: Authentication failed.
00858  *  UPAP_AUTHACK: Authentication succeeded.
00859  * In either case, msg points to an appropriate message.
00860  */
00861 u_char
00862 check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen)
00863 {
00864 #if 1 /* XXX Assume all entries OK. */
00865   LWIP_UNUSED_ARG(unit);
00866   LWIP_UNUSED_ARG(auser);
00867   LWIP_UNUSED_ARG(userlen);
00868   LWIP_UNUSED_ARG(apasswd);
00869   LWIP_UNUSED_ARG(passwdlen);
00870   LWIP_UNUSED_ARG(msglen);
00871   *msg = (char *) 0;
00872   return UPAP_AUTHACK;     /* XXX Assume all entries OK. */
00873 #else
00874   u_char ret = 0;
00875   struct wordlist *addrs = NULL;
00876   char passwd[256], user[256];
00877   char secret[MAXWORDLEN];
00878   static u_short attempts = 0;
00879   
00880   /*
00881    * Make copies of apasswd and auser, then null-terminate them.
00882    */
00883   BCOPY(apasswd, passwd, passwdlen);
00884   passwd[passwdlen] = '\0';
00885   BCOPY(auser, user, userlen);
00886   user[userlen] = '\0';
00887   *msg = (char *) 0;
00888 
00889   /* XXX Validate user name and password. */
00890   ret = UPAP_AUTHACK;     /* XXX Assume all entries OK. */
00891       
00892   if (ret == UPAP_AUTHNAK) {
00893     if (*msg == (char *) 0) {
00894       *msg = "Login incorrect";
00895     }
00896     *msglen = strlen(*msg);
00897     /*
00898      * Frustrate passwd stealer programs.
00899      * Allow 10 tries, but start backing off after 3 (stolen from login).
00900      * On 10'th, drop the connection.
00901      */
00902     if (attempts++ >= 10) {
00903       AUTHDEBUG(LOG_WARNING, ("%d LOGIN FAILURES BY %s\n", attempts, user));
00904       /*ppp_panic("Excess Bad Logins");*/
00905     }
00906     if (attempts > 3) {
00907       /* @todo: this was sleep(), i.e. seconds, not milliseconds
00908        * I don't think we really need this in lwIP - we would block tcpip_thread!
00909        */
00910       /*sys_msleep((attempts - 3) * 5);*/
00911     }
00912     if (addrs != NULL) {
00913       free_wordlist(addrs);
00914     }
00915   } else {
00916     attempts = 0; /* Reset count */
00917     if (*msg == (char *) 0) {
00918       *msg = "Login ok";
00919     }
00920     *msglen = strlen(*msg);
00921     set_allowed_addrs(unit, addrs);
00922   }
00923 
00924   BZERO(passwd, sizeof(passwd));
00925   BZERO(secret, sizeof(secret));
00926 
00927   return ret;
00928 #endif
00929 }
00930 #endif /* PAP_SUPPORT */
00931 
00932 #if 0 /* UNUSED */
00933 /*
00934  * This function is needed for PAM.
00935  */
00936 
00937 #ifdef USE_PAM
00938 
00939 /* lwip does not support PAM*/
00940 
00941 #endif  /* USE_PAM */
00942 
00943 #endif /* UNUSED */
00944 
00945 
00946 #if 0 /* UNUSED */
00947 /*
00948  * plogin - Check the user name and password against the system
00949  * password database, and login the user if OK.
00950  *
00951  * returns:
00952  *  UPAP_AUTHNAK: Login failed.
00953  *  UPAP_AUTHACK: Login succeeded.
00954  * In either case, msg points to an appropriate message.
00955  */
00956 static int
00957 plogin(char *user, char *passwd, char **msg, int *msglen)
00958 {
00959 
00960   LWIP_UNUSED_ARG(user);
00961   LWIP_UNUSED_ARG(passwd);
00962   LWIP_UNUSED_ARG(msg);
00963   LWIP_UNUSED_ARG(msglen);
00964 
00965 
00966  /* The new lines are here align the file when 
00967   * compared against the pppd 2.3.11 code */
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 
00979 
00980 
00981 
00982 
00983 
00984   /* XXX Fail until we decide that we want to support logins. */
00985   return (UPAP_AUTHNAK);
00986 }
00987 #endif
00988 
00989 
00990 
00991 /*
00992  * plogout - Logout the user.
00993  */
00994 static void
00995 plogout(void)
00996 {
00997   logged_in = 0;
00998 }
00999 
01000 /*
01001  * null_login - Check if a username of "" and a password of "" are
01002  * acceptable, and iff so, set the list of acceptable IP addresses
01003  * and return 1.
01004  */
01005 static int
01006 null_login(int unit)
01007 {
01008   LWIP_UNUSED_ARG(unit);
01009   /* XXX Fail until we decide that we want to support logins. */
01010   return 0;
01011 }
01012 
01013 
01014 /*
01015  * get_pap_passwd - get a password for authenticating ourselves with
01016  * our peer using PAP.  Returns 1 on success, 0 if no suitable password
01017  * could be found.
01018  */
01019 static int
01020 get_pap_passwd(int unit, char *user, char *passwd)
01021 {
01022   LWIP_UNUSED_ARG(unit);
01023 /* normally we would reject PAP if no password is provided,
01024    but this causes problems with some providers (like CHT in Taiwan)
01025    who incorrectly request PAP and expect a bogus/empty password, so
01026    always provide a default user/passwd of "none"/"none"
01027 
01028    @todo: This should be configured by the user, instead of being hardcoded here!
01029 */
01030   if(user) {
01031     strcpy(user, "none");
01032   }
01033   if(passwd) {
01034     strcpy(passwd, "none");
01035   }
01036   return 1;
01037 }
01038 
01039 /*
01040  * have_pap_secret - check whether we have a PAP file with any
01041  * secrets that we could possibly use for authenticating the peer.
01042  */
01043 static int
01044 have_pap_secret(void)
01045 {
01046   /* XXX Fail until we set up our passwords. */
01047   return 0;
01048 }
01049 
01050 /*
01051  * have_chap_secret - check whether we have a CHAP file with a
01052  * secret that we could possibly use for authenticating `client'
01053  * on `server'.  Either can be the null string, meaning we don't
01054  * know the identity yet.
01055  */
01056 static int
01057 have_chap_secret(char *client, char *server, u32_t remote)
01058 {
01059   LWIP_UNUSED_ARG(client);
01060   LWIP_UNUSED_ARG(server);
01061   LWIP_UNUSED_ARG(remote);
01062 
01063   /* XXX Fail until we set up our passwords. */
01064   return 0;
01065 }
01066 #if CHAP_SUPPORT
01067 
01068 /*
01069  * get_secret - open the CHAP secret file and return the secret
01070  * for authenticating the given client on the given server.
01071  * (We could be either client or server).
01072  */
01073 int
01074 get_secret(int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs)
01075 {
01076 #if 1
01077   int len;
01078   struct wordlist *addrs;
01079 
01080   LWIP_UNUSED_ARG(unit);
01081   LWIP_UNUSED_ARG(server);
01082   LWIP_UNUSED_ARG(save_addrs);
01083 
01084   addrs = NULL;
01085 
01086   if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
01087     return 0;
01088   }
01089 
01090   len = (int)strlen(ppp_settings.passwd);
01091   if (len > MAXSECRETLEN) {
01092     AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server));
01093     len = MAXSECRETLEN;
01094   }
01095 
01096   BCOPY(ppp_settings.passwd, secret, len);
01097   *secret_len = len;
01098 
01099   return 1;
01100 #else
01101   int ret = 0, len;
01102   struct wordlist *addrs;
01103   char secbuf[MAXWORDLEN];
01104   
01105   addrs = NULL;
01106   secbuf[0] = 0;
01107 
01108   /* XXX Find secret. */
01109   if (ret < 0) {
01110     return 0;
01111   }
01112 
01113   if (save_addrs) {
01114     set_allowed_addrs(unit, addrs);
01115   }
01116 
01117   len = strlen(secbuf);
01118   if (len > MAXSECRETLEN) {
01119     AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server));
01120     len = MAXSECRETLEN;
01121   }
01122 
01123   BCOPY(secbuf, secret, len);
01124   BZERO(secbuf, sizeof(secbuf));
01125   *secret_len = len;
01126 
01127   return 1;
01128 #endif
01129 }
01130 #endif /* CHAP_SUPPORT */
01131 
01132 
01133 #if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
01134 /*
01135  * set_allowed_addrs() - set the list of allowed addresses.
01136  */
01137 static void
01138 set_allowed_addrs(int unit, struct wordlist *addrs)
01139 {
01140   if (addresses[unit] != NULL) {
01141     free_wordlist(addresses[unit]);
01142   }
01143   addresses[unit] = addrs;
01144 
01145 #if 0
01146   /*
01147    * If there's only one authorized address we might as well
01148    * ask our peer for that one right away
01149    */
01150   if (addrs != NULL && addrs->next == NULL) {
01151     char *p = addrs->word;
01152     struct ipcp_options *wo = &ipcp_wantoptions[unit];
01153     u32_t a;
01154     struct hostent *hp;
01155     
01156     if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) {
01157       hp = gethostbyname(p);
01158       if (hp != NULL && hp->h_addrtype == AF_INET) {
01159         a = *(u32_t *)hp->h_addr;
01160       } else {
01161         a = inet_addr(p);
01162       }
01163       if (a != (u32_t) -1) {
01164         wo->hisaddr = a;
01165       }
01166     }
01167   }
01168 #endif
01169 }
01170 #endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
01171 
01172 /*
01173  * auth_ip_addr - check whether the peer is authorized to use
01174  * a given IP address.  Returns 1 if authorized, 0 otherwise.
01175  */
01176 int
01177 auth_ip_addr(int unit, u32_t addr)
01178 {
01179   return ip_addr_check(addr, addresses[unit]);
01180 }
01181 
01182 static int /* @todo: integrate this funtion into auth_ip_addr()*/
01183 ip_addr_check(u32_t addr, struct wordlist *addrs)
01184 {
01185   /* don't allow loopback or multicast address */
01186   if (bad_ip_adrs(addr)) {
01187     return 0;
01188   }
01189 
01190   if (addrs == NULL) {
01191     return !ppp_settings.auth_required; /* no addresses authorized */
01192   }
01193 
01194   /* XXX All other addresses allowed. */
01195   return 1;
01196 }
01197 
01198 /*
01199  * bad_ip_adrs - return 1 if the IP address is one we don't want
01200  * to use, such as an address in the loopback net or a multicast address.
01201  * addr is in network byte order.
01202  */
01203 int
01204 bad_ip_adrs(u32_t addr)
01205 {
01206   addr = ntohl(addr);
01207   return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
01208       || IN_MULTICAST(addr) || IN_BADCLASS(addr);
01209 }
01210 
01211 #if 0 /* UNUSED */ /* PAP_SUPPORT || CHAP_SUPPORT */
01212 /*
01213  * some_ip_ok - check a wordlist to see if it authorizes any
01214  * IP address(es).
01215  */
01216 static int
01217 some_ip_ok(struct wordlist *addrs)
01218 {
01219     for (; addrs != 0; addrs = addrs->next) {
01220       if (addrs->word[0] == '-')
01221         break;
01222       if (addrs->word[0] != '!')
01223         return 1; /* some IP address is allowed */
01224     }
01225     return 0;
01226 }
01227 
01228 /*
01229  * check_access - complain if a secret file has too-liberal permissions.
01230  */
01231 static void
01232 check_access(FILE *f, char *filename)
01233 {
01234     struct stat sbuf;
01235 
01236     if (fstat(fileno(f), &sbuf) < 0) {
01237       warn("cannot stat secret file %s: %m", filename);
01238     } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
01239       warn("Warning - secret file %s has world and/or group access",
01240             filename);
01241     }
01242 }
01243 
01244 
01245 /*
01246  * scan_authfile - Scan an authorization file for a secret suitable
01247  * for authenticating `client' on `server'.  The return value is -1
01248  * if no secret is found, otherwise >= 0.  The return value has
01249  * NONWILD_CLIENT set if the secret didn't have "*" for the client, and
01250  * NONWILD_SERVER set if the secret didn't have "*" for the server.
01251  * Any following words on the line up to a "--" (i.e. address authorization
01252  * info) are placed in a wordlist and returned in *addrs.  Any
01253  * following words (extra options) are placed in a wordlist and
01254  * returned in *opts.
01255  * We assume secret is NULL or points to MAXWORDLEN bytes of space.
01256  */
01257 static int
01258 scan_authfile(FILE *f, char *client, char *server, char *secret, struct wordlist **addrs, struct wordlist **opts, char *filename)
01259 {
01260   /* We do not (currently) need this in lwip  */
01261   return 0; /* dummy */
01262 }
01263 /*
01264  * free_wordlist - release memory allocated for a wordlist.
01265  */
01266 static void
01267 free_wordlist(struct wordlist *wp)
01268 {
01269   struct wordlist *next;
01270 
01271   while (wp != NULL) {
01272     next = wp->next;
01273     free(wp);
01274     wp = next;
01275   }
01276 }
01277 
01278 /*
01279  * auth_script_done - called when the auth-up or auth-down script
01280  * has finished.
01281  */
01282 static void
01283 auth_script_done(void *arg)
01284 {
01285     auth_script_pid = 0;
01286     switch (auth_script_state) {
01287     case s_up:
01288       if (auth_state == s_down) {
01289         auth_script_state = s_down;
01290         auth_script(_PATH_AUTHDOWN);
01291       }
01292       break;
01293     case s_down:
01294       if (auth_state == s_up) {
01295         auth_script_state = s_up;
01296         auth_script(_PATH_AUTHUP);
01297       }
01298       break;
01299     }
01300 }
01301 
01302 /*
01303  * auth_script - execute a script with arguments
01304  * interface-name peer-name real-user tty speed
01305  */
01306 static void
01307 auth_script(char *script)
01308 {
01309     char strspeed[32];
01310     struct passwd *pw;
01311     char struid[32];
01312     char *user_name;
01313     char *argv[8];
01314 
01315     if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL)
01316       user_name = pw->pw_name;
01317     else {
01318       slprintf(struid, sizeof(struid), "%d", getuid());
01319       user_name = struid;
01320     }
01321     slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);
01322 
01323     argv[0] = script;
01324     argv[1] = ifname;
01325     argv[2] = peer_authname;
01326     argv[3] = user_name;
01327     argv[4] = devnam;
01328     argv[5] = strspeed;
01329     argv[6] = NULL;
01330 
01331     auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL);
01332 }
01333 #endif  /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
01334 #endif /* PPP_SUPPORT */

Generated on Mon May 28 2012 04:24:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.