122347Spst/* accessfile.c: Handle trusted network access file and per-user 222347Spst overrides. 322347Spst 429964Sache%%% portions-copyright-cmetz-96 592906SmarkmPortions of this software are Copyright 1996-1999 by Craig Metz, All Rights 622347SpstReserved. The Inner Net License Version 2 applies to these portions of 722347Spstthe software. 822347SpstYou should have received a copy of the license with this software. If 922347Spstyou didn't get a copy, you may request one from <license@inner.net>. 1022347Spst 1122347SpstPortions of this software are Copyright 1995 by Randall Atkinson and Dan 1222347SpstMcDonald, All Rights Reserved. All Rights under this copyright are assigned 1322347Spstto the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and 1422347SpstLicense Agreement applies to this software. 1522347Spst 1622347Spst History: 1722347Spst 1829964Sache Modified by cmetz for OPIE 2.31. Include syslog.h on debug. 1922347Spst Modified by cmetz for OPIE 2.3. Send debug info to syslog. 2022347Spst Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al. 2122347Spst Ifdef around some headers. Remove extra semicolon. 2222347Spst Modified at NRL for OPIE 2.2. Moved from accessfile.c to 2322347Spst libopie/opieaccessfile.c. 2422347Spst Modified at NRL for OPIE 2.0. 2522347Spst Written at Bellcore for the S/Key Version 1 software distribution 2622347Spst (login.c). 2722347Spst*/ 2822347Spst#include "opie_cfg.h" 2922347Spst 3022347Spst#include <stdio.h> 3122347Spst#include <sys/types.h> 3222347Spst#include <sys/socket.h> 3322347Spst#include <netinet/in.h> 3422347Spst#include <arpa/inet.h> 3522347Spst#include <netdb.h> 3622347Spst#if HAVE_STRING_H 3722347Spst#include <string.h> 3822347Spst#endif /* HAVE_STRING_H */ 3922347Spst#if HAVE_UNISTD_H 4022347Spst#include <unistd.h> 4122347Spst#endif /* HAVE_UNISTD_H */ 4222347Spst#if HAVE_STDLIB_H 4322347Spst#include <stdlib.h> 4422347Spst#endif /* HAVE_STDLIB_H */ 4522347Spst 4629964Sache#ifdef DEBUG 4729964Sache#include <syslog.h> 4829964Sache#endif /* DEBUG */ 4929964Sache 5022347Spst#include "opie.h" 5122347Spst 5222347Spstint opieaccessfile FUNCTION((host), char *host) 5322347Spst{ 5422347Spst#ifdef PATH_ACCESS_FILE 5522347Spst/* Turn host into an IP address and then look it up in the authorization 5622347Spst * database to determine if ordinary password logins are OK 5722347Spst */ 5822347Spst long n; 5922347Spst struct hostent *hp; 6022347Spst FILE *fp; 6122347Spst char buf[128], **lp; 6222347Spst 6322347Spst#ifdef DEBUG 6422347Spst syslog(LOG_DEBUG, "accessfile: host=%s", host); 6522347Spst#endif /* DEBUG */ 6622347Spst if (!host[0]) 6722347Spst /* Local login, okay */ 6822347Spst return (1); 6922347Spst if (isaddr(host)) { 7022347Spst n = inet_addr(host); 7122347Spst return rdnets(n); 7222347Spst } else { 7322347Spst hp = gethostbyname(host); 7422347Spst if (!hp) { 7522347Spst printf("Unknown host %s\n", host); 7622347Spst return 0; 7722347Spst } 7822347Spst for (lp = hp->h_addr_list; *lp; lp++) { 7922347Spst memcpy((char *) &n, *lp, sizeof(n)); 8022347Spst if (rdnets(n)) 8122347Spst return (1); 8222347Spst } 8322347Spst return (0); 8422347Spst } 8522347Spst} 8622347Spst 8722347Spstint rdnets FUNCTION((host), long host) 8822347Spst{ 8922347Spst FILE *fp; 9022347Spst char buf[128], *cp; 9122347Spst long pattern, mask; 9222347Spst int permit_it; 9322347Spst 9422347Spst if (!(fp = fopen(PATH_ACCESS_FILE, "r"))) 9522347Spst return 0; 9622347Spst 9722347Spst while (fgets(buf, sizeof(buf), fp), !feof(fp)) { 9822347Spst if (buf[0] == '#') 9922347Spst continue; /* Comment */ 10022347Spst if (!(cp = strtok(buf, " \t"))) 10122347Spst continue; 10222347Spst /* two choices permit of deny */ 10322347Spst if (strncasecmp(cp, "permit", 4) == 0) { 10422347Spst permit_it = 1; 10522347Spst } else { 10622347Spst if (strncasecmp(cp, "deny", 4) == 0) { 10722347Spst permit_it = 0; 10822347Spst } else { 10922347Spst continue; /* ignore; it is not permit/deny */ 11022347Spst } 11122347Spst } 11222347Spst if (!(cp = strtok(NULL, " \t"))) 11322347Spst continue; /* Invalid line */ 11422347Spst pattern = inet_addr(cp); 11522347Spst if (!(cp = strtok(NULL, " \t"))) 11622347Spst continue; /* Invalid line */ 11722347Spst mask = inet_addr(cp); 11822347Spst#ifdef DEBUG 11922347Spst syslog(LOG_DEBUG, "accessfile: %08x & %08x == %08x (%s)", host, mask, pattern, ((host & mask) == pattern) ? "true" : "false"); 12022347Spst#endif /* DEBUG */ 12122347Spst if ((host & mask) == pattern) { 12222347Spst fclose(fp); 12322347Spst return permit_it; 12422347Spst } 12522347Spst } 12622347Spst fclose(fp); 12722347Spst return 0; 12822347Spst} 12922347Spst 13022347Spst 13122347Spst/* Return TRUE if string appears to be an IP address in dotted decimal; 13222347Spst * return FALSE otherwise (i.e., if string is a domain name) 13322347Spst */ 13422347Spstint isaddr FUNCTION((s), register char *s) 13522347Spst{ 13622347Spst char c; 13722347Spst 13822347Spst if (!s) 13922347Spst return 1; /* Can't happen */ 14022347Spst 14122347Spst while ((c = *s++) != '\0') { 14222347Spst if (c != '[' && c != ']' && !isdigit(c) && c != '.') 14322347Spst return 0; 14422347Spst } 14522347Spst return 1; 14622347Spst#else /* PATH_ACCESS_FILE */ 14722347Spst return !host[0]; 14822347Spst#endif /* PATH_ACCESS_FILE */ 14922347Spst} 15022347Spst 15122347Spst/* Returns the opposite of what you might expect */ 15222347Spst/* Returns 1 on error (allow)... this might not be what you want */ 15322347Spstint opiealways FUNCTION((homedir), char *homedir) 15422347Spst{ 15522347Spst char *opiealwayspath; 15622347Spst int i; 15722347Spst 15822347Spst if (!homedir) 15922347Spst return 1; 16022347Spst 16122347Spst if (!(opiealwayspath = malloc(strlen(homedir) + sizeof(OPIE_ALWAYS_FILE) + 1))) 16222347Spst return 1; 16322347Spst 16422347Spst strcpy(opiealwayspath, homedir); 16522347Spst strcat(opiealwayspath, "/"); 16622347Spst strcat(opiealwayspath, OPIE_ALWAYS_FILE); 16722347Spst i = access(opiealwayspath, F_OK); 16822347Spst free(opiealwayspath); 16922347Spst return (i); 17022347Spst} 171