tags 556522 patch thanks Hi :) I incorporated some code from util-linuxs getty to make hurds getty ask for a login name and pass that name to login. This way the login shell is no longer needed. I also turned on logins --paranoid flag to prevent it leaking whether a user exists or not. Cheers, Justus
--- hurd-20100926/daemons/getty.c 2010-09-26 22:10:52.000000000 +0000 +++ hurd-20100926-mine/daemons/getty.c 2011-01-09 23:35:27.000000000 +0000 @@ -4,6 +4,9 @@ Written by Michael I. Bushnell, p/BSG. + This file contains parts of the get_logname function from + util-linux/getty.c. + This file is part of the GNU Hurd. The GNU Hurd is free software; you can redistribute it and/or @@ -34,11 +37,21 @@ #include <utmp.h> #include <sys/ioctl.h> #include <termios.h> +#include <ctype.h> /* XXX */ extern char *localhost (); #define _PATH_LOGIN "/bin/login" +#define LOGIN " login: " /* login prompt */ + +/* Some shorthands for control characters. */ + +#define CTL(x) (x ^ 0100) /* Assumes ASCII dialect */ +#define CR CTL('M') /* carriage return */ +#define NL CTL('J') /* line feed */ +#define BS CTL('H') /* back space */ +#define DEL CTL('?') /* delete */ /* Parse the terminal speed. */ static void @@ -77,6 +90,89 @@ write (fd, s, cc); } +char * +get_login_name(int fd) +{ + size_t max_pw_size; + char *result; + char *ptr; + char c; + char done; + char *prompt; + int prompt_size; + char *hostname; + + max_pw_size = sysconf (_SC_GETPW_R_SIZE_MAX); + + if (!(result = malloc (max_pw_size + 1))) + { + syslog (LOG_ERR, "Failed to allocate memory for login name"); + exit (EXIT_FAILURE); + } + + hostname = localhost (); + prompt_size = asprintf (&prompt, "%s%s", hostname, LOGIN); + free (hostname); + write (fd, prompt, prompt_size); + free (prompt); + + /* flush pending input */ + sleep (1); + tcflush (fd, TCIFLUSH); + + for (ptr = result, done = 0; !done; /* void */) + { + if (read (fd, &c, 1) < 1) + { + if (errno == EINTR || errno == EIO) + exit (EXIT_FAILURE); + } + + switch (c) + { + case CR: + case NL: + *ptr = 0; /* terminate logname */ + done = 1; + break; + case BS: + case DEL: + case '#': + if (ptr > result) + { + write (fd, "\b", 1); + ptr--; + } + break; + case CTL('U'): + case '@': + while (ptr > result) + { + write (fd, "\b", 1); + ptr--; + } + break; + case CTL('D'): + exit (EXIT_SUCCESS); + default: + if (!isascii (c) || !isprint (c)) + { + /* ignore garbage characters */ + } + else if (ptr - result > max_pw_size) + { + /* input overrun, dropping character */ + } + else + { + *ptr++ = c; /* and store it */ + } + break; + } + } + return result; +} + int main (int argc, char **argv) { @@ -84,6 +180,7 @@ int tty; struct ttyent *tt; char *arg; + char *login_name; openlog ("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH); @@ -121,6 +218,7 @@ set_speed (tty, linespec); print_banner (tty, ttyname); + login_name = get_login_name(tty); if (login_tty (tty) == -1) syslog (LOG_ERR, "cannot set controlling terminal to %s: %m", ttyname); @@ -129,10 +227,12 @@ if (tt && strcmp (tt->ty_type, "dialup") == 0) /* Dialup lines time out (which is login's default). */ - execl (_PATH_LOGIN, "login", "-e", arg, NULL); + execl (_PATH_LOGIN, "login", "--paranoid", "-e", arg, + login_name, NULL); else /* Hardwired lines don't. */ - execl (_PATH_LOGIN, "login", "-e", arg, "-aNOAUTH_TIMEOUT", NULL); + execl (_PATH_LOGIN, "login", "--paranoid", "-e", arg, + "-aNOAUTH_TIMEOUT", login_name, NULL); syslog (LOG_ERR, "%s: %m", _PATH_LOGIN);
Attachment:
signature.asc
Description: PGP signature