diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-03-27 15:31:52 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-03-27 15:31:52 +0000 |
commit | 2649eef33ab4947ad690a90e381056e285d46635 (patch) | |
tree | b6332f7070186571127312c36f155cc3ea405b1c /cpukit/libmisc | |
parent | 2009-03-27 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff) | |
download | rtems-2649eef33ab4947ad690a90e381056e285d46635.tar.bz2 |
2009-03-27 Sebastian Huber <sebastian.huber@embedded-brains.de>
* Makefile.am, preinstall.am, libmisc/Makefile.am,
libmisc/shell/shell.c, libmisc/shell/shell.h, telnetd/check_passwd.c,
telnetd/telnetd.c, telnetd/telnetd.h:
Generalized login check.
* libmisc/shell/login.h, libmisc/shell/login_check.c,
libmisc/shell/login_prompt.c: New files.
* libmisc/stackchk/check.c: Changed format for blown stack message.
* libcsupport/src/libio_sockets.c: Removed superfluous cast.
* libnetworking/rtems/ftpfs.h: Documentation.
Diffstat (limited to 'cpukit/libmisc')
-rw-r--r-- | cpukit/libmisc/shell/login.h | 56 | ||||
-rw-r--r-- | cpukit/libmisc/shell/login_check.c | 58 | ||||
-rw-r--r-- | cpukit/libmisc/shell/login_prompt.c | 162 |
3 files changed, 276 insertions, 0 deletions
diff --git a/cpukit/libmisc/shell/login.h b/cpukit/libmisc/shell/login.h new file mode 100644 index 0000000000..3e107825d4 --- /dev/null +++ b/cpukit/libmisc/shell/login.h @@ -0,0 +1,56 @@ +/** + * @file + * + * @author Sebastian Huber <sebastian.huber@embedded-brains.de> + * + * @brief Login types and functions. + */ + +/* + * Copyright (c) 2009 + * 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. + * + * 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. + */ + +#ifndef RTEMS_LOGIN_H +#define RTEMS_LOGIN_H + +#include <stdio.h> + +#include <rtems.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef bool (*rtems_login_check)( + const char * /* user */, + const char * /* passphrase */ +); + +bool rtems_shell_login_prompt( + FILE *in, + FILE *out, + const char *device, + rtems_login_check check +); + +bool rtems_shell_login_check( + const char *user, + const char *passphrase +); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* RTEMS_LOGIN_H */ diff --git a/cpukit/libmisc/shell/login_check.c b/cpukit/libmisc/shell/login_check.c new file mode 100644 index 0000000000..066ab16b61 --- /dev/null +++ b/cpukit/libmisc/shell/login_check.c @@ -0,0 +1,58 @@ +/** + * @file + * + * @author Sebastian Huber <sebastian.huber@embedded-brains.de> + * + * @brief Shell login check function. + */ + +/* + * Copyright (c) 2009 + * 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. + * + * 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. + */ + +#include <sys/types.h> +#include <unistd.h> +#include <pwd.h> + +#include <rtems/login.h> +#include <rtems/shell.h> +#include <rtems/userenv.h> + +bool rtems_shell_login_check( + const char *user, + const char *passphrase +) +{ + struct passwd *pw = getpwnam( user); + + /* Valid user? */ + if (pw != NULL && strcmp( pw->pw_passwd, "!") != 0) { + setuid( pw->pw_uid); + setgid( pw->pw_gid); + rtems_current_user_env->euid = 0; + rtems_current_user_env->egid = 0; + chown( rtems_current_shell_env->devname, pw->pw_uid, 0); + rtems_current_user_env->euid = pw->pw_uid; + rtems_current_user_env->egid = pw->pw_gid; + if (strcmp( pw->pw_passwd, "*") == 0) { + /* TODO: /etc/shadow */ + return true; + } else { + /* TODO: crypt() */ + return true; + } + } + + return false; +} diff --git a/cpukit/libmisc/shell/login_prompt.c b/cpukit/libmisc/shell/login_prompt.c new file mode 100644 index 0000000000..fd347fb728 --- /dev/null +++ b/cpukit/libmisc/shell/login_prompt.c @@ -0,0 +1,162 @@ +/** + * @file + * + * @author Sebastian Huber <sebastian.huber@embedded-brains.de> + * + * @brief Shell login prompt functions. + */ + +/* + * Copyright (c) 2009 + * 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. + * + * 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. + */ + +#include <stdio.h> +#include <termios.h> +#include <unistd.h> +#include <ctype.h> + +#include <rtems/login.h> + +static int rtems_shell_discard( int c, FILE *stream) +{ + return c; +} + +static void 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; + } + + tcdrain( fd_in); + if (out != NULL){ + tcdrain( fileno( out)); + } + + while (true) { + int c = fgetc( in); + + switch (c) { + case EOF: + /* Here comes an ugly hack: The Termios driver's read() handler returns + * 0 to the C library's fgets() if it times out. fgets() interprets + * this (correctly) as EOF, a condition we want to undo since it's not + * really true since we really have a read error (Termios bug?). + * + * As a workaround we push something back and read it again. This + * should simply reset the EOF condition. + */ + if (ungetc( '?', in) == '?') { + fgetc( in); + } + break; + case '\n': + case '\r': + put( '\n', out); + line [i] = '\0'; + return; + 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; + } + } +} + +bool rtems_shell_login_prompt( + FILE *in, + FILE *out, + const char *device, + rtems_login_check 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; + + termios_new.c_lflag &= ~ECHO; + termios_new.c_lflag &= ~ICANON; + termios_new.c_cc [VTIME] = 255; + termios_new.c_cc [VMIN] = 0; + + 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); + rtems_shell_get_text( in, out, user, sizeof( user)); + + fflush( in); + fprintf( out, "Password: "); + fflush( out); + rtems_shell_get_text( in, NULL, passphrase, sizeof( passphrase)); + 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; +} |