summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
Diffstat (limited to 'libexec')
-rw-r--r--libexec/telnetd/ext.h5
-rw-r--r--libexec/telnetd/state.c54
-rw-r--r--libexec/telnetd/sys_term.c68
-rw-r--r--libexec/telnetd/telnetd.87
-rw-r--r--libexec/telnetd/telnetd.c119
-rw-r--r--libexec/telnetd/telnetd.h3
6 files changed, 66 insertions, 190 deletions
diff --git a/libexec/telnetd/ext.h b/libexec/telnetd/ext.h
index 5f911a2980b..dba7049e543 100644
--- a/libexec/telnetd/ext.h
+++ b/libexec/telnetd/ext.h
@@ -51,6 +51,7 @@ extern int restartany; /* restart output on any character state */
#ifdef DIAGNOSTICS
extern int diagnostic; /* telnet diagnostic capabilities */
#endif /* DIAGNOSTICS */
+extern int require_otp;
#ifdef AUTHENTICATION
extern int auth_level;
#endif
@@ -117,7 +118,7 @@ void tty_tspeed (int val);
void tty_rspeed (int val);
void getptyslave (void);
int cleanopen (char *line);
-void startslave (const char *host, int channel[2]);
+void startslave (const char *host, const char *, int autologin, char *autoname);
void init_env (void);
void start_login (const char *host, int autologin, char *name);
void cleanup (int sig);
@@ -125,7 +126,7 @@ int main (int argc, char **argv);
int getterminaltype (char *name, size_t);
void _gettermname (void);
int terminaltypeok (char *s);
-void my_telnet (int f, int p, const char *, const char *, int, char *, char *, FILE *);
+void my_telnet (int f, int p, const char*, const char *, int, char*);
void interrupt (void);
void sendbrk (void);
void sendsusp (void);
diff --git a/libexec/telnetd/state.c b/libexec/telnetd/state.c
index c6cb0d09649..d20f49eb80c 100644
--- a/libexec/telnetd/state.c
+++ b/libexec/telnetd/state.c
@@ -895,38 +895,44 @@ int env_ovalue = -1;
#endif /* ENV_HACK */
/*
- * Environment variables that are safe to let through.
- * Anything else will simply be dropped.
+ * variables not to let through.
+ * if name ends in =, it is complete variable name
+ * if it does not end in =, all variables starting with this name
+ * should be dropped.
*/
-char *goodenv_table[] = {
- "TERM",
- "DISPLAY",
- "USER",
- "LOGNAME",
- "POSIXLY_CORRECT",
- NULL
+char *badenv_table[] = {
+ "IFS=",
+ "LD_",
+ "_RLD_",
+ "SHLIB_PATH=",
+ "LIBPATH=",
+ "KRB",
+ "ENV=",
+ "BASH_ENV=",
+ NULL,
};
+/* envvarok(char*) */
/* check that variable is safe to pass to login or shell */
-int
-envvarok(varp, valp)
+static int
+envvarok(varp)
char *varp;
- char *valp;
{
int i;
+ int len;
if (strchr(varp, '='))
return (0);
-
- for (i = 0; goodenv_table[i]; i++) {
- if (strcmp(goodenv_table[i], varp) != 0)
- continue;
- /* disallow variables with slashes or ones that are too long */
- if (strchr(valp, '/') || strlen(valp) >= 0x100)
- return (0);
- return (1);
- }
- return (0);
+ for (i = 0; badenv_table[i]; i++) {
+ len = strlen(badenv_table[i]);
+ if (badenv_table[i][len-1] == '=' &&
+ !strncmp(badenv_table[i], varp, len-1) &&
+ varp[len-2] == '\0')
+ return (0);
+ if (!strncmp(badenv_table[i], varp, len-1))
+ return (0);
+ }
+ return (1);
}
/*
@@ -1219,7 +1225,7 @@ suboption(void)
case NEW_ENV_VAR:
case ENV_USERVAR:
*cp = '\0';
- if (envvarok(varp, valp)) {
+ if(envvarok(varp)) {
if (valp)
esetenv(varp, valp, 1);
else
@@ -1240,7 +1246,7 @@ suboption(void)
}
}
*cp = '\0';
- if (envvarok(varp, valp)) {
+ if(envvarok(varp)) {
if (valp)
esetenv(varp, valp, 1);
else
diff --git a/libexec/telnetd/sys_term.c b/libexec/telnetd/sys_term.c
index 4f98a2bef5e..0d05a0da07f 100644
--- a/libexec/telnetd/sys_term.c
+++ b/libexec/telnetd/sys_term.c
@@ -1101,42 +1101,6 @@ make_id (char *tty)
}
#endif
-static int
-fgets0(char *s, int size, FILE *f)
-{
- int i, c, trunc;
-
- i = 0;
- trunc = 0;
- while ((c = getc(f)) != EOF && c)
- if (i < size - 1)
- s[i++] = c;
- else
- trunc = 1;
- s[i] = 0;
-
- if (c == EOF)
- fatal(-1, "fgets0: Unexpected EOF");
-
- return trunc;
-}
-
-extern char *goodenv_table[];
-extern int envvarok(char *varp, char *valp);
-
-static void
-fgetenv(FILE *f)
-{
- char **name, value[0x100];
-
- for (name = goodenv_table; *name; name++) {
- if (fgets0(value, sizeof(value), f) || !value[0])
- continue;
- if (envvarok(*name, value))
- setenv(*name, value, 1);
- }
-}
-
/*
* startslave(host)
*
@@ -1146,19 +1110,12 @@ fgetenv(FILE *f)
/* ARGSUSED */
void
-startslave(const char *host, int channel[2])
+startslave(const char *host, const char *utmp_host,
+ int autologin, char *autoname)
{
int i;
- int autologin;
- char autoname[9];
- FILE *masterf;
-
- autologin = -1; /* shouldn't be used */
- autoname[0] = '\0';
#ifdef AUTHENTICATION
- autologin = AUTH_REJECT;
-
if (!autoname || !autoname[0])
autologin = 0;
@@ -1211,27 +1168,6 @@ startslave(const char *host, int channel[2])
utmp_sig_notify(pid);
# endif /* PARENT_DOES_UTMP */
} else {
- close(channel[1]);
-
- masterf = fdopen(channel[0], "r");
- if (!masterf)
- fatalperror(-1, "fdopen");
-
-#ifdef AUTHENTICATION
- if (fread(&autologin, sizeof(autologin), 1, masterf) != 1)
- fatalperror(-1, "fread");
-
- if (fgets0(autoname, sizeof(autoname), masterf)) {
- /* Truncation of a username isn't safe */
- autologin = AUTH_REJECT;
- autoname[0] = 0;
- }
-#endif
-
- fgetenv(masterf);
-
- fclose(masterf);
-
getptyslave();
#if defined(DCE)
/* if we authenticated via K5, try and join the PAG */
diff --git a/libexec/telnetd/telnetd.8 b/libexec/telnetd/telnetd.8
index b47dae64bfc..a2a5aadb221 100644
--- a/libexec/telnetd/telnetd.8
+++ b/libexec/telnetd/telnetd.8
@@ -123,6 +123,13 @@ by any of the existing authentication mechanisms,
and is thus the same as specifying
.Fl a
.Cm valid .
+.It otp
+Only allow Kerberos authenticated connections (as with
+.Fl a
+.Cm user )
+and also logins with one-time passwords (OTPs).
+This option will call login with an option so that only OTPs are accepted.
+The user can of course still type secret information at the prompt.
.It none
This is the default state.
Kerberos authentication information is not required.
diff --git a/libexec/telnetd/telnetd.c b/libexec/telnetd/telnetd.c
index 18089dc3462..2b3f61dea0c 100644
--- a/libexec/telnetd/telnetd.c
+++ b/libexec/telnetd/telnetd.c
@@ -37,8 +37,6 @@
#include <fcntl.h>
#include <syslog.h>
#include <unistd.h>
-#include <pwd.h>
-#include <grp.h>
#include <sys/ioctl.h>
/* RCSID("$KTH: telnetd.c,v 1.64 2001/02/08 16:06:27 assar Exp $"); */
@@ -129,9 +127,7 @@ int debug = 0;
int keepalive = 1;
char *progname;
char *gettyent = "default";
-char *gettytab[2] = { "./etc/gettytab", NULL };
-
-static int issue_fd;
+char *gettytab[2] = { "/etc/gettytab", NULL };
static void usage (void);
@@ -433,8 +429,7 @@ main(int argc, char **argv)
}
#endif /* _SC_CRAY_SECURE_SYS */
- tzset();
- openlog("telnetd", LOG_PID | LOG_NDELAY, LOG_DAEMON);
+ openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
sa_size = sizeof (__ss);
if (getpeername(STDIN_FILENO, sa, &sa_size) < 0) {
fprintf(stderr, "%s: ", progname);
@@ -682,32 +677,6 @@ char host_name[MAXHOSTNAMELEN];
char remote_host_name[MAXHOSTNAMELEN];
char remote_utmp_name[MAXHOSTNAMELEN];
-static void
-drop_root(void)
-{
- struct passwd *pw;
-
- pw = getpwnam(TELNETD_USER);
- if (!pw)
- fatal(-1, "getpwnam: telnetd: No such user");
-
- /*
- * Note: we will do another chdir to / later on, after we have
- * finished accessing files outside the jail.
- */
- if (chdir("/"))
- fatalperror(-1, "chdir");
- if (chroot(TELNETD_CHROOT))
- fatalperror(-1, "chroot");
-
- if (setgroups(0, NULL))
- fatalperror(-1, "setgroups");
- if (setgid(pw->pw_gid))
- fatalperror(-1, "setgid");
- if (setuid(pw->pw_uid))
- fatalperror(-1, "setuid");
-}
-
/*
* Get a pty, scan input lines.
*/
@@ -716,10 +685,8 @@ doit(struct sockaddr *who, int who_len)
{
int level;
int ptynum;
- char user_name[256], *buf;
+ char user_name[256];
int error;
- int channel[2];
- FILE *slavef;
/*
* Find an available pty to use.
@@ -783,30 +750,6 @@ Please contact your net administrator");
#endif
init_env();
-
- if (pipe(channel))
- fatalperror(-1, "pipe");
-
- startslave(remote_host_name, channel);
- close(channel[0]);
-
- issue_fd = open("/etc/issue.net", O_RDONLY);
- if (issue_fd < 0)
- issue_fd = open("/etc/issue", O_RDONLY);
-
- drop_root();
-
- if (cgetent(&buf, gettytab, gettyent) < 0)
- buf = NULL;
-
- /* make the chroot really take effect */
- if (chdir("/"))
- fatalperror(-1, "chdir");
-
- slavef = fdopen(channel[1], "w");
- if (!slavef)
- fatalperror(-1, "fdopen");
-
/*
* get terminal type.
*/
@@ -825,7 +768,7 @@ Please contact your net administrator");
/* begin server processing */
my_telnet(net, ourpty, remote_host_name, remote_utmp_name,
- level, user_name, buf, slavef);
+ level, user_name);
/*NOTREACHED*/
} /* end of doit */
@@ -835,32 +778,15 @@ show_issue(void)
{
FILE *f;
char buf[128];
-
- if (issue_fd < 0)
- return;
-
- f = fdopen(issue_fd, "r");
+ f = fopen("/etc/issue.net", "r");
+ if(f == NULL)
+ f = fopen("/etc/issue", "r");
if(f){
while(fgets(buf, sizeof(buf)-2, f)){
strcpy(buf + strcspn(buf, "\r\n"), "\r\n");
writenet((unsigned char*)buf, strlen(buf));
}
fclose(f);
- } else
- close(issue_fd);
-}
-
-extern char *goodenv_table[];
-
-static void
-fputenv(FILE *f)
-{
- char **name, *value;
-
- for (name = goodenv_table; *name; name++) {
- value = getenv(*name) ?: "";
- if (fwrite(value, strlen(value) + 1, 1, f) != 1)
- fatalperror(-1, "fwrite");
}
}
@@ -870,12 +796,15 @@ fputenv(FILE *f)
*/
void
my_telnet(int f, int p, const char *host, const char *utmp_host,
- int level, char *autoname, char *gettybuf, FILE *slavef)
+ int level, char *autoname)
{
int on = 1;
char *he;
char *IM;
+ char *buf;
int nfd;
+ int startslave_called = 0;
+ time_t timeout;
/*
* Initialize the slc mapping table.
@@ -1025,18 +954,18 @@ my_telnet(int f, int p, const char *host, const char *utmp_host,
if (getenv("USER"))
hostinfo = 0;
- if (gettybuf) {
+ if (cgetent(&buf, gettytab, gettyent) >= 0) {
char *HN;
- if (cgetstr(gettybuf, "he", &he) <= 0)
+ if (cgetstr(buf, "he", &he) <= 0)
he = NULL;
- if (cgetstr(gettybuf, "im", &IM) <= 0)
+ if (cgetstr(buf, "im", &IM) <= 0)
IM = "";
- if (cgetstr(gettybuf, "hn", &HN) > 0) {
+ if (cgetstr(buf, "hn", &HN) > 0) {
strlcpy(host_name, HN, sizeof host_name);
free(HN);
}
- free(gettybuf);
+ cgetclose();
} else {
IM = DEFAULT_IM;
he = NULL;
@@ -1058,20 +987,20 @@ my_telnet(int f, int p, const char *host, const char *utmp_host,
output_data("td: Entering processing loop\r\n");
});
-#ifdef AUTHENTICATION
- if (fwrite(&level, sizeof(level), 1, slavef) != 1 ||
- fwrite(autoname, strlen(autoname) + 1, 1, slavef) != 1)
- fatalperror(-1, "fwrite");
-#endif
-
- fputenv(slavef);
- fclose(slavef);
nfd = ((f > p) ? f : p) + 1;
+ timeout = time(NULL) + 5;
for (;;) {
fd_set ibits, obits, xbits;
int c;
+ /* wait for encryption to be turned on, but don't wait
+ indefinitely */
+ if(!startslave_called && (!encrypt_delay() || timeout > time(NULL))){
+ startslave_called = 1;
+ startslave(host, utmp_host, level, autoname);
+ }
+
if (ncc < 0 && pcc < 0)
break;
diff --git a/libexec/telnetd/telnetd.h b/libexec/telnetd/telnetd.h
index 7657525088f..8955fce4699 100644
--- a/libexec/telnetd/telnetd.h
+++ b/libexec/telnetd/telnetd.h
@@ -52,9 +52,6 @@
#define HAVE_SYS_UTSNAME_H
#define HAVE_UNAME
-#define TELNETD_USER "_telnetd"
-#define TELNETD_CHROOT "/var/empty"
-
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif