diff options
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/telnetd/ext.h | 5 | ||||
-rw-r--r-- | libexec/telnetd/state.c | 54 | ||||
-rw-r--r-- | libexec/telnetd/sys_term.c | 68 | ||||
-rw-r--r-- | libexec/telnetd/telnetd.8 | 7 | ||||
-rw-r--r-- | libexec/telnetd/telnetd.c | 119 | ||||
-rw-r--r-- | libexec/telnetd/telnetd.h | 3 |
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 |