1/* insecure.c: The opieinsecure() library function.
2
3%%% portions-copyright-cmetz-96
4Portions of this software are Copyright 1996-1999 by Craig Metz, All Rights
5Reserved. The Inner Net License Version 2 applies to these portions of
6the software.
7You should have received a copy of the license with this software. If
8you didn't get a copy, you may request one from <license@inner.net>.
9
10Portions of this software are Copyright 1995 by Randall Atkinson and Dan
11McDonald, All Rights Reserved. All Rights under this copyright are assigned
12to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
13License Agreement applies to this software.
14
15        History:
16
17	Modified by cmetz for OPIE 2.4. Do utmp checks on utmpx systems.
18	     Handle unterminated ut_host.
19	Modified by cmetz for OPIE 2.31. Fixed a logic bug. Call endut[x]ent().
20	Modified by cmetz for OPIE 2.3. Added result caching. Use
21	     __opiegetutmpentry(). Ifdef around ut_host check. Eliminate
22	     unused variable.
23	Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
24             Allow IP loopback. DISPLAY and ut_host must match exactly,
25             not just the part before the colon. Added work-around for
26             Sun CDE dtterm bug. Leave the environment as it was
27             found. Use uname().
28        Created at NRL for OPIE 2.2 from opiesubr.c. Fixed pointer
29             assignment that should have been a comparison.
30
31$FreeBSD$
32
33*/
34#include "opie_cfg.h"
35
36#include <stdio.h>
37#include <string.h>
38#include <stdlib.h>	/* ANSI C standard library */
39#include <sys/param.h>
40#include <unistd.h>
41
42#if DOUTMPX
43#include <utmpx.h>
44#define utmp utmpx
45#define endutent endutxent
46#else
47#include <utmp.h>
48#endif	/* DOUTMPX */
49
50#if HAVE_SYS_UTSNAME_H
51#include <sys/utsname.h>
52#endif /* HAVE_SYS_UTSNAME_H */
53
54#include "opie.h"
55
56char *remote_terms[] = { "xterm", "xterms", "kterm", NULL };
57
58int opieinsecure FUNCTION_NOARGS
59{
60#ifndef NO_INSECURE_CHECK
61  char *display_name;
62  char *s;
63  char *term_name;
64  int  insecure = 0;
65#if HAVE_UT_HOST || DOUTMPX
66  struct utmp utmp;
67#endif /* HAVE_UT_HOST || DOUTMPX */
68  static int result = -1;
69
70  if (result != -1)
71    return result;
72
73  if (getenv("SSH_CLIENT") != NULL)
74	return (result = 0);
75  display_name = (char *) getenv("DISPLAY");
76  term_name = (char *) getenv("TERM");
77
78  if (display_name) {
79    insecure = 1;
80    if (s = strchr(display_name, ':')) {
81      int n = s - display_name;
82      if (!n)
83	insecure = 0;
84      else {
85	if (!strncmp("unix", display_name, n))
86	  insecure = 0;
87        else if (!strncmp("localhost", display_name, n))
88	    insecure = 0;
89        else if (!strncmp("loopback", display_name, n))
90	    insecure = 0;
91        else if (!strncmp("127.0.0.1", display_name, n))
92	    insecure = 0;
93	else {
94          struct utsname utsname;
95
96	  if (!uname(&utsname)) {
97	    if (!strncmp(utsname.nodename, display_name, n))
98	      insecure = 0;
99	    else {
100	      if (s = strchr(display_name, '.')) {
101		int n2 = s - display_name;
102                if (n < n2)
103                  n2 = n;
104		if (!strncmp(utsname.nodename, display_name, n2))
105		  insecure = 0;
106	      } /* endif display_name is '.' */
107	    } /* endif hostname != display_name */
108	  } /* endif was able to get hostname */
109	} /* endif display_name == UNIX */
110      }
111    }
112    } /* endif display_name == ":" */
113    if (insecure)
114      return (result = 1);
115
116  /* If no DISPLAY variable exists and TERM=xterm,
117     then we probably have an xterm executing on a remote system
118     with an rlogin or telnet to our system.  If it were a local
119     xterm, then the DISPLAY environment variable would
120     have to exist. rja */
121  if (!display_name && term_name) {
122    int i;
123    for (i = 0; remote_terms[i]; i++)
124      if (!strcmp(term_name, remote_terms[i]))
125        return (result = 1);
126  };
127
128#if HAVE_UT_HOST || DOUTMPX
129  if (isatty(0)) {
130    memset(&utmp, 0, sizeof(struct utmp));
131    {
132      int i = __opiegetutmpentry(ttyname(0), &utmp);
133      endutent();
134      if (!i && utmp.ut_host[0]) {
135	char host[sizeof(utmp.ut_host) + 1];
136	insecure = 1;
137
138	strncpy(host, utmp.ut_host, sizeof(utmp.ut_host));
139	host[sizeof(utmp.ut_host)] = 0;
140
141	if (s = strchr(host, ':')) {
142	  int n = s - host;
143	  if (!n)
144	    insecure = 0;
145	  else
146	    if (display_name) {
147	      if (!strncmp(host, display_name, n))
148		insecure = 0;
149#if 1 /* def SOLARIS */
150	      else
151		if (s = strchr(host, ' ')) {
152		  *s = ':';
153		  if (s = strchr(s + 1, ' '))
154		    *s = '.';
155		  if (!strncmp(host, display_name, n))
156		    insecure = 0;
157		}
158#endif /* SOLARIS */
159	    }
160	}
161      }
162    };
163  };
164#endif /* HAVE_UT_HOST || DOUTMPX */
165  if (insecure)
166    return (result = 1);
167
168  return (result = 0);
169#else /* NO_INSECURE_CHECK */
170  return 0;
171#endif /* NO_INSECURE_CHECK */
172}
173