📄 auth.c
字号:
int i;
struct protent *protp;
lcp_options *wo = &lcp_wantoptions[unit];
lcp_options *go = &lcp_gotoptions[unit];
#if PAP_SUPPORT || CHAP_SUPPORT
lcp_options *ho = &lcp_hisoptions[unit];
#endif /* PAP_SUPPORT || CHAP_SUPPORT */
AUTHDEBUG(LOG_INFO, ("link_established: unit %d; Lowering up all protocols...\n", unit));
/*
* Tell higher-level protocols that LCP is up.
*/
for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) {
(*protp->lowerup)(unit);
}
}
if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {
/*
* We wanted the peer to authenticate itself, and it refused:
* treat it as though it authenticated with PAP using a username
* of "" and a password of "". If that's not OK, boot it out.
*/
if (!wo->neg_upap || !null_login(unit)) {
AUTHDEBUG(LOG_WARNING, ("peer refused to authenticate\n"));
lcp_close(unit, "peer refused to authenticate");
return;
}
}
lcp_phase[unit] = PHASE_AUTHENTICATE;
auth = 0;
#if CHAP_SUPPORT
if (go->neg_chap) {
ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);
auth |= CHAP_PEER;
}
#endif /* CHAP_SUPPORT */
#if PAP_SUPPORT && CHAP_SUPPORT
else
#endif /* PAP_SUPPORT && CHAP_SUPPORT */
#if PAP_SUPPORT
if (go->neg_upap) {
upap_authpeer(unit);
auth |= PAP_PEER;
}
#endif /* PAP_SUPPORT */
#if CHAP_SUPPORT
if (ho->neg_chap) {
ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);
auth |= CHAP_WITHPEER;
}
#endif /* CHAP_SUPPORT */
#if PAP_SUPPORT && CHAP_SUPPORT
else
#endif /* PAP_SUPPORT && CHAP_SUPPORT */
#if PAP_SUPPORT
if (ho->neg_upap) {
if (ppp_settings.passwd[0] == 0) {
passwd_from_file = 1;
if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) {
AUTHDEBUG(LOG_ERR, ("No secret found for PAP login\n"));
}
}
upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);
auth |= PAP_WITHPEER;
}
#endif /* PAP_SUPPORT */
auth_pending[unit] = auth;
if (!auth) {
network_phase(unit);
}
}
/*
* Proceed to the network phase.
*/
static void
network_phase(int unit)
{
int i;
struct protent *protp;
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) && !did_authup) {
/* XXX Do setup for peer authentication. */
did_authup = 1;
}
#if CBCP_SUPPORT
/*
* If we negotiated callback, do it now.
*/
if (go->neg_cbcp) {
lcp_phase[unit] = PHASE_CALLBACK;
(*cbcp_protent.open)(unit);
return;
}
#endif /* CBCP_SUPPORT */
lcp_phase[unit] = PHASE_NETWORK;
for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) {
(*protp->open)(unit);
if (protp->protocol != PPP_CCP) {
++num_np_open;
}
}
}
if (num_np_open == 0) {
/* nothing to do */
lcp_close(0, "No network protocols running");
}
}
/* @todo: add void start_networks(void) here (pppd 2.3.11) */
/*
* The peer has failed to authenticate himself using `protocol'.
*/
void
auth_peer_fail(int unit, u16_t protocol)
{
LWIP_UNUSED_ARG(protocol);
AUTHDEBUG(LOG_INFO, ("auth_peer_fail: %d proto=%X\n", unit, protocol));
/*
* Authentication failure: take the link down
*/
lcp_close(unit, "Authentication failed");
}
#if PAP_SUPPORT || CHAP_SUPPORT
/*
* The peer has been successfully authenticated using `protocol'.
*/
void
auth_peer_success(int unit, u16_t protocol, char *name, int namelen)
{
int pbit;
AUTHDEBUG(LOG_INFO, ("auth_peer_success: %d proto=%X\n", unit, protocol));
switch (protocol) {
case PPP_CHAP:
pbit = CHAP_PEER;
break;
case PPP_PAP:
pbit = PAP_PEER;
break;
default:
AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol));
return;
}
/*
* Save the authenticated name of the peer for later.
*/
if (namelen > (int)sizeof(peer_authname) - 1) {
namelen = sizeof(peer_authname) - 1;
}
BCOPY(name, peer_authname, namelen);
peer_authname[namelen] = 0;
/*
* If there is no more authentication still to be done,
* proceed to the network (or callback) phase.
*/
if ((auth_pending[unit] &= ~pbit) == 0) {
network_phase(unit);
}
}
/*
* We have failed to authenticate ourselves to the peer using `protocol'.
*/
void
auth_withpeer_fail(int unit, u16_t protocol)
{
int errCode = PPPERR_AUTHFAIL;
LWIP_UNUSED_ARG(protocol);
AUTHDEBUG(LOG_INFO, ("auth_withpeer_fail: %d proto=%X\n", unit, protocol));
if (passwd_from_file) {
BZERO(ppp_settings.passwd, MAXSECRETLEN);
}
/*
* We've failed to authenticate ourselves to our peer.
* He'll probably take the link down, and there's not much
* we can do except wait for that.
*/
pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);
lcp_close(unit, "Failed to authenticate ourselves to peer");
}
/*
* We have successfully authenticated ourselves with the peer using `protocol'.
*/
void
auth_withpeer_success(int unit, u16_t protocol)
{
int pbit;
AUTHDEBUG(LOG_INFO, ("auth_withpeer_success: %d proto=%X\n", unit, protocol));
switch (protocol) {
case PPP_CHAP:
pbit = CHAP_WITHPEER;
break;
case PPP_PAP:
if (passwd_from_file) {
BZERO(ppp_settings.passwd, MAXSECRETLEN);
}
pbit = PAP_WITHPEER;
break;
default:
AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol));
pbit = 0;
}
/*
* If there is no more authentication still being done,
* proceed to the network (or callback) phase.
*/
if ((auth_pending[unit] &= ~pbit) == 0) {
network_phase(unit);
}
}
#endif /* PAP_SUPPORT || CHAP_SUPPORT */
/*
* np_up - a network protocol has come up.
*/
void
np_up(int unit, u16_t proto)
{
LWIP_UNUSED_ARG(unit);
LWIP_UNUSED_ARG(proto);
AUTHDEBUG(LOG_INFO, ("np_up: %d proto=%X\n", unit, proto));
if (num_np_up == 0) {
AUTHDEBUG(LOG_INFO, ("np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));
/*
* At this point we consider that the link has come up successfully.
*/
if (ppp_settings.idle_time_limit > 0) {
TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);
}
/*
* Set a timeout to close the connection once the maximum
* connect time has expired.
*/
if (ppp_settings.maxconnect > 0) {
TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);
}
}
++num_np_up;
}
/*
* np_down - a network protocol has gone down.
*/
void
np_down(int unit, u16_t proto)
{
LWIP_UNUSED_ARG(unit);
LWIP_UNUSED_ARG(proto);
AUTHDEBUG(LOG_INFO, ("np_down: %d proto=%X\n", unit, proto));
if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {
UNTIMEOUT(check_idle, NULL);
}
}
/*
* np_finished - a network protocol has finished using the link.
*/
void
np_finished(int unit, u16_t proto)
{
LWIP_UNUSED_ARG(unit);
LWIP_UNUSED_ARG(proto);
AUTHDEBUG(LOG_INFO, ("np_finished: %d proto=%X\n", 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 void
check_idle(void *arg)
{
struct ppp_idle idle;
u_short itime;
LWIP_UNUSED_ARG(arg);
if (!get_idle_time(0, &idle)) {
return;
}
itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);
if (itime >= ppp_settings.idle_time_limit) {
/* link is idle: shut it down. */
AUTHDEBUG(LOG_INFO, ("Terminating connection due to lack of activity.\n"));
lcp_close(0, "Link inactive");
} else {
TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);
}
}
/*
* connect_time_expired - log a message and close the connection.
*/
static void
connect_time_expired(void *arg)
{
LWIP_UNUSED_ARG(arg);
AUTHDEBUG(LOG_INFO, ("Connect time expired\n"));
lcp_close(0, "Connect time expired"); /* Close connection */
}
#if 0 /* UNUSED */
/*
* auth_check_options - called to check authentication options.
*/
void
auth_check_options(void)
{
lcp_options *wo = &lcp_wantoptions[0];
int can_auth;
ipcp_options *ipwo = &ipcp_wantoptions[0];
u32_t remote;
/* Default our_name to hostname, and user to our_name */
if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) {
strcpy(ppp_settings.our_name, ppp_settings.hostname);
}
if (ppp_settings.user[0] == 0) {
strcpy(ppp_settings.user, ppp_settings.our_name);
}
/* If authentication is required, ask peer for CHAP or PAP. */
if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {
wo->neg_chap = 1;
wo->neg_upap = 1;
}
/*
* Check whether we have appropriate secrets to use
* to authenticate the peer.
*/
can_auth = wo->neg_upap && have_pap_secret();
if (!can_auth && wo->neg_chap) {
remote = ipwo->accept_remote? 0: ipwo->hisaddr;
can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);
}
if (ppp_settings.auth_required && !can_auth) {
ppp_panic("No auth secret");
}
}
#endif /* UNUSED */
/*
* 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.
*/
void
auth_reset(int unit)
{
lcp_options *go = &lcp_gotoptions[unit];
lcp_options *ao = &lcp_allowoptions[0];
ipcp_options *ipwo = &ipcp_wantoptions[0];
u32_t remote;
AUTHDEBUG(LOG_INFO, ("auth_reset: %d\n", unit));
ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));
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)*/;
if (go->neg_upap && !have_pap_secret()) {
go->neg_upap = 0;
}
if (go->neg_chap) {
remote = ipwo->accept_remote? 0: ipwo->hisaddr;
if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) {
go->neg_chap = 0;
}
}
}
#if PAP_SUPPORT
/*
* 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.
*/
u_char
check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen)
{
#if 1 /* XXX Assume all entries OK. */
LWIP_UNUSED_ARG(unit);
LWIP_UNUSED_ARG(auser);
LWIP_UNUSED_ARG(userlen);
LWIP_UNUSED_ARG(apasswd);
LWIP_UNUSED_ARG(passwdlen);
LWIP_UNUSED_ARG(msglen);
*msg = (char *) 0;
return UPAP_AUTHACK; /* XXX Assume all entries OK. */
#else
u_char ret = 0;
struct wordlist *addrs = NULL;
char passwd[256], user[256];
char secret[MAXWORDLEN];
static u_short attempts = 0;
/*
* Make copies of apasswd and auser, then null-terminate them.
*/
BCOPY(apasswd, passwd, passwdlen);
passwd[passwdlen] = '\0';
BCOPY(auser, user, userlen);
user[userlen] = '\0';
*msg = (char *) 0;
/* XXX Validate user name and password. */
ret = UPAP_AUTHACK; /* XXX Assume all entries OK. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -