Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
auth.c
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 * XXX Warning: the unit number indicates the interface which is 00639 * not necessarily the PPP connection. It works here as long 00640 * as we are only supporting PPP interfaces. 00641 */ 00642 /* @todo: Remove pppIOCtl, it is not used anywhere else. 00643 Instead, directly set errCode. */ 00644 pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode); 00645 00646 /* 00647 * We've failed to authenticate ourselves to our peer. 00648 * He'll probably take the link down, and there's not much 00649 * we can do except wait for that. 00650 */ 00651 } 00652 00653 /* 00654 * We have successfully authenticated ourselves with the peer using `protocol'. 00655 */ 00656 void 00657 auth_withpeer_success(int unit, u16_t protocol) 00658 { 00659 int pbit; 00660 00661 AUTHDEBUG(LOG_INFO, ("auth_withpeer_success: %d proto=%X\n", unit, protocol)); 00662 switch (protocol) { 00663 case PPP_CHAP: 00664 pbit = CHAP_WITHPEER; 00665 break; 00666 case PPP_PAP: 00667 if (passwd_from_file) { 00668 BZERO(ppp_settings.passwd, MAXSECRETLEN); 00669 } 00670 pbit = PAP_WITHPEER; 00671 break; 00672 default: 00673 AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol)); 00674 pbit = 0; 00675 } 00676 00677 /* 00678 * If there is no more authentication still being done, 00679 * proceed to the network (or callback) phase. 00680 */ 00681 if ((auth_pending[unit] &= ~pbit) == 0) { 00682 network_phase(unit); 00683 } 00684 } 00685 #endif /* PAP_SUPPORT || CHAP_SUPPORT */ 00686 00687 00688 /* 00689 * np_up - a network protocol has come up. 00690 */ 00691 void 00692 np_up(int unit, u16_t proto) 00693 { 00694 LWIP_UNUSED_ARG(unit); 00695 LWIP_UNUSED_ARG(proto); 00696 00697 AUTHDEBUG(LOG_INFO, ("np_up: %d proto=%X\n", unit, proto)); 00698 if (num_np_up == 0) { 00699 AUTHDEBUG(LOG_INFO, ("np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit)); 00700 /* 00701 * At this point we consider that the link has come up successfully. 00702 */ 00703 if (ppp_settings.idle_time_limit > 0) { 00704 TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit); 00705 } 00706 00707 /* 00708 * Set a timeout to close the connection once the maximum 00709 * connect time has expired. 00710 */ 00711 if (ppp_settings.maxconnect > 0) { 00712 TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect); 00713 } 00714 } 00715 ++num_np_up; 00716 } 00717 00718 /* 00719 * np_down - a network protocol has gone down. 00720 */ 00721 void 00722 np_down(int unit, u16_t proto) 00723 { 00724 LWIP_UNUSED_ARG(unit); 00725 LWIP_UNUSED_ARG(proto); 00726 00727 AUTHDEBUG(LOG_INFO, ("np_down: %d proto=%X\n", unit, proto)); 00728 if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) { 00729 UNTIMEOUT(check_idle, NULL); 00730 } 00731 } 00732 00733 /* 00734 * np_finished - a network protocol has finished using the link. 00735 */ 00736 void 00737 np_finished(int unit, u16_t proto) 00738 { 00739 LWIP_UNUSED_ARG(unit); 00740 LWIP_UNUSED_ARG(proto); 00741 00742 AUTHDEBUG(LOG_INFO, ("np_finished: %d proto=%X\n", unit, proto)); 00743 if (--num_np_open <= 0) { 00744 /* no further use for the link: shut up shop. */ 00745 lcp_close(0, "No network protocols running"); 00746 } 00747 } 00748 00749 /* 00750 * check_idle - check whether the link has been idle for long 00751 * enough that we can shut it down. 00752 */ 00753 static void 00754 check_idle(void *arg) 00755 { 00756 struct ppp_idle idle; 00757 u_short itime; 00758 00759 LWIP_UNUSED_ARG(arg); 00760 if (!get_idle_time(0, &idle)) { 00761 return; 00762 } 00763 itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); 00764 if (itime >= ppp_settings.idle_time_limit) { 00765 /* link is idle: shut it down. */ 00766 AUTHDEBUG(LOG_INFO, ("Terminating connection due to lack of activity.\n")); 00767 lcp_close(0, "Link inactive"); 00768 } else { 00769 TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime); 00770 } 00771 } 00772 00773 /* 00774 * connect_time_expired - log a message and close the connection. 00775 */ 00776 static void 00777 connect_time_expired(void *arg) 00778 { 00779 LWIP_UNUSED_ARG(arg); 00780 00781 AUTHDEBUG(LOG_INFO, ("Connect time expired\n")); 00782 lcp_close(0, "Connect time expired"); /* Close connection */ 00783 } 00784 00785 #if 0 /* UNUSED */ 00786 /* 00787 * auth_check_options - called to check authentication options. 00788 */ 00789 void 00790 auth_check_options(void) 00791 { 00792 lcp_options *wo = &lcp_wantoptions[0]; 00793 int can_auth; 00794 ipcp_options *ipwo = &ipcp_wantoptions[0]; 00795 u32_t remote; 00796 00797 /* Default our_name to hostname, and user to our_name */ 00798 if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) { 00799 strcpy(ppp_settings.our_name, ppp_settings.hostname); 00800 } 00801 00802 if (ppp_settings.user[0] == 0) { 00803 strcpy(ppp_settings.user, ppp_settings.our_name); 00804 } 00805 00806 /* If authentication is required, ask peer for CHAP or PAP. */ 00807 if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) { 00808 wo->neg_chap = 1; 00809 wo->neg_upap = 1; 00810 } 00811 00812 /* 00813 * Check whether we have appropriate secrets to use 00814 * to authenticate the peer. 00815 */ 00816 can_auth = wo->neg_upap && have_pap_secret(); 00817 if (!can_auth && wo->neg_chap) { 00818 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 00819 can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote); 00820 } 00821 00822 if (ppp_settings.auth_required && !can_auth) { 00823 ppp_panic("No auth secret"); 00824 } 00825 } 00826 #endif /* UNUSED */ 00827 00828 /* 00829 * auth_reset - called when LCP is starting negotiations to recheck 00830 * authentication options, i.e. whether we have appropriate secrets 00831 * to use for authenticating ourselves and/or the peer. 00832 */ 00833 void 00834 auth_reset(int unit) 00835 { 00836 lcp_options *go = &lcp_gotoptions[unit]; 00837 lcp_options *ao = &lcp_allowoptions[0]; 00838 ipcp_options *ipwo = &ipcp_wantoptions[0]; 00839 u32_t remote; 00840 00841 AUTHDEBUG(LOG_INFO, ("auth_reset: %d\n", unit)); 00842 ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL)); 00843 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)*/; 00844 00845 if (go->neg_upap && !have_pap_secret()) { 00846 go->neg_upap = 0; 00847 } 00848 if (go->neg_chap) { 00849 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 00850 if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) { 00851 go->neg_chap = 0; 00852 } 00853 } 00854 } 00855 00856 #if PAP_SUPPORT 00857 /* 00858 * check_passwd - Check the user name and passwd against the PAP secrets 00859 * file. If requested, also check against the system password database, 00860 * and login the user if OK. 00861 * 00862 * returns: 00863 * UPAP_AUTHNAK: Authentication failed. 00864 * UPAP_AUTHACK: Authentication succeeded. 00865 * In either case, msg points to an appropriate message. 00866 */ 00867 u_char 00868 check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen) 00869 { 00870 #if 1 /* XXX Assume all entries OK. */ 00871 LWIP_UNUSED_ARG(unit); 00872 LWIP_UNUSED_ARG(auser); 00873 LWIP_UNUSED_ARG(userlen); 00874 LWIP_UNUSED_ARG(apasswd); 00875 LWIP_UNUSED_ARG(passwdlen); 00876 LWIP_UNUSED_ARG(msglen); 00877 *msg = (char *) 0; 00878 return UPAP_AUTHACK; /* XXX Assume all entries OK. */ 00879 #else 00880 u_char ret = 0; 00881 struct wordlist *addrs = NULL; 00882 char passwd[256], user[256]; 00883 char secret[MAXWORDLEN]; 00884 static u_short attempts = 0; 00885 00886 /* 00887 * Make copies of apasswd and auser, then null-terminate them. 00888 */ 00889 BCOPY(apasswd, passwd, passwdlen); 00890 passwd[passwdlen] = '\0'; 00891 BCOPY(auser, user, userlen); 00892 user[userlen] = '\0'; 00893 *msg = (char *) 0; 00894 00895 /* XXX Validate user name and password. */ 00896 ret = UPAP_AUTHACK; /* XXX Assume all entries OK. */ 00897 00898 if (ret == UPAP_AUTHNAK) { 00899 if (*msg == (char *) 0) { 00900 *msg = "Login incorrect"; 00901 } 00902 *msglen = strlen(*msg); 00903 /* 00904 * Frustrate passwd stealer programs. 00905 * Allow 10 tries, but start backing off after 3 (stolen from login). 00906 * On 10'th, drop the connection. 00907 */ 00908 if (attempts++ >= 10) { 00909 AUTHDEBUG(LOG_WARNING, ("%d LOGIN FAILURES BY %s\n", attempts, user)); 00910 /*ppp_panic("Excess Bad Logins");*/ 00911 } 00912 if (attempts > 3) { 00913 /* @todo: this was sleep(), i.e. seconds, not milliseconds 00914 * I don't think we really need this in lwIP - we would block tcpip_thread! 00915 */ 00916 /*sys_msleep((attempts - 3) * 5);*/ 00917 } 00918 if (addrs != NULL) { 00919 free_wordlist(addrs); 00920 } 00921 } else { 00922 attempts = 0; /* Reset count */ 00923 if (*msg == (char *) 0) { 00924 *msg = "Login ok"; 00925 } 00926 *msglen = strlen(*msg); 00927 set_allowed_addrs(unit, addrs); 00928 } 00929 00930 BZERO(passwd, sizeof(passwd)); 00931 BZERO(secret, sizeof(secret)); 00932 00933 return ret; 00934 #endif 00935 } 00936 #endif /* PAP_SUPPORT */ 00937 00938 #if 0 /* UNUSED */ 00939 /* 00940 * This function is needed for PAM. 00941 */ 00942 00943 #ifdef USE_PAM 00944 00945 /* lwip does not support PAM*/ 00946 00947 #endif /* USE_PAM */ 00948 00949 #endif /* UNUSED */ 00950 00951 00952 #if 0 /* UNUSED */ 00953 /* 00954 * plogin - Check the user name and password against the system 00955 * password database, and login the user if OK. 00956 * 00957 * returns: 00958 * UPAP_AUTHNAK: Login failed. 00959 * UPAP_AUTHACK: Login succeeded. 00960 * In either case, msg points to an appropriate message. 00961 */ 00962 static int 00963 plogin(char *user, char *passwd, char **msg, int *msglen) 00964 { 00965 00966 LWIP_UNUSED_ARG(user); 00967 LWIP_UNUSED_ARG(passwd); 00968 LWIP_UNUSED_ARG(msg); 00969 LWIP_UNUSED_ARG(msglen); 00970 00971 00972 /* The new lines are here align the file when 00973 * compared against the pppd 2.3.11 code */ 00974 00975 00976 00977 00978 00979 00980 00981 00982 00983 00984 00985 00986 00987 00988 00989 00990 /* XXX Fail until we decide that we want to support logins. */ 00991 return (UPAP_AUTHNAK); 00992 } 00993 #endif 00994 00995 00996 00997 /* 00998 * plogout - Logout the user. 00999 */ 01000 static void 01001 plogout(void) 01002 { 01003 logged_in = 0; 01004 } 01005 01006 /* 01007 * null_login - Check if a username of "" and a password of "" are 01008 * acceptable, and iff so, set the list of acceptable IP addresses 01009 * and return 1. 01010 */ 01011 static int 01012 null_login(int unit) 01013 { 01014 LWIP_UNUSED_ARG(unit); 01015 /* XXX Fail until we decide that we want to support logins. */ 01016 return 0; 01017 } 01018 01019 01020 /* 01021 * get_pap_passwd - get a password for authenticating ourselves with 01022 * our peer using PAP. Returns 1 on success, 0 if no suitable password 01023 * could be found. 01024 */ 01025 static int 01026 get_pap_passwd(int unit, char *user, char *passwd) 01027 { 01028 LWIP_UNUSED_ARG(unit); 01029 /* normally we would reject PAP if no password is provided, 01030 but this causes problems with some providers (like CHT in Taiwan) 01031 who incorrectly request PAP and expect a bogus/empty password, so 01032 always provide a default user/passwd of "none"/"none" 01033 01034 @todo: This should be configured by the user, instead of being hardcoded here! 01035 */ 01036 if(user) { 01037 strcpy(user, "none"); 01038 } 01039 if(passwd) { 01040 strcpy(passwd, "none"); 01041 } 01042 return 1; 01043 } 01044 01045 /* 01046 * have_pap_secret - check whether we have a PAP file with any 01047 * secrets that we could possibly use for authenticating the peer. 01048 */ 01049 static int 01050 have_pap_secret(void) 01051 { 01052 /* XXX Fail until we set up our passwords. */ 01053 return 0; 01054 } 01055 01056 /* 01057 * have_chap_secret - check whether we have a CHAP file with a 01058 * secret that we could possibly use for authenticating `client' 01059 * on `server'. Either can be the null string, meaning we don't 01060 * know the identity yet. 01061 */ 01062 static int 01063 have_chap_secret(char *client, char *server, u32_t remote) 01064 { 01065 LWIP_UNUSED_ARG(client); 01066 LWIP_UNUSED_ARG(server); 01067 LWIP_UNUSED_ARG(remote); 01068 01069 /* XXX Fail until we set up our passwords. */ 01070 return 0; 01071 } 01072 #if CHAP_SUPPORT 01073 01074 /* 01075 * get_secret - open the CHAP secret file and return the secret 01076 * for authenticating the given client on the given server. 01077 * (We could be either client or server). 01078 */ 01079 int 01080 get_secret(int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs) 01081 { 01082 #if 1 01083 int len; 01084 struct wordlist *addrs; 01085 01086 LWIP_UNUSED_ARG(unit); 01087 LWIP_UNUSED_ARG(server); 01088 LWIP_UNUSED_ARG(save_addrs); 01089 01090 addrs = NULL; 01091 01092 if(!client || !client[0] || strcmp(client, ppp_settings.user)) { 01093 return 0; 01094 } 01095 01096 len = (int)strlen(ppp_settings.passwd); 01097 if (len > MAXSECRETLEN) { 01098 AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); 01099 len = MAXSECRETLEN; 01100 } 01101 01102 BCOPY(ppp_settings.passwd, secret, len); 01103 *secret_len = len; 01104 01105 return 1; 01106 #else 01107 int ret = 0, len; 01108 struct wordlist *addrs; 01109 char secbuf[MAXWORDLEN]; 01110 01111 addrs = NULL; 01112 secbuf[0] = 0; 01113 01114 /* XXX Find secret. */ 01115 if (ret < 0) { 01116 return 0; 01117 } 01118 01119 if (save_addrs) { 01120 set_allowed_addrs(unit, addrs); 01121 } 01122 01123 len = strlen(secbuf); 01124 if (len > MAXSECRETLEN) { 01125 AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); 01126 len = MAXSECRETLEN; 01127 } 01128 01129 BCOPY(secbuf, secret, len); 01130 BZERO(secbuf, sizeof(secbuf)); 01131 *secret_len = len; 01132 01133 return 1; 01134 #endif 01135 } 01136 #endif /* CHAP_SUPPORT */ 01137 01138 01139 #if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ 01140 /* 01141 * set_allowed_addrs() - set the list of allowed addresses. 01142 */ 01143 static void 01144 set_allowed_addrs(int unit, struct wordlist *addrs) 01145 { 01146 if (addresses[unit] != NULL) { 01147 free_wordlist(addresses[unit]); 01148 } 01149 addresses[unit] = addrs; 01150 01151 #if 0 01152 /* 01153 * If there's only one authorized address we might as well 01154 * ask our peer for that one right away 01155 */ 01156 if (addrs != NULL && addrs->next == NULL) { 01157 char *p = addrs->word; 01158 struct ipcp_options *wo = &ipcp_wantoptions[unit]; 01159 u32_t a; 01160 struct hostent *hp; 01161 01162 if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) { 01163 hp = gethostbyname(p); 01164 if (hp != NULL && hp->h_addrtype == AF_INET) { 01165 a = *(u32_t *)hp->h_addr; 01166 } else { 01167 a = inet_addr(p); 01168 } 01169 if (a != (u32_t) -1) { 01170 wo->hisaddr = a; 01171 } 01172 } 01173 } 01174 #endif 01175 } 01176 #endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ 01177 01178 /* 01179 * auth_ip_addr - check whether the peer is authorized to use 01180 * a given IP address. Returns 1 if authorized, 0 otherwise. 01181 */ 01182 int 01183 auth_ip_addr(int unit, u32_t addr) 01184 { 01185 return ip_addr_check(addr, addresses[unit]); 01186 } 01187 01188 static int /* @todo: integrate this funtion into auth_ip_addr()*/ 01189 ip_addr_check(u32_t addr, struct wordlist *addrs) 01190 { 01191 /* don't allow loopback or multicast address */ 01192 if (bad_ip_adrs(addr)) { 01193 return 0; 01194 } 01195 01196 if (addrs == NULL) { 01197 return !ppp_settings.auth_required; /* no addresses authorized */ 01198 } 01199 01200 /* XXX All other addresses allowed. */ 01201 return 1; 01202 } 01203 01204 /* 01205 * bad_ip_adrs - return 1 if the IP address is one we don't want 01206 * to use, such as an address in the loopback net or a multicast address. 01207 * addr is in network byte order. 01208 */ 01209 int 01210 bad_ip_adrs(u32_t addr) 01211 { 01212 addr = ntohl(addr); 01213 return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET 01214 || IN_MULTICAST(addr) || IN_BADCLASS(addr); 01215 } 01216 01217 #if 0 /* UNUSED */ /* PAP_SUPPORT || CHAP_SUPPORT */ 01218 /* 01219 * some_ip_ok - check a wordlist to see if it authorizes any 01220 * IP address(es). 01221 */ 01222 static int 01223 some_ip_ok(struct wordlist *addrs) 01224 { 01225 for (; addrs != 0; addrs = addrs->next) { 01226 if (addrs->word[0] == '-') 01227 break; 01228 if (addrs->word[0] != '!') 01229 return 1; /* some IP address is allowed */ 01230 } 01231 return 0; 01232 } 01233 01234 /* 01235 * check_access - complain if a secret file has too-liberal permissions. 01236 */ 01237 static void 01238 check_access(FILE *f, char *filename) 01239 { 01240 struct stat sbuf; 01241 01242 if (fstat(fileno(f), &sbuf) < 0) { 01243 warn("cannot stat secret file %s: %m", filename); 01244 } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { 01245 warn("Warning - secret file %s has world and/or group access", 01246 filename); 01247 } 01248 } 01249 01250 01251 /* 01252 * scan_authfile - Scan an authorization file for a secret suitable 01253 * for authenticating `client' on `server'. The return value is -1 01254 * if no secret is found, otherwise >= 0. The return value has 01255 * NONWILD_CLIENT set if the secret didn't have "*" for the client, and 01256 * NONWILD_SERVER set if the secret didn't have "*" for the server. 01257 * Any following words on the line up to a "--" (i.e. address authorization 01258 * info) are placed in a wordlist and returned in *addrs. Any 01259 * following words (extra options) are placed in a wordlist and 01260 * returned in *opts. 01261 * We assume secret is NULL or points to MAXWORDLEN bytes of space. 01262 */ 01263 static int 01264 scan_authfile(FILE *f, char *client, char *server, char *secret, struct wordlist **addrs, struct wordlist **opts, char *filename) 01265 { 01266 /* We do not (currently) need this in lwip */ 01267 return 0; /* dummy */ 01268 } 01269 /* 01270 * free_wordlist - release memory allocated for a wordlist. 01271 */ 01272 static void 01273 free_wordlist(struct wordlist *wp) 01274 { 01275 struct wordlist *next; 01276 01277 while (wp != NULL) { 01278 next = wp->next; 01279 free(wp); 01280 wp = next; 01281 } 01282 } 01283 01284 /* 01285 * auth_script_done - called when the auth-up or auth-down script 01286 * has finished. 01287 */ 01288 static void 01289 auth_script_done(void *arg) 01290 { 01291 auth_script_pid = 0; 01292 switch (auth_script_state) { 01293 case s_up: 01294 if (auth_state == s_down) { 01295 auth_script_state = s_down; 01296 auth_script(_PATH_AUTHDOWN); 01297 } 01298 break; 01299 case s_down: 01300 if (auth_state == s_up) { 01301 auth_script_state = s_up; 01302 auth_script(_PATH_AUTHUP); 01303 } 01304 break; 01305 } 01306 } 01307 01308 /* 01309 * auth_script - execute a script with arguments 01310 * interface-name peer-name real-user tty speed 01311 */ 01312 static void 01313 auth_script(char *script) 01314 { 01315 char strspeed[32]; 01316 struct passwd *pw; 01317 char struid[32]; 01318 char *user_name; 01319 char *argv[8]; 01320 01321 if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) 01322 user_name = pw->pw_name; 01323 else { 01324 slprintf(struid, sizeof(struid), "%d", getuid()); 01325 user_name = struid; 01326 } 01327 slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); 01328 01329 argv[0] = script; 01330 argv[1] = ifname; 01331 argv[2] = peer_authname; 01332 argv[3] = user_name; 01333 argv[4] = devnam; 01334 argv[5] = strspeed; 01335 argv[6] = NULL; 01336 01337 auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL); 01338 } 01339 #endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ 01340 #endif /* PPP_SUPPORT */
Generated on Tue Jul 12 2022 11:17:50 by
