[finsh] Add password authentication. Increased input security.

This commit is contained in:
armink 2016-11-26 15:23:12 +08:00
parent 8b5db10f78
commit 8ff7529039
2 changed files with 116 additions and 1 deletions

View File

@ -174,6 +174,91 @@ rt_uint32_t finsh_get_echo()
return shell->echo_mode; 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) static void shell_auto_complete(char *prefix)
{ {
@ -305,7 +390,6 @@ void finsh_thread_entry(void *parameter)
#ifndef FINSH_USING_MSH_ONLY #ifndef FINSH_USING_MSH_ONLY
finsh_init(&shell->parser); finsh_init(&shell->parser);
#endif #endif
rt_kprintf(FINSH_PROMPT);
/* set console device as shell device */ /* set console device as shell device */
if (shell->device == RT_NULL) if (shell->device == RT_NULL)
@ -320,6 +404,16 @@ void finsh_thread_entry(void *parameter)
#endif #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) while (1)
{ {
/* wait receive */ /* wait receive */

View File

@ -68,6 +68,18 @@ const char* finsh_get_prompt(void);
#endif #endif
#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 enum input_stat
{ {
WAIT_NORMAL, WAIT_NORMAL,
@ -98,6 +110,10 @@ struct finsh_shell
rt_uint8_t line_curpos; rt_uint8_t line_curpos;
rt_device_t device; rt_device_t device;
#ifdef FINSH_USING_AUTH
char password[FINSH_PASSWORD_MAX];
#endif
}; };
void finsh_set_echo(rt_uint32_t echo); 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); void finsh_set_device(const char* device_name);
const char* finsh_get_device(void); 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 #endif