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