NSH: Add option to use platform-specific logic to verify login credentials; Add option to add a delay after each failed login attempt

This commit is contained in:
Gregory Nutt 2016-01-22 10:46:19 -06:00
parent 1decdb2afc
commit 0720f9a357
11 changed files with 152 additions and 26 deletions

View File

@ -1520,4 +1520,7 @@
the encrypted password in /etc/passwd (2016-01-20).
* apps/fsutils/inifile: Move system/inifile to fsutils/inifile
where it seems to fit in better (2016-01-20).
* apps/nshlib: Extend logins. Added: Optional platform-specific
function to perform password verification and optionsl delay
after each failed login attempt (2016-01-22).

View File

@ -158,6 +158,49 @@ int nsh_consolemain(int argc, char *argv[]);
int nsh_telnetstart(void);
/****************************************************************************
* Name: platform_motd
*
* Description:
* If CONFIG_NSH_PLATFORM_MOTD is defined, then platform-specific logic
* must provide this function in order to obtain the Message of the Day
* (MOTD)
*
* Input Parmeters:
* buffer - A caller allocated buffer in which to receive the MOTD
* buflen - The length in bytes of the caller allocated buffer
*
* Returned value:
* None
*
****************************************************************************/
#ifdef CONFIG_NSH_PLATFORM_MOTD
void platform_motd(FAR char *buffer, size_t buflen);
#endif
/****************************************************************************
* Name: platform_user_verify
*
* Description:
* If CONFIG_NSH_LOGIN_PLATFORM is defined, then platform-specific logic
* must provide this function in order verify user credentials as part of
* the login process.
*
* Input Parmeters:
* username/password - User credentials to be verified.
*
* Returned value:
* 1 - The user credentials are verified
* 0 - The user credentials are incorrect
* <0 - An error occurred. The returned value is a negated errno number.
*
****************************************************************************/
#ifdef CONFIG_NSH_LOGIN_PLATFORM
int platform_user_verify(FAR const char *username, FAR const char *password);
#endif
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -43,6 +43,11 @@ config NSH_PLATFORM_MOTD
One newline will be inserted after the platform-supplied message.
platform_motd() is prototyped and described in apps/include/nsh.h
which may be included like:
#include <apps/nsh.h>
config NSH_MOTD_STRING
string "MOTD String"
default "No MOTD string provided"
@ -379,7 +384,7 @@ config NSH_DISABLE_NSLOOKUP
config NSH_DISABLE_PASSWD
bool "Disable passwd"
default y
depends on FSUTILS_PASSWD && FS_WRITABLE && !FSUTILS_PASSWD_READONLY
depends on NSH_LOGIN_PASSWD && FS_WRITABLE && !FSUTILS_PASSWD_READONLY
config NSH_DISABLE_POWEROFF
bool "Disable poweroff"
@ -475,12 +480,12 @@ config NSH_DISABLE_URLENCODE
config NSH_DISABLE_USERADD
bool "Disable useradd"
default y
depends on FSUTILS_PASSWD && FS_WRITABLE && !FSUTILS_PASSWD_READONLY
depends on NSH_LOGIN_PASSWD && FS_WRITABLE && !FSUTILS_PASSWD_READONLY
config NSH_DISABLE_USERDEL
bool "Disable userdel"
default y
depends on FSUTILS_PASSWD && FS_WRITABLE && !FSUTILS_PASSWD_READONLY
depends on NSH_LOGIN_PASSWD && FS_WRITABLE && !FSUTILS_PASSWD_READONLY
config NSH_DISABLE_USLEEP
bool "Disable usleep"
@ -1468,22 +1473,70 @@ config NSH_TELNET_LOGIN
if NSH_LOGIN
choice
prompt "Verification method"
default NSH_LOGIN_PASSWD if FSUTILS_PASSWD
default NSH_LOGIN_FIXED if !FSUTILS_PASSWD
config NSH_LOGIN_FIXED
bool "Fixed username/password"
---help---
Verify user credentials by matching to fixed username and password
strings
config NSH_LOGIN_PLATFORM
bool "Platform username/password"
---help---
Call a platform-specific function to perform the verification of
user credentials. In this case, the platform-specific logic must
provide a function with the following prototype:
int platform_user_verify(FAR const char *username, FAR const char *password);
which is prototyped an described in apps/include/nsh.h and which may
be included like:
#include <apps/nsh.h>
An appropriate place to implement this function might be in the
directory apps/platform/<board>.
config NSH_LOGIN_PASSWD
bool "Encrypted password file"
depends on FSUTILS_PASSWD
---help---
Use the content of an encrypted password file to verify user
credentials. This option requires that you have selected
CONFIG_FSUTILS_PASSWD to enable the access methods of
apps/fsutils/passwd.
endchoice # Verification method
config NSH_LOGIN_USERNAME
string "Login Username"
string "Login username"
default "admin"
depends on !FSUTILS_PASSWD
depends on !NSH_LOGIN_PASSWD
---help---
Login user name. Default: "admin"
config NSH_LOGIN_PASSWORD
string "Login Password"
string "Login password"
default "Administrator"
depends on !FSUTILS_PASSWD
depends on !NSH_LOGIN_PASSWD
---help---
Login password: Default: "Administrator"
config NSH_LOGIN_FAILDELAY
int "Login failure delay"
default 0
---help---
Login failure delay in milliseconds. The system will pause this
amount of time after each failed login attempt in order to
discourage people from cracking the password by brute force. The
value zero may be supplied to disable the delay.
config NSH_LOGIN_FAILCOUNT
int "Login Retry Count"
int "Login retry count"
default 3
---help---
Number of login retry attempts.

View File

@ -120,11 +120,10 @@ ifeq ($(CONFIG_NETUTILS_CODECS),y)
CSRCS += nsh_codeccmd.c
endif
ifeq ($(CONFIG_FSUTILS_PASSWD),y)
ifeq ($(CONFIG_NSH_LOGIN_PASSWD),y)
CSRCS += nsh_passwdcmds.c
endif
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))

View File

@ -1179,7 +1179,7 @@ Command Dependencies on Configuration Settings
mv (((!CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_WRITABLE) || !CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_DESCRIPTORS > 0) (see note 4)
nfsmount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET && CONFIG_NFS
nslookup CONFIG_LIBC_NETDB && CONFIG_NETDB_DNSCLIENT
password !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_WRITABLE && CONFIG_FSUTILS_PASSWD
password !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_WRITABLE && CONFIG_NSH_LOGIN_PASSWD
ping CONFIG_NET && CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING && !CONFIG_DISABLE_SIGNALS
ping6 CONFIG_NET && CONFIG_NET_ICMPv6 && CONFIG_NET_ICMPv6_PING && !CONFIG_DISABLE_SIGNALS
poweroff CONFIG_BOARDCTL_POWEROFF
@ -1201,8 +1201,8 @@ Command Dependencies on Configuration Settings
unset !CONFIG_DISABLE_ENVIRON
urldecode CONFIG_NETUTILS_CODECS && CONFIG_CODECS_URLCODE
urlencode CONFIG_NETUTILS_CODECS && CONFIG_CODECS_URLCODE
useradd !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_WRITABLE && CONFIG_FSUTILS_PASSWD
userdel !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_WRITABLE && CONFIG_FSUTILS_PASSWD
useradd !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_WRITABLE && CONFIG_NSH_LOGIN_PASSWD
userdel !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_WRITABLE && CONFIG_NSH_LOGIN_PASSWD
usleep !CONFIG_DISABLE_SIGNALS
get CONFIG_NET && CONFIG_NET_TCP && CONFIG_NFILE_DESCRIPTORS > 0
xd ---

View File

@ -1068,7 +1068,7 @@ int cmd_lsmod(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
int cmd_mksmartfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# endif /* CONFIG_FS_SMARTFS */
# if defined(CONFIG_FSUTILS_PASSWD) && defined(CONFIG_FS_WRITABLE) && \
# if defined(CONFIG_NSH_LOGIN_PASSWD) && defined(CONFIG_FS_WRITABLE) && \
!defined(CONFIG_FSUTILS_PASSWD_READONLY)
# ifndef CONFIG_NSH_DISABLE_USERADD
int cmd_useradd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);

View File

@ -1,7 +1,7 @@
/****************************************************************************
* apps/nshlib/nsh_command.c
*
* Copyright (C) 2007-2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -352,7 +352,7 @@ static const struct cmdmap_s g_cmdmap[] =
#endif
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && \
defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FSUTILS_PASSWD) && \
defined(CONFIG_FS_WRITABLE) && defined(CONFIG_NSH_LOGIN_PASSWD) && \
!defined(CONFIG_FSUTILS_PASSWD_READONLY)
# ifndef CONFIG_NSH_DISABLE_PASSWD
{ "passwd", cmd_passwd, 3, 3, "<username> <password>" },
@ -481,7 +481,7 @@ static const struct cmdmap_s g_cmdmap[] =
#endif
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && \
defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FSUTILS_PASSWD) && \
defined(CONFIG_FS_WRITABLE) && defined(CONFIG_NSH_LOGIN_PASSWD) && \
!defined(CONFIG_FSUTILS_PASSWD_READONLY)
# ifndef CONFIG_NSH_DISABLE_USERADD
{ "useradd", cmd_useradd, 3, 3, "<username> <password>" },

View File

@ -201,13 +201,19 @@ int nsh_login(FAR struct console_stdio_s *pstate)
/* Verify the username and password */
#ifdef CONFIG_FSUTILS_PASSWD
#if defined(CONFIG_NSH_LOGIN_PASSWD)
ret = passwd_verify(username, password);
if (PASSWORD_VERIFY_MATCH(ret))
#else
#elif defined(CONFIG_NSH_LOGIN_PLATFORM)
ret = platform_user_verify(username, password);
if (PASSWORD_VERIFY_MATCH(ret))
#elif defined(CONFIG_NSH_LOGIN_FIXED)
if (strcmp(password, CONFIG_NSH_LOGIN_PASSWORD) == 0 &&
strcmp(username, CONFIG_NSH_LOGIN_USERNAME) == 0)
#else
# error No user verification method selected
#endif
{
fputs(g_loginsuccess, pstate->cn_outstream);
@ -218,6 +224,9 @@ int nsh_login(FAR struct console_stdio_s *pstate)
{
fputs(g_badcredentials, pstate->cn_outstream);
fflush(pstate->cn_outstream);
#if CONFIG_NSH_LOGIN_FAILDELAY > 0
usleep(CONFIG_NSH_LOGIN_FAILDELAY * 1000L);
#endif
}
}
}

View File

@ -45,7 +45,7 @@
#include "nsh_console.h"
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && \
defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FSUTILS_PASSWD) && \
defined(CONFIG_FS_WRITABLE) && defined(CONFIG_NSH_LOGIN_PASSWD) && \
!defined(CONFIG_FSUTILS_PASSWD_READONLY)
/****************************************************************************
@ -116,5 +116,5 @@ int cmd_passwd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
#endif /* !CONFIG_NSH_DISABLE_USERADD */
#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 &&
* CONFIG_FS_WRITABLE && CONFIG_FSUTILS_PASSWD &&
* CONFIG_FS_WRITABLE && CONFIG_NSH_LOGIN_PASSWD &&
* !CONFIG_FSUTILS_PASSWD_READONLY */

View File

@ -200,13 +200,19 @@ int nsh_stdlogin(FAR struct console_stdio_s *pstate)
/* Verify the username and password */
#ifdef CONFIG_FSUTILS_PASSWD
#if defined(CONFIG_NSH_LOGIN_PASSWD)
ret = passwd_verify(username, password);
if (PASSWORD_VERIFY_MATCH(ret))
#else
#elif defined(CONFIG_NSH_LOGIN_PLATFORM)
ret = platform_user_verify(username, password);
if (PASSWORD_VERIFY_MATCH(ret))
#elif defined(CONFIG_NSH_LOGIN_FIXED)
if (strcmp(password, CONFIG_NSH_LOGIN_PASSWORD) == 0 &&
strcmp(username, CONFIG_NSH_LOGIN_USERNAME) == 0)
#else
# error No user verification method selected
#endif
{
printf("%s", g_loginsuccess);
@ -215,6 +221,9 @@ int nsh_stdlogin(FAR struct console_stdio_s *pstate)
else
{
printf("%s", g_badcredentials);
#if CONFIG_NSH_LOGIN_FAILDELAY > 0
usleep(CONFIG_NSH_LOGIN_FAILDELAY * 1000L);
#endif
}
}
}

View File

@ -176,7 +176,7 @@ int nsh_telnetlogin(FAR struct console_stdio_s *pstate)
{
char username[16];
char password[16];
#ifdef CONFIG_FSUTILS_PASSWD
#ifdef CONFIG_NSH_LOGIN_PASSWD
int ret;
#endif
int i;
@ -218,12 +218,19 @@ int nsh_telnetlogin(FAR struct console_stdio_s *pstate)
/* Verify the username and password */
#ifdef CONFIG_FSUTILS_PASSWD
#if defined(CONFIG_NSH_LOGIN_PASSWD)
ret = passwd_verify(username, password);
if (PASSWORD_VERIFY_MATCH(ret))
#else
#elif defined(CONFIG_NSH_LOGIN_PLATFORM)
ret = platform_user_verify(username, password);
if (PASSWORD_VERIFY_MATCH(ret))
#elif defined(CONFIG_NSH_LOGIN_FIXED)
if (strcmp(password, CONFIG_NSH_LOGIN_PASSWORD) == 0 &&
strcmp(username, CONFIG_NSH_LOGIN_USERNAME) == 0)
#else
# error No user verification method selected
#endif
{
fputs(g_loginsuccess, pstate->cn_outstream);
@ -235,6 +242,9 @@ int nsh_telnetlogin(FAR struct console_stdio_s *pstate)
{
fputs(g_badcredentials, pstate->cn_outstream);
fflush(pstate->cn_outstream);
#if CONFIG_NSH_LOGIN_FAILDELAY > 0
usleep(CONFIG_NSH_LOGIN_FAILDELAY * 1000L);
#endif
}
}