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