📄 auth.c
字号:
upap_authwithpeer(unit, user, passwd); auth |= PAP_WITHPEER; } auth_pending[unit] = auth; if (!auth) network_phase(unit);}/* * Proceed to the network phase. */static voidnetwork_phase(unit) int unit;{ lcp_options *go = &lcp_gotoptions[unit]; /* * If the peer had to authenticate, run the auth-up script now. */ if (go->neg_chap || go->neg_upap) { auth_state = s_up; if (auth_script_state == s_down && auth_script_pid == 0) { auth_script_state = s_up; auth_script(_PATH_AUTHUP); } }#ifdef CBCP_SUPPORT /* * If we negotiated callback, do it now. */ if (go->neg_cbcp) { new_phase(PHASE_CALLBACK); (*cbcp_protent.open)(unit); return; }#endif /* * Process extra options from the secrets file */ if (extra_options) { options_from_list(extra_options, 1); free_wordlist(extra_options); extra_options = 0; } start_networks();}voidstart_networks(){ int i; struct protent *protp; new_phase(PHASE_NETWORK);#ifdef HAVE_MULTILINK if (multilink) { if (mp_join_bundle()) { if (updetach && !nodetach) detach(); return; } }#endif /* HAVE_MULTILINK */#ifdef PPP_FILTER if (!demand) set_filters(&pass_filter, &active_filter);#endif for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) { (*protp->open)(0); if (protp->protocol != PPP_CCP) ++num_np_open; } if (num_np_open == 0) /* nothing to do */ lcp_close(0, "No network protocols running");}/* * The peer has failed to authenticate himself using `protocol'. */voidauth_peer_fail(unit, protocol) int unit, protocol;{ /* * Authentication failure: take the link down */ lcp_close(unit, "Authentication failed"); status = EXIT_PEER_AUTH_FAILED;}/* * The peer has been successfully authenticated using `protocol'. */voidauth_peer_success(unit, protocol, name, namelen) int unit, protocol; char *name; int namelen;{ int bit; switch (protocol) { case PPP_CHAP: bit = CHAP_PEER; break; case PPP_PAP: bit = PAP_PEER; break; default: warn("auth_peer_success: unknown protocol %x", protocol); return; } /* * Save the authenticated name of the peer for later. */ if (namelen > sizeof(peer_authname) - 1) namelen = sizeof(peer_authname) - 1; BCOPY(name, peer_authname, namelen); peer_authname[namelen] = 0; script_setenv("PEERNAME", peer_authname, 0); /* * If there is no more authentication still to be done, * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) network_phase(unit);}/* * We have failed to authenticate ourselves to the peer using `protocol'. */voidauth_withpeer_fail(unit, protocol) int unit, protocol;{ if (passwd_from_file) BZERO(passwd, MAXSECRETLEN); /* * We've failed to authenticate ourselves to our peer. * Some servers keep sending CHAP challenges, but there * is no point in persisting without any way to get updated * authentication secrets. */ lcp_close(unit, "Failed to authenticate ourselves to peer"); status = EXIT_AUTH_TOPEER_FAILED;}/* * We have successfully authenticated ourselves with the peer using `protocol'. */voidauth_withpeer_success(unit, protocol) int unit, protocol;{ int bit; switch (protocol) { case PPP_CHAP: bit = CHAP_WITHPEER; break; case PPP_PAP: if (passwd_from_file) BZERO(passwd, MAXSECRETLEN); bit = PAP_WITHPEER; break; default: warn("auth_withpeer_success: unknown protocol %x", protocol); bit = 0; } /* * If there is no more authentication still being done, * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) network_phase(unit);}/* * np_up - a network protocol has come up. */voidnp_up(unit, proto) int unit, proto;{ int tlim; if (num_np_up == 0) { /* * At this point we consider that the link has come up successfully. */ status = EXIT_OK; unsuccess = 0; new_phase(PHASE_RUNNING); if (idle_time_hook != 0) tlim = (*idle_time_hook)(NULL); else tlim = idle_time_limit; if (tlim > 0) TIMEOUT(check_idle, NULL, tlim); /* * Set a timeout to close the connection once the maximum * connect time has expired. */ if (maxconnect > 0) TIMEOUT(connect_time_expired, 0, maxconnect); /* * Detach now, if the updetach option was given. */ if (updetach && !nodetach) detach(); } ++num_np_up;}/* * np_down - a network protocol has gone down. */voidnp_down(unit, proto) int unit, proto;{ if (--num_np_up == 0) { UNTIMEOUT(check_idle, NULL); new_phase(PHASE_NETWORK); }}/* * np_finished - a network protocol has finished using the link. */voidnp_finished(unit, proto) int unit, proto;{ if (--num_np_open <= 0) { /* no further use for the link: shut up shop. */ lcp_close(0, "No network protocols running"); }}/* * check_idle - check whether the link has been idle for long * enough that we can shut it down. */static voidcheck_idle(arg) void *arg;{ struct ppp_idle idle; time_t itime; int tlim; if (!get_idle_time(0, &idle)) return; if (idle_time_hook != 0) { tlim = idle_time_hook(&idle); } else { itime = MIN(idle.xmit_idle, idle.recv_idle); tlim = idle_time_limit - itime; } if (tlim <= 0) { /* link is idle: shut it down. */ notice("Terminating connection due to lack of activity."); lcp_close(0, "Link inactive"); need_holdoff = 0; status = EXIT_IDLE_TIMEOUT; } else { TIMEOUT(check_idle, NULL, tlim); }}/* * connect_time_expired - log a message and close the connection. */static voidconnect_time_expired(arg) void *arg;{ info("Connect time expired"); lcp_close(0, "Connect time expired"); /* Close connection */ status = EXIT_CONNECT_TIME;}/* * auth_check_options - called to check authentication options. */voidauth_check_options(){ lcp_options *wo = &lcp_wantoptions[0]; int can_auth; int lacks_ip; /* Default our_name to hostname, and user to our_name */ if (our_name[0] == 0 || usehostname) strlcpy(our_name, hostname, sizeof(our_name)); if (user[0] == 0) strlcpy(user, our_name, sizeof(user)); /* * If we have a default route, require the peer to authenticate * unless the noauth option was given or the real user is root. */ if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { auth_required = 1; default_auth = 1; } /* If authentication is required, ask peer for CHAP or PAP. */ if (auth_required) { allow_any_ip = 0; if (!wo->neg_chap && !wo->neg_upap) { wo->neg_chap = 1; wo->neg_upap = 1; } } else { wo->neg_chap = 0; wo->neg_upap = 0; } /* * Check whether we have appropriate secrets to use * to authenticate the peer. */ lacks_ip = 0; can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); if (!can_auth && wo->neg_chap) { can_auth = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, &lacks_ip); } if (auth_required && !can_auth && noauth_addrs == NULL) { if (default_auth) { option_error("By default the remote system is required to authenticate itself"); option_error("(because this system has a default route to the internet)"); } else if (explicit_remote) option_error("The remote system (%s) is required to authenticate itself", remote_name); else option_error("The remote system is required to authenticate itself"); option_error("but I couldn't find any suitable secret (password) for it to use to do so."); if (lacks_ip) option_error("(None of the available passwords would let it use an IP address.)"); exit(1); }}/* * auth_reset - called when LCP is starting negotiations to recheck * authentication options, i.e. whether we have appropriate secrets * to use for authenticating ourselves and/or the peer. */voidauth_reset(unit) int unit;{ lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ao = &lcp_allowoptions[0]; ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); ao->neg_chap = !refuse_chap && (passwd[0] != 0 || have_chap_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) go->neg_upap = 0; if (go->neg_chap) { if (!have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL)) go->neg_chap = 0; }}/* * check_passwd - Check the user name and passwd against the PAP secrets * file. If requested, also check against the system password database, * and login the user if OK. * * returns: * UPAP_AUTHNAK: Authentication failed. * UPAP_AUTHACK: Authentication succeeded. * In either case, msg points to an appropriate message. */intcheck_passwd(unit, auser, userlen, apasswd, passwdlen, msg) int unit; char *auser; int userlen; char *apasswd; int passwdlen; char **msg;{ int ret; char *filename; FILE *f; struct wordlist *addrs = NULL, *opts = NULL; char passwd[256], user[256]; char secret[MAXWORDLEN]; static int attempts = 0; /* * Make copies of apasswd and auser, then null-terminate them. * If there are unprintable characters in the password, make * them visible. */ slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd); slprintf(user, sizeof(user), "%.*v", userlen, auser); *msg = ""; /* * Check if a plugin wants to handle this. */ if (pap_auth_hook) { ret = (*pap_auth_hook)(user, passwd, msg, &addrs, &opts); if (ret >= 0) { if (ret) set_allowed_addrs(unit, addrs, opts); BZERO(passwd, sizeof(passwd)); if (addrs != 0) free_wordlist(addrs); return ret? UPAP_AUTHACK: UPAP_AUTHNAK; } } /* * Open the file of pap secrets and scan for a suitable secret * for authenticating this user. */ filename = _PATH_UPAPFILE; addrs = opts = NULL; ret = UPAP_AUTHNAK; f = fopen(filename, "r"); if (f == NULL) { error("Can't open PAP password file %s: %m", filename); } else { check_access(f, filename); if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename) < 0) { warn("no PAP secret found for %s", user); } else { /* * If the secret is "@login", it means to check * the password against the login database. */ int login_secret = strcmp(secret, "@login") == 0; ret = UPAP_AUTHACK; if (uselogin || login_secret) { /* login option or secret is @login */ ret = plogin(user, passwd, msg); if (ret == UPAP_AUTHNAK) warn("PAP login failure for %s", user); else used_login = 1; } if (secret[0] != 0 && !login_secret) { /* password given in pap-secrets - must match */ if ((cryptpap || strcmp(passwd, secret) != 0) && strcmp(crypt(passwd, secret), secret) != 0) { ret = UPAP_AUTHNAK; warn("PAP authentication failure for %s", user); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -