From c78ef640cd18847a962d3e1fdb84ad6c265b0deb Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 10 Aug 2011 12:47:08 +0200 Subject: login: add timeout support If a timeout is specified and expired the command will be executed by default boot Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Sascha Hauer --- commands/login.c | 26 ++++++++++++++-- commands/passwd.c | 4 +-- common/password.c | 87 ++++++++++++++++++++++++++++++------------------------ include/password.h | 2 +- 4 files changed, 74 insertions(+), 45 deletions(-) diff --git a/commands/login.c b/commands/login.c index 7d99b73921..610fb9ed73 100644 --- a/commands/login.c +++ b/commands/login.c @@ -21,6 +21,7 @@ #include #include #include +#include #define PASSWD_MAX_LENGTH (128 + 1) @@ -35,16 +36,32 @@ static int do_login(struct command *cmdtp, int argc, char *argv[]) { unsigned char passwd[PASSWD_MAX_LENGTH]; - int passwd_len; + int passwd_len, opt; + int timeout = 0; + char *timeout_cmd = "boot"; if (!is_passwd_enable()) { puts("login: password not set\n"); return 0; } + while((opt = getopt(argc, argv, "t:")) > 0) { + switch(opt) { + case 't': + timeout = simple_strtoul(optarg, NULL, 10); + break; + } + } + + if (optind != argc) + timeout_cmd = argv[optind]; + do { puts("Password: "); - passwd_len = password(passwd, PASSWD_MAX_LENGTH, LOGIN_MODE); + passwd_len = password(passwd, PASSWD_MAX_LENGTH, LOGIN_MODE, timeout); + + if (passwd_len < 0) + run_command(timeout_cmd, 0); if (check_passwd(passwd, passwd_len)) return 0; @@ -54,7 +71,10 @@ static int do_login(struct command *cmdtp, int argc, char *argv[]) } static const __maybe_unused char cmd_login_help[] = -""; +"Usage: login [[-t timeout] ]\n" +"If a timeout is specified and expired the command will be executed\n" +"by default boot\n" +; BAREBOX_CMD_START(login) .cmd = do_login, diff --git a/commands/passwd.c b/commands/passwd.c index 94350911df..9a0787372a 100644 --- a/commands/passwd.c +++ b/commands/passwd.c @@ -42,13 +42,13 @@ static int do_passwd(struct command *cmdtp, int argc, char *argv[]) int ret = 1; puts("Enter new password: "); - passwd1_len = password(passwd1, PASSWD_MAX_LENGTH, PASSWD_MODE); + passwd1_len = password(passwd1, PASSWD_MAX_LENGTH, PASSWD_MODE, 0); if (passwd1_len < 0) return 1; puts("Retype new password: "); - passwd2_len = password(passwd2, PASSWD_MAX_LENGTH, PASSWD_MODE); + passwd2_len = password(passwd2, PASSWD_MAX_LENGTH, PASSWD_MODE, 0); if (passwd2_len < 0) return 1; diff --git a/common/password.c b/common/password.c index 20e398fc17..ece7704786 100644 --- a/common/password.c +++ b/common/password.c @@ -27,6 +27,7 @@ #include #include #include +#include #if defined(CONFIG_PASSWD_SUM_MD5) #define PASSWD_SUM "md5" @@ -36,56 +37,64 @@ #define PASSWD_SUM "sha256" #endif -int password(unsigned char *passwd, size_t length, int flags) +int password(unsigned char *passwd, size_t length, int flags, int timeout) { unsigned char *buf = passwd; int pos = 0; unsigned char ch; + uint64_t start, second; if (!passwd) return -EINVAL; + start = get_time_ns(); + second = start; + do { - ch = getc(); - - switch (ch) { - case '\r': - case '\n': - *buf = '\0'; - puts("\r\n"); - return pos; - case '\0': - case '\t': - continue; - case CTL_CH('c'): - passwd[0] = '\0'; - puts("\r\n"); - return 0; - case CTL_CH('h'): - case KEY_DEL7: - case KEY_DEL: - if (flags & STAR && pos > 0) - puts("\b \b"); - *buf = '\0'; - buf--; - pos--; - continue; - default: - if (pos < length - 1) { - if (flags & STAR) - putchar('*'); - else if (flags & CLEAR) - putchar(ch); - - *buf = ch; - buf++; - pos++; - } else { - if (flags & STAR) - putchar('\a'); + if (tstc()) { + ch = getc(); + + switch (ch) { + case '\r': + case '\n': + *buf = '\0'; + puts("\r\n"); + return pos; + case '\0': + case '\t': + continue; + case CTL_CH('c'): + passwd[0] = '\0'; + puts("\r\n"); + return 0; + case CTL_CH('h'): + case KEY_DEL7: + case KEY_DEL: + if (flags & STAR && pos > 0) + puts("\b \b"); + *buf = '\0'; + buf--; + pos--; + continue; + default: + if (pos < length - 1) { + if (flags & STAR) + putchar('*'); + else if (flags & CLEAR) + putchar(ch); + + *buf = ch; + buf++; + pos++; + } else { + if (flags & STAR) + putchar('\a'); + } } } - } while(1); + } while (!is_timeout(start, timeout * SECOND) || timeout == 0); + + return -1; } EXPORT_SYMBOL(password); diff --git a/include/password.h b/include/password.h index 32301eb482..540ab05d45 100644 --- a/include/password.h +++ b/include/password.h @@ -28,7 +28,7 @@ #define STAR (1 << 1) #define CLEAR (1 << 2) -int password(unsigned char *passwd, size_t length, int flags); +int password(unsigned char *passwd, size_t length, int flags, int timeout); int read_passwd(unsigned char *sum, size_t length); int write_passwd(unsigned char *sum, size_t length); -- cgit v1.2.3