diff options
Diffstat (limited to 'cpukit/libmisc/shell/login_prompt.c')
-rw-r--r-- | cpukit/libmisc/shell/login_prompt.c | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/cpukit/libmisc/shell/login_prompt.c b/cpukit/libmisc/shell/login_prompt.c new file mode 100644 index 0000000000..7e93078805 --- /dev/null +++ b/cpukit/libmisc/shell/login_prompt.c @@ -0,0 +1,209 @@ +/** + * @file + * + * @brief Shell login prompt functions. + */ + +/* + * Authorship + * ---------- + * Parts of this software was created by + * Till Straumann <strauman@slac.stanford.edu>, 2003-2007 + * Stanford Linear Accelerator Center, Stanford University. + * + * Acknowledgement of sponsorship + * ------------------------------ + * Parts of this software was produced by + * the Stanford Linear Accelerator Center, Stanford University, + * under Contract DE-AC03-76SFO0515 with the Department of Energy. + * + * Government disclaimer of liability + * ---------------------------------- + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, or + * assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately owned + * rights. + * + * Stanford disclaimer of liability + * -------------------------------- + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * Stanford disclaimer of copyright + * -------------------------------- + * Stanford University, owner of the copyright, hereby disclaims its + * copyright and all other rights in this software. Hence, anyone may + * freely use it for any purpose without restriction. + * + * Maintenance of notices + * ---------------------- + * In the interest of clarity regarding the origin and status of this + * SLAC software, this and all the preceding Stanford University notices + * are to remain affixed to any copy or derivative of this software made + * or distributed by the recipient and are to be affixed to any copy of + * software made or distributed by the recipient that contains a copy or + * derivative of this software. + * + * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 + * + * Copyright (c) 2009 embedded brains GmbH and others. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * Based on work from Chris Johns, Fernando Ruiz and Till Straumann. + * + * Derived from files "cpukit/libmisc/shell/shell.c" and + * "cpukit/telnetd/check_passwd.c". + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <termios.h> +#include <unistd.h> +#include <ctype.h> +#include <errno.h> + +#include <rtems/shell.h> + +static int rtems_shell_discard( int c, FILE *stream) +{ + return c; +} + +static bool rtems_shell_get_text( + FILE *in, + FILE *out, + char *line, + size_t size +) +{ + int fd_in = fileno( in); + int (*put)( int, FILE *) = + out != NULL && isatty( fd_in) + ? fputc + : rtems_shell_discard; + size_t i = 0; + + if (size < 1) { + return false; + } + + tcdrain( fd_in); + if (out != NULL){ + tcdrain( fileno(out) ); + } + + while (true) { + int c = fgetc(in); + + switch (c) { + case EOF: + clearerr( in ); + return false; + case '\n': + case '\r': + put('\n', out); + line [i] = '\0'; + return true; + case 127: + case '\b': + if (i > 0) { + put('\b', out); + put(' ', out); + put('\b', out); + --i; + } else { + put('\a', out); + } + break; + default: + if (!iscntrl( c)) { + if (i < size - 1) { + line [i] = (char) c; + ++i; + put( c, out); + } else { + put('\a', out); + } + } else { + put('\a', out); + } + break; + } + } + return true; +} + +bool rtems_shell_login_prompt( + FILE *in, + FILE *out, + const char *device, + rtems_shell_login_check_t check +) +{ + int fd_in = fileno(in); + struct termios termios_previous; + bool restore_termios = false; + int i = 0; + bool result = false; + + if (tcgetattr( fd_in, &termios_previous) == 0) { + struct termios termios_new = termios_previous; + + /* + * Stay in canonical mode so we can tell EOF and dropped connections. + * But read one character at a time and do not echo it. + */ + termios_new.c_lflag &= (unsigned char) ~ECHO; + termios_new.c_cc [VTIME] = 0; + termios_new.c_cc [VMIN] = 1; + + restore_termios = tcsetattr( fd_in, TCSANOW, &termios_new) == 0; + } + + for (i = 0; i < 3; ++i) { + char user [32]; + char passphrase [128]; + + fprintf( out, "%s login: ", device ); + fflush( out ); + result = rtems_shell_get_text( in, out, user, sizeof(user) ); + if ( !result ) + break; + + fflush( in); + fprintf( out, "Password: "); + fflush( out); + result = rtems_shell_get_text( in, NULL, passphrase, sizeof(passphrase) ); + if ( !result ) + break; + fputc( '\n', out); + + result = check( user, passphrase ); + if (result) + break; + + fprintf( out, "Login incorrect\n\n"); + sleep( 2); + } + + if (restore_termios) { + /* What to do if restoring the flags fails? */ + tcsetattr( fd_in, TCSANOW, &termios_previous); + } + + return result; +} |