From c36fc5c3f201ba8eb1fa12eb0a10af9904277d7b Mon Sep 17 00:00:00 2001 From: Pete Skeggs Date: Thu, 4 Mar 2021 11:28:05 -0800 Subject: [PATCH] shell: add obscured input mode Add flag to shell_flags to control echo as obscure character (for passwords) or not. Add setter and getter functions. Modify shell echo to use this flag if set. Also add public setter for color mode and obscure mode. Signed-off-by: Pete Skeggs --- include/shell/shell.h | 25 +++++++++++++++++++++++++ subsys/shell/Kconfig | 7 +++++++ subsys/shell/shell.c | 23 +++++++++++++++++++++++ subsys/shell/shell_ops.c | 15 +++++++++++++-- subsys/shell/shell_ops.h | 10 ++++++++++ 5 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/shell/shell.h b/include/shell/shell.h index 7ef1e8686a8..e86cffac6e5 100644 --- a/include/shell/shell.h +++ b/include/shell/shell.h @@ -608,6 +608,7 @@ struct shell_flags { uint32_t insert_mode :1; /*!< Controls insert mode for text introduction.*/ uint32_t use_colors :1; /*!< Controls colored syntax.*/ uint32_t echo :1; /*!< Controls shell echo.*/ + uint32_t obscure :1; /*!< If echo on, print asterisk instead */ uint32_t processing :1; /*!< Shell is executing process function.*/ uint32_t tx_rdy :1; uint32_t mode_delete :1; /*!< Operation mode of backspace key */ @@ -1034,6 +1035,30 @@ int shell_execute_cmd(const struct shell *shell, const char *cmd); */ int shell_set_root_cmd(const char *cmd); +/** + * @brief Allow application to control whether terminal output uses colored + * syntax. + * + * @param[in] shell Pointer to the shell instance. + * @param[in] use_colors Color mode. + * + * @retval 0 if set. + * @retval -EINVAL if shell is NULL. + */ +int shell_use_colors_set(const struct shell *shell, bool use_colors); + +/** + * @brief Allow application to control whether user input is obscured with + * asterisks -- useful for implementing passwords. + * + * @param[in] shell Pointer to the shell instance. + * @param[in] obscure Obscure mode. + * + * @retval 0 if set. + * @retval -EINVAL if shell is NULL. + */ +int shell_obscure_set(const struct shell *shell, bool obscure); + /** * @} */ diff --git a/subsys/shell/Kconfig b/subsys/shell/Kconfig index 5d30fa691ee..950b32f1480 100644 --- a/subsys/shell/Kconfig +++ b/subsys/shell/Kconfig @@ -103,6 +103,13 @@ config SHELL_ECHO_STATUS help If enabled shell prints back every input byte. +config SHELL_START_OBSCURED + bool "Display asterisk when echoing" + default n + help + If enabled, don't echo actual character, but echo * instead. + This is used for login prompts. + config SHELL_VT100_COLORS bool "Enable colors in shell" default y if !SHELL_MINIMAL diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index c063829e3e6..7703856fb4d 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1166,6 +1166,7 @@ static int instance_init(const struct shell *shell, const void *p_config, z_flag_tx_rdy_set(shell, true); z_flag_echo_set(shell, IS_ENABLED(CONFIG_SHELL_ECHO_STATUS)); + z_flag_obscure_set(shell, IS_ENABLED(CONFIG_SHELL_START_OBSCURED)); z_flag_mode_delete_set(shell, IS_ENABLED(CONFIG_SHELL_BACKSPACE_MODE_DELETE)); shell->ctx->vt100_ctx.cons.terminal_wid = @@ -1559,6 +1560,28 @@ int shell_execute_cmd(const struct shell *shell, const char *cmd) return ret_val; } +int shell_use_colors_set(const struct shell *shell, bool use_colors) +{ + if (shell == NULL) { + return -EINVAL; + } + + z_flag_use_colors_set(shell, use_colors); + + return 0; +} + +int shell_obscure_set(const struct shell *shell, bool obscure) +{ + if (shell == NULL) { + return -EINVAL; + } + + z_flag_obscure_set(shell, obscure); + + return 0; +} + static int cmd_help(const struct shell *shell, size_t argc, char **argv) { ARG_UNUSED(argc); diff --git a/subsys/shell/shell_ops.c b/subsys/shell/shell_ops.c index ec694f8334c..d2a2a4048c8 100644 --- a/subsys/shell/shell_ops.c +++ b/subsys/shell/shell_ops.c @@ -223,8 +223,16 @@ static void reprint_from_cursor(const struct shell *shell, uint16_t diff, z_clear_eos(shell); } - z_shell_fprintf(shell, SHELL_NORMAL, "%s", - &shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos]); + if (z_flag_obscure_get(shell)) { + int len = strlen(&shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos]); + + while (len--) { + z_shell_raw_fprintf(shell->fprintf_ctx, "*"); + } + } else { + z_shell_fprintf(shell, SHELL_NORMAL, "%s", + &shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos]); + } shell->ctx->cmd_buff_pos = shell->ctx->cmd_buff_len; if (full_line_cmd(shell)) { @@ -265,6 +273,9 @@ static void char_replace(const struct shell *shell, char data) if (!z_flag_echo_get(shell)) { return; } + if (z_flag_obscure_get(shell)) { + data = '*'; + } z_shell_raw_fprintf(shell->fprintf_ctx, "%c", data); if (z_shell_cursor_in_empty_line(shell)) { diff --git a/subsys/shell/shell_ops.h b/subsys/shell/shell_ops.h index d905ae32fa7..8750fc6d8a1 100644 --- a/subsys/shell/shell_ops.h +++ b/subsys/shell/shell_ops.h @@ -90,6 +90,16 @@ static inline void z_flag_echo_set(const struct shell *shell, bool val) shell->ctx->internal.flags.echo = val ? 1 : 0; } +static inline bool z_flag_obscure_get(const struct shell *shell) +{ + return shell->ctx->internal.flags.obscure == 1; +} + +static inline void z_flag_obscure_set(const struct shell *shell, bool val) +{ + shell->ctx->internal.flags.obscure = val ? 1 : 0; +} + static inline bool z_flag_processing_get(const struct shell *shell) { return shell->ctx->internal.flags.processing == 1;