📄 auth.c
字号:
bit = 0;
}
/*
* If we have overridden addresses based on auth info
* then set that information now before continuing.
*/
auth_set_ip_addr(unit);
/*
* 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.
*/
void
np_up(unit, proto)
int unit, proto;
{
if (num_np_up == 0) {
/*
* At this point we consider that the link has come up successfully.
*/
need_holdoff = 0;
if (idle_time_limit > 0)
TIMEOUT(check_idle, NULL, idle_time_limit);
/*
* Set a timeout to close the connection once the maximum
* connect time has expired.
*/
if (maxconnect > 0)
TIMEOUT(connect_time_expired, 0, maxconnect);
}
++num_np_up;
}
/*
* np_down - a network protocol has gone down.
*/
void
np_down(unit, proto)
int unit, proto;
{
if (--num_np_up == 0 && idle_time_limit > 0) {
UNTIMEOUT(check_idle, NULL);
}
}
/*
* np_finished - a network protocol has finished using the link.
*/
void
np_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 void
check_idle(arg)
void *arg;
{
struct ppp_idle idle;
time_t itime;
if (!get_idle_time(0, &idle))
return;
itime = MIN(idle.xmit_idle, idle.recv_idle);
if (itime >= idle_time_limit) {
/* link is idle: shut it down. */
syslog(LOG_INFO, "Terminating connection due to lack of activity.");
lcp_close(0, "Link inactive");
} else {
TIMEOUT(check_idle, NULL, idle_time_limit - itime);
}
}
/*
* connect_time_expired - log a message and close the connection.
*/
static void
connect_time_expired(arg)
void *arg;
{
syslog(LOG_INFO, "Connect time expired");
lcp_close(0, "Connect time expired"); /* Close connection */
}
/*
* auth_check_options - called to check authentication options.
*/
void
auth_check_options()
{
lcp_options *wo = &lcp_wantoptions[0];
int can_auth;
ipcp_options *ipwo = &ipcp_wantoptions[0];
u_int32_t remote;
/* Default our_name to hostname, and user to our_name */
if (our_name[0] == 0 || usehostname)
strcpy(our_name, cyg_ppp_hostname);
if (user[0] == 0)
strcpy(user, our_name);
/* If authentication is required, ask peer for CHAP or PAP. */
if (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 && (uselogin || have_pap_secret());
if (!can_auth && wo->neg_chap) {
remote = ipwo->accept_remote? 0: ipwo->hisaddr;
can_auth = have_chap_secret(remote_name, our_name, remote);
}
if (auth_required && !can_auth) {
option_error("peer authentication required but no suitable secret(s) found\n");
if (remote_name[0] == 0)
option_error("for authenticating any peer to us (%s)\n", our_name);
else
option_error("for authenticating peer %s to us (%s)\n",
remote_name, our_name);
exit(1);
}
/*
* Check whether the user tried to override certain values
* set by root.
*/
if (!auth_required && auth_req_info.priv > 0) {
if (!default_device && devnam_info.priv == 0) {
option_error("can't override device name when noauth option used");
exit(1);
}
if ((connector != NULL && connector_info.priv == 0)
|| (disconnector != NULL && disconnector_info.priv == 0)
|| (welcomer != NULL && welcomer_info.priv == 0)) {
option_error("can't override connect, disconnect or welcome");
option_error("option values when noauth option used");
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.
*/
void
auth_reset(unit)
int unit;
{
lcp_options *go = &lcp_gotoptions[unit];
lcp_options *ao = &lcp_allowoptions[0];
ipcp_options *ipwo = &ipcp_wantoptions[0];
u_int32_t remote;
ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
ao->neg_chap = !refuse_chap
&& have_chap_secret(user, remote_name, (u_int32_t)0);
if (go->neg_upap && !uselogin && !have_pap_secret())
go->neg_upap = 0;
if (go->neg_chap) {
remote = ipwo->accept_remote? 0: ipwo->hisaddr;
if (!have_chap_secret(remote_name, our_name, remote))
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.
*/
int
check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
int unit;
char *auser;
int userlen;
char *apasswd;
int passwdlen;
char **msg;
int *msglen;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
return 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(unit)
int unit;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
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(passwd)
char *passwd;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
return 0;
}
/*
* 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()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
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(client, server, remote)
char *client;
char *server;
u_int32_t remote;
{
// db_printf("%s(%s,%s,%d) called\n", __PRETTY_FUNCTION__,client,server,remote);
return 1;
}
/*
* 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(unit, client, server, secret, secret_len, save_addrs)
int unit;
char *client;
char *server;
char *secret;
int *secret_len;
int save_addrs;
{
db_printf("%s(%d,%s,%s,%08x,%d,%d) called\n", __PRETTY_FUNCTION__,
unit, client, server, secret, secret_len, save_addrs);
// We use the PAP password as the CHAP secret also.
strncpy( secret, passwd, MAXNAMELEN );
*secret_len = strlen(secret);
return 1;
}
static void
auth_set_ip_addr(unit)
int unit;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}
/*
* 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(unit, addr)
int unit;
u_int32_t addr;
{
return ip_addr_check(addr, addresses[unit]);
}
static int
ip_addr_check(addr, addrs)
u_int32_t addr;
struct wordlist *addrs;
{
int x, y;
// u_int32_t a, mask, ah;
u_int32_t a = -1, mask;
int accept;
char *ptr_word, *ptr_mask;
// struct hostent *hp;
// struct netent *np;
/* don't allow loopback or multicast address */
if (bad_ip_adrs(addr))
return 0;
if (addrs == NULL)
return !auth_required; /* no addresses authorized */
x = y = 0;
for (; addrs != NULL; addrs = addrs->next) {
y++;
/* "-" means no addresses authorized, "*" means any address allowed */
ptr_word = addrs->word;
if (strcmp(ptr_word, "-") == 0)
break;
if (strcmp(ptr_word, "*") == 0)
return 1;
/*
* A colon in the string means that we wish to force a specific
* local:remote address, but we ignore these for now.
*/
if (strchr(addrs->word, ':') != NULL)
x++;
else {
accept = 1;
if (*ptr_word == '!') {
accept = 0;
++ptr_word;
}
mask = ~ (u_int32_t) 0;
ptr_mask = strchr (ptr_word, '/');
if (ptr_mask != NULL) {
int bit_count;
bit_count = (int) strtol (ptr_mask+1, (char **) 0, 10);
if (bit_count <= 0 || bit_count > 32) {
syslog (LOG_WARNING,
"invalid address length %s in auth. address list",
ptr_mask);
continue;
}
*ptr_mask = '\0';
mask <<= 32 - bit_count;
}
#ifndef __ECOS
hp = gethostbyname(ptr_word);
if (hp != NULL && hp->h_addrtype == AF_INET) {
a = *(u_int32_t *)hp->h_addr;
} else {
np = getnetbyname (ptr_word);
if (np != NULL && np->n_addrtype == AF_INET) {
a = htonl (*(u_int32_t *)np->n_net);
if (ptr_mask == NULL) {
/* calculate appropriate mask for net */
ah = ntohl(a);
if (IN_CLASSA(ah))
mask = IN_CLASSA_NET;
else if (IN_CLASSB(ah))
mask = IN_CLASSB_NET;
else if (IN_CLASSC(ah))
mask = IN_CLASSC_NET;
}
} else {
a = inet_addr (ptr_word);
}
}
#endif
if (ptr_mask != NULL)
*ptr_mask = '/';
if (a == (u_int32_t)-1L)
syslog (LOG_WARNING,
"unknown host %s in auth. address list",
addrs->word);
else
/* Here a and addr are in network byte order,
and mask is in host order. */
if (((addr ^ a) & htonl(mask)) == 0)
return accept;
} /* else */
}
return x == y; /* not in list => can't have it */
}
/*
* 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(addr)
u_int32_t addr;
{
addr = ntohl(addr);
return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
|| IN_MULTICAST(addr) || IN_BADCLASS(addr);
}
/*
* check_access - complain if a secret file has too-liberal permissions.
*/
void
check_access(f, filename)
FILE *f;
char *filename;
{
struct stat sbuf;
if (fstat(fileno(f), &sbuf) < 0) {
syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename);
} else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", filename);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -