3653271054
libskey. (such as wu-ftp and xdm). Editted skey so it matches the standard /usr/include way.
178 lines
4.0 KiB
C
178 lines
4.0 KiB
C
/* Portions taken from the skey distribution on Oct 21 1993 */
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <string.h>
|
|
#include <netdb.h>
|
|
#include <arpa/inet.h>
|
|
#include <stdio.h>
|
|
#include <pwd.h>
|
|
#include <syslog.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <skey.h>
|
|
|
|
#if (MAXHOSTNAMELEN < 64) /* AIX weirdness */
|
|
#undef MAXHOSTNAMELEN
|
|
#endif
|
|
|
|
#ifndef MAXHOSTNAMELEN
|
|
#define MAXHOSTNAMELEN 255
|
|
#endif
|
|
|
|
#include "pathnames.h"
|
|
|
|
static int isaddr();
|
|
static int rdnets();
|
|
|
|
#define MAXADDR 16 /* how many addresses can a machine
|
|
* have? */
|
|
|
|
/*
|
|
* Turn host into an IP address and then look it up in the authorization
|
|
* database to determine if ordinary password logins are OK
|
|
*/
|
|
int authfile(host)
|
|
char *host;
|
|
{
|
|
char *addr[MAXADDR];
|
|
char **ap;
|
|
long n;
|
|
struct hostent *hp;
|
|
char **lp;
|
|
struct hostent *xp;
|
|
int addr_length;
|
|
|
|
if (strlen(host) == 0) {
|
|
/* Local login, okay */
|
|
return 1;
|
|
}
|
|
if (isaddr(host)) {
|
|
return rdnets(inet_addr(host));
|
|
} else {
|
|
|
|
/*
|
|
* Stash away a copy of the host address list because it will be
|
|
* clobbered by other gethostbyXXX() calls.
|
|
*/
|
|
|
|
hp = gethostbyname(host);
|
|
if (hp == NULL) {
|
|
syslog(LOG_ERR, "unknown host: %s", host);
|
|
return 0;
|
|
}
|
|
if (hp->h_addrtype != AF_INET) {
|
|
syslog(LOG_ERR, "unknown network family: %d", hp->h_addrtype);
|
|
return 0;
|
|
}
|
|
for (lp = hp->h_addr_list, ap = addr; ap < addr + MAXADDR; lp++, ap++) {
|
|
if (*lp == NULL) {
|
|
*ap = 0;
|
|
break;
|
|
} else {
|
|
if ((*ap = malloc(hp->h_length)) == 0) {
|
|
syslog(LOG_ERR, "out of memory");
|
|
return 0;
|
|
}
|
|
memcpy(*ap, *lp, hp->h_length);
|
|
}
|
|
}
|
|
addr_length = hp->h_length;
|
|
|
|
/*
|
|
* See if any of the addresses matches a pattern in the control file.
|
|
* Report and skip the address if it does not belong to the remote
|
|
* host. Assume localhost == localhost.domain.
|
|
*/
|
|
|
|
#define NEQ(x,y) (strcasecmp((x),(y)) != 0)
|
|
|
|
while (ap-- > addr) {
|
|
memcpy((char *) &n, *ap, addr_length);
|
|
if (rdnets(n)) {
|
|
if ((hp = gethostbyaddr(*ap, addr_length, AF_INET)) == 0
|
|
|| (NEQ(host, hp->h_name) && NEQ(host, "localhost"))) {
|
|
syslog(LOG_ERR, "IP address %s not registered for host %s",
|
|
inet_ntoa(*(struct in_addr *) * ap), host);
|
|
continue;
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
static int rdnets(host)
|
|
unsigned long host;
|
|
{
|
|
FILE *fp;
|
|
char buf[128],
|
|
*cp;
|
|
long pattern,
|
|
mask;
|
|
char *strtok();
|
|
int permit_it = 0;
|
|
|
|
/*
|
|
* If auth file not found, be backwards compatible with standard login
|
|
* and allow hard coded passwords in from anywhere. Some may consider
|
|
* this a security hole, but backwards compatibility is more desirable
|
|
* than others. If you don't like it, change the return value to be zero.
|
|
*/
|
|
if ((fp = fopen(_PATH_SKEYACCESS, "r")) == NULL)
|
|
return 1;
|
|
|
|
while (fgets(buf, sizeof(buf), fp), !feof(fp)) {
|
|
if (buf[0] == '#')
|
|
continue; /* Comment */
|
|
cp = strtok(buf, " \t");
|
|
if (cp == NULL)
|
|
continue;
|
|
/* two choices permit or deny */
|
|
if (strncasecmp(cp, "permit", 4) == 0) {
|
|
permit_it = 1;
|
|
} else {
|
|
if (strncasecmp(cp, "deny", 4) == 0) {
|
|
permit_it = 0;
|
|
} else {
|
|
continue; /* ignore this it is not
|
|
* permit/deny */
|
|
}
|
|
}
|
|
cp = strtok(NULL, " \t");
|
|
if (cp == NULL)
|
|
continue; /* Invalid line */
|
|
pattern = inet_addr(cp);
|
|
cp = strtok(NULL, " \t");
|
|
if (cp == NULL)
|
|
continue; /* Invalid line */
|
|
mask = inet_addr(cp);
|
|
if ((host & mask) == pattern) {
|
|
fclose(fp);
|
|
return permit_it;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Return TRUE if string appears to be an IP address in dotted decimal;
|
|
* return FALSE otherwise (i.e., if string is a domain name)
|
|
*/
|
|
static int isaddr(s)
|
|
register char *s;
|
|
{
|
|
char c;
|
|
|
|
if (s == NULL)
|
|
return 1; /* Can't happen */
|
|
|
|
while ((c = *s++) != '\0') {
|
|
if (c != '[' && c != ']' && !isdigit(c) && c != '.')
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|