📄 auth.c
字号:
/*
* 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 > 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.
*/
int check_passwd(
int unit,
char *auser,
int userlen,
char *apasswd,
int passwdlen,
char **msg,
int *msglen
)
{
#if 1
*msg = (char *) 0;
return UPAP_AUTHACK; /* XXX Assume all entries OK. */
#else
int 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. */
if (ret == UPAP_AUTHNAK) {
if (*msg == (char *) 0)
*msg = "Login incorrect";
*msglen = strlen(*msg);
/*
* Frustrate passwd stealer programs.
* Allow 10 tries, but start backing off after 3 (stolen from login).
* On 10'th, drop the connection.
*/
if (attempts++ >= 10) {
AUTHDEBUG((LOG_WARNING, "%d LOGIN FAILURES BY %s\n", attempts, user));
/*ppp_panic("Excess Bad Logins");*/
}
if (attempts > 3) {
sys_msleep((attempts - 3) * 5);
}
if (addrs != NULL) {
free_wordlist(addrs);
}
} else {
attempts = 0; /* Reset count */
if (*msg == (char *) 0)
*msg = "Login ok";
*msglen = strlen(*msg);
set_allowed_addrs(unit, addrs);
}
BZERO(passwd, sizeof(passwd));
BZERO(secret, sizeof(secret));
return ret;
#endif
}
#endif
/*
* auth_ip_addr - check whether the peer is authorized to use
* a given IP address. Returns 1 if authorized, 0 otherwise.
*/
int auth_ip_addr(int unit, u32_t addr)
{
return ip_addr_check(addr, addresses[unit]);
}
/*
* bad_ip_adrs - return 1 if the IP address is one we don't want
* to use, such as an address in the loopback net or a multicast address.
* addr is in network byte order.
*/
int bad_ip_adrs(u32_t addr)
{
addr = ntohl(addr);
return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
|| IN_MULTICAST(addr) || IN_BADCLASS(addr);
}
#if CHAP_SUPPORT > 0
/*
* get_secret - open the CHAP secret file and return the secret
* for authenticating the given client on the given server.
* (We could be either client or server).
*/
int get_secret(
int unit,
char *client,
char *server,
char *secret,
int *secret_len,
int save_addrs
)
{
#if 1
int len;
struct wordlist *addrs;
addrs = NULL;
if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
return 0;
}
len = strlen(ppp_settings.passwd);
if (len > MAXSECRETLEN) {
AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
len = MAXSECRETLEN;
}
BCOPY(ppp_settings.passwd, secret, len);
*secret_len = len;
return 1;
#else
int ret = 0, len;
struct wordlist *addrs;
char secbuf[MAXWORDLEN];
addrs = NULL;
secbuf[0] = 0;
/* XXX Find secret. */
if (ret < 0)
return 0;
if (save_addrs)
set_allowed_addrs(unit, addrs);
len = strlen(secbuf);
if (len > MAXSECRETLEN) {
AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server));
len = MAXSECRETLEN;
}
BCOPY(secbuf, secret, len);
BZERO(secbuf, sizeof(secbuf));
*secret_len = len;
return 1;
#endif
}
#endif
#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
/**********************************/
/*** LOCAL FUNCTION DEFINITIONS ***/
/**********************************/
/*
* 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 > 0
/*
* If we negotiated callback, do it now.
*/
if (go->neg_cbcp) {
lcp_phase[unit] = PHASE_CALLBACK;
(*cbcp_protent.open)(unit);
return;
}
#endif
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");
}
/*
* 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;
(void)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)
{
(void)arg;
AUTHDEBUG((LOG_INFO, "Connect time expired\n"));
lcp_close(0, "Connect time expired"); /* Close connection */
}
#if 0
/*
* login - Check the user name and password against the system
* password database, and login the user if OK.
*
* returns:
* UPAP_AUTHNAK: Login failed.
* UPAP_AUTHACK: Login succeeded.
* In either case, msg points to an appropriate message.
*/
static int login(char *user, char *passwd, char **msg, int *msglen)
{
/* XXX Fail until we decide that we want to support logins. */
return (UPAP_AUTHNAK);
}
#endif
/*
* logout - Logout the user.
*/
static void logout(void)
{
logged_in = 0;
}
/*
* null_login - Check if a username of "" and a password of "" are
* acceptable, and iff so, set the list of acceptable IP addresses
* and return 1.
*/
static int null_login(int unit)
{
(void)unit;
/* XXX Fail until we decide that we want to support logins. */
return 0;
}
/*
* get_pap_passwd - get a password for authenticating ourselves with
* our peer using PAP. Returns 1 on success, 0 if no suitable password
* could be found.
*/
static int get_pap_passwd(int unit, char *user, char *passwd)
{
/* normally we would reject PAP if no password is provided,
but this causes problems with some providers (like CHT in Taiwan)
who incorrectly request PAP and expect a bogus/empty password, so
always provide a default user/passwd of "none"/"none"
*/
if(user)
strcpy(user, "none");
if(passwd)
strcpy(passwd, "none");
return 1;
}
/*
* have_pap_secret - check whether we have a PAP file with any
* secrets that we could possibly use for authenticating the peer.
*/
static int have_pap_secret(void)
{
/* XXX Fail until we set up our passwords. */
return 0;
}
/*
* have_chap_secret - check whether we have a CHAP file with a
* secret that we could possibly use for authenticating `client'
* on `server'. Either can be the null string, meaning we don't
* know the identity yet.
*/
static int have_chap_secret(char *client, char *server, u32_t remote)
{
(void)client;
(void)server;
(void)remote;
/* XXX Fail until we set up our passwords. */
return 0;
}
#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT > 0 */
/*
* set_allowed_addrs() - set the list of allowed addresses.
*/
static void set_allowed_addrs(int unit, struct wordlist *addrs)
{
if (addresses[unit] != NULL)
free_wordlist(addresses[unit]);
addresses[unit] = addrs;
#if 0
/*
* If there's only one authorized address we might as well
* ask our peer for that one right away
*/
if (addrs != NULL && addrs->next == NULL) {
char *p = addrs->word;
struct ipcp_options *wo = &ipcp_wantoptions[unit];
u32_t a;
struct hostent *hp;
if (wo->hisaddr == 0 && *p != '!' && *p != '-'
&& strchr(p, '/') == NULL) {
hp = gethostbyname(p);
if (hp != NULL && hp->h_addrtype == AF_INET)
a = *(u32_t *)hp->h_addr;
else
a = inet_addr(p);
if (a != (u32_t) -1)
wo->hisaddr = a;
}
}
#endif
}
#endif
static int ip_addr_check(u32_t addr, struct wordlist *addrs)
{
/* don't allow loopback or multicast address */
if (bad_ip_adrs(addr))
return 0;
if (addrs == NULL)
return !ppp_settings.auth_required; /* no addresses authorized */
/* XXX All other addresses allowed. */
return 1;
}
#if 0 /* PAP_SUPPORT > 0 || CHAP_SUPPORT */
/*
* free_wordlist - release memory allocated for a wordlist.
*/
static void free_wordlist(struct wordlist *wp)
{
struct wordlist *next;
while (wp != NULL) {
next = wp->next;
free(wp);
wp = next;
}
}
#endif
#endif /* PPP_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -