1/* accessfile.c: Handle trusted network access file and per-user 2 overrides. 3 4%%% portions-copyright-cmetz-96 5Portions of this software are Copyright 1996-1999 by Craig Metz, All Rights 6Reserved. The Inner Net License Version 2 applies to these portions of 7the software. 8You should have received a copy of the license with this software. If 9you didn't get a copy, you may request one from <license@inner.net>. 10 11Portions of this software are Copyright 1995 by Randall Atkinson and Dan 12McDonald, All Rights Reserved. All Rights under this copyright are assigned 13to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and 14License Agreement applies to this software. 15 16 History: 17 18 Modified by cmetz for OPIE 2.31. Include syslog.h on debug. 19 Modified by cmetz for OPIE 2.3. Send debug info to syslog. 20 Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al. 21 Ifdef around some headers. Remove extra semicolon. 22 Modified at NRL for OPIE 2.2. Moved from accessfile.c to 23 libopie/opieaccessfile.c. 24 Modified at NRL for OPIE 2.0. 25 Written at Bellcore for the S/Key Version 1 software distribution 26 (login.c). 27*/ 28#include "opie_cfg.h" 29 30#include <stdio.h> 31#include <sys/types.h> 32#include <sys/socket.h> 33#include <netinet/in.h> 34#include <arpa/inet.h> 35#include <netdb.h> 36#if HAVE_STRING_H 37#include <string.h> 38#endif /* HAVE_STRING_H */ 39#if HAVE_UNISTD_H 40#include <unistd.h> 41#endif /* HAVE_UNISTD_H */ 42#if HAVE_STDLIB_H 43#include <stdlib.h> 44#endif /* HAVE_STDLIB_H */ 45 46#ifdef DEBUG 47#include <syslog.h> 48#endif /* DEBUG */ 49 50#include "opie.h" 51 52int opieaccessfile FUNCTION((host), char *host) 53{ 54#ifdef PATH_ACCESS_FILE 55/* Turn host into an IP address and then look it up in the authorization 56 * database to determine if ordinary password logins are OK 57 */ 58 long n; 59 struct hostent *hp; 60 FILE *fp; 61 char buf[128], **lp; 62 63#ifdef DEBUG 64 syslog(LOG_DEBUG, "accessfile: host=%s", host); 65#endif /* DEBUG */ 66 if (!host[0]) 67 /* Local login, okay */ 68 return (1); 69 if (isaddr(host)) { 70 n = inet_addr(host); 71 return rdnets(n); 72 } else { 73 hp = gethostbyname(host); 74 if (!hp) { 75 printf("Unknown host %s\n", host); 76 return 0; 77 } 78 for (lp = hp->h_addr_list; *lp; lp++) { 79 memcpy((char *) &n, *lp, sizeof(n)); 80 if (rdnets(n)) 81 return (1); 82 } 83 return (0); 84 } 85} 86 87int rdnets FUNCTION((host), long host) 88{ 89 FILE *fp; 90 char buf[128], *cp; 91 long pattern, mask; 92 int permit_it; 93 94 if (!(fp = fopen(PATH_ACCESS_FILE, "r"))) 95 return 0; 96 97 while (fgets(buf, sizeof(buf), fp), !feof(fp)) { 98 if (buf[0] == '#') 99 continue; /* Comment */ 100 if (!(cp = strtok(buf, " \t"))) 101 continue; 102 /* two choices permit of deny */ 103 if (strncasecmp(cp, "permit", 4) == 0) { 104 permit_it = 1; 105 } else { 106 if (strncasecmp(cp, "deny", 4) == 0) { 107 permit_it = 0; 108 } else { 109 continue; /* ignore; it is not permit/deny */ 110 } 111 } 112 if (!(cp = strtok(NULL, " \t"))) 113 continue; /* Invalid line */ 114 pattern = inet_addr(cp); 115 if (!(cp = strtok(NULL, " \t"))) 116 continue; /* Invalid line */ 117 mask = inet_addr(cp); 118#ifdef DEBUG 119 syslog(LOG_DEBUG, "accessfile: %08x & %08x == %08x (%s)", host, mask, pattern, ((host & mask) == pattern) ? "true" : "false"); 120#endif /* DEBUG */ 121 if ((host & mask) == pattern) { 122 fclose(fp); 123 return permit_it; 124 } 125 } 126 fclose(fp); 127 return 0; 128} 129 130 131/* Return TRUE if string appears to be an IP address in dotted decimal; 132 * return FALSE otherwise (i.e., if string is a domain name) 133 */ 134int isaddr FUNCTION((s), register char *s) 135{ 136 char c; 137 138 if (!s) 139 return 1; /* Can't happen */ 140 141 while ((c = *s++) != '\0') { 142 if (c != '[' && c != ']' && !isdigit(c) && c != '.') 143 return 0; 144 } 145 return 1; 146#else /* PATH_ACCESS_FILE */ 147 return !host[0]; 148#endif /* PATH_ACCESS_FILE */ 149} 150 151/* Returns the opposite of what you might expect */ 152/* Returns 1 on error (allow)... this might not be what you want */ 153int opiealways FUNCTION((homedir), char *homedir) 154{ 155 char *opiealwayspath; 156 int i; 157 158 if (!homedir) 159 return 1; 160 161 if (!(opiealwayspath = malloc(strlen(homedir) + sizeof(OPIE_ALWAYS_FILE) + 1))) 162 return 1; 163 164 strcpy(opiealwayspath, homedir); 165 strcat(opiealwayspath, "/"); 166 strcat(opiealwayspath, OPIE_ALWAYS_FILE); 167 i = access(opiealwayspath, F_OK); 168 free(opiealwayspath); 169 return (i); 170} 171