summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorarmink <[email protected]>2016-11-26 15:23:12 +0800
committerarmink <[email protected]>2016-11-26 15:23:12 +0800
commit8ff75290391c02e92a9b3510b72c1495da25cd13 (patch)
treecbe4e1399fffb0750bb9c35e24f0ddbbc9b53de6 /components
parent8b5db10f7888482b0572a411c94c6d00de2c2df1 (diff)
[finsh] Add password authentication. Increased input security.
Diffstat (limited to 'components')
-rw-r--r--components/finsh/shell.c96
-rw-r--r--components/finsh/shell.h21
2 files changed, 116 insertions, 1 deletions
diff --git a/components/finsh/shell.c b/components/finsh/shell.c
index ae0934f5d1..83709560b1 100644
--- a/components/finsh/shell.c
+++ b/components/finsh/shell.c
@@ -174,6 +174,91 @@ rt_uint32_t finsh_get_echo()
return shell->echo_mode;
}
+#ifdef FINSH_USING_AUTH
+/**
+ * set a new password for finsh
+ *
+ * @param password new password
+ *
+ * @return result, RT_EOK on OK, -RT_ERROR on the new password length is less than FINSH_PASSWORD_MIN
+ */
+rt_err_t finsh_set_password(const char *password) {
+ rt_ubase_t level;
+
+ if (rt_strlen(password) < FINSH_PASSWORD_MIN)
+ return -RT_ERROR;
+
+ level = rt_hw_interrupt_disable();
+ rt_strncpy(shell->password, password, FINSH_PASSWORD_MAX);
+ rt_hw_interrupt_enable(level);
+
+ return RT_EOK;
+}
+
+/**
+ * get the finsh password
+ *
+ * @return password
+ */
+const char *finsh_get_password(void)
+{
+ return shell->password;
+}
+
+static void finsh_wait_auth(void)
+{
+ char ch;
+ rt_bool_t input_finish = RT_FALSE;
+ char password[FINSH_PASSWORD_MAX] = { 0 };
+ rt_size_t cur_pos = 0;
+ while (1)
+ {
+ rt_kprintf("Password for finsh: ");
+ while (!input_finish)
+ {
+ /* wait receive */
+ if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;
+
+ /* read one character from device */
+ while (rt_device_read(shell->device, 0, &ch, 1) == 1)
+ {
+ if (ch >= ' ' && ch <= '~' && cur_pos < FINSH_PASSWORD_MAX)
+ {
+ /* change the printable characters to '*' */
+ rt_kprintf("*");
+ password[cur_pos++] = ch;
+ }
+ else if (ch == '\b' && cur_pos > 0)
+ {
+ /* backspace */
+ password[cur_pos] = '\0';
+ cur_pos--;
+ rt_kprintf("\b \b");
+ }
+ else if (ch == '\r' || ch == '\n')
+ {
+ rt_kprintf("\n");
+ input_finish = RT_TRUE;
+ break;
+ }
+ }
+ }
+ if (!rt_strncmp(shell->password, password, FINSH_PASSWORD_MAX)) return;
+ else
+ {
+ /* authentication failed, delay 2S for retry */
+ rt_thread_delay(2 * RT_TICK_PER_SECOND);
+ rt_kprintf("Sorry, try again.\n");
+ cur_pos = 0;
+ input_finish = RT_FALSE;
+ rt_memset(password, '\0', FINSH_PASSWORD_MAX);
+ /* read all last dirty data */
+ while (rt_device_read(shell->device, 0, &ch, 1) == 1);
+ }
+ }
+}
+#endif /* FINSH_USING_AUTH */
+
static void shell_auto_complete(char *prefix)
{
@@ -305,7 +390,6 @@ void finsh_thread_entry(void *parameter)
#ifndef FINSH_USING_MSH_ONLY
finsh_init(&shell->parser);
#endif
- rt_kprintf(FINSH_PROMPT);
/* set console device as shell device */
if (shell->device == RT_NULL)
@@ -320,6 +404,16 @@ void finsh_thread_entry(void *parameter)
#endif
}
+#ifdef FINSH_USING_AUTH
+ /* set the default password when the password isn't setting */
+ if (rt_strlen(finsh_get_password()) == 0)
+ finsh_set_password(FINSH_DEFAULT_PASSWORD);
+ /* waiting authenticate success */
+ finsh_wait_auth();
+#endif
+
+ rt_kprintf(FINSH_PROMPT);
+
while (1)
{
/* wait receive */
diff --git a/components/finsh/shell.h b/components/finsh/shell.h
index 751590366a..a4c96b9a26 100644
--- a/components/finsh/shell.h
+++ b/components/finsh/shell.h
@@ -68,6 +68,18 @@ const char* finsh_get_prompt(void);
#endif
#endif
+#ifdef FINSH_USING_AUTH
+ #ifndef FINSH_PASSWORD_MAX
+ #define FINSH_PASSWORD_MAX RT_NAME_MAX
+ #endif
+ #ifndef FINSH_PASSWORD_MIN
+ #define FINSH_PASSWORD_MIN 6
+ #endif
+ #ifndef FINSH_DEFAULT_PASSWORD
+ #define FINSH_DEFAULT_PASSWORD "rtthread"
+ #endif
+#endif /* FINSH_USING_AUTH */
+
enum input_stat
{
WAIT_NORMAL,
@@ -98,6 +110,10 @@ struct finsh_shell
rt_uint8_t line_curpos;
rt_device_t device;
+
+#ifdef FINSH_USING_AUTH
+ char password[FINSH_PASSWORD_MAX];
+#endif
};
void finsh_set_echo(rt_uint32_t echo);
@@ -107,4 +123,9 @@ int finsh_system_init(void);
void finsh_set_device(const char* device_name);
const char* finsh_get_device(void);
+#ifdef FINSH_USING_AUTH
+rt_err_t finsh_set_password(const char *password);
+const char *finsh_get_password(void);
+#endif
+
#endif