diff --git a/ChangeLog.txt b/ChangeLog.txt index 0bcc74b77..ad9dc8a46 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -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). diff --git a/include/nsh.h b/include/nsh.h index b4183cd9b..9620cbd26 100644 --- a/include/nsh.h +++ b/include/nsh.h @@ -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 } diff --git a/nshlib/Kconfig b/nshlib/Kconfig index 9c463ebfe..f6261abd8 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -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 + 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 + + An appropriate place to implement this function might be in the + directory apps/platform/. + +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. diff --git a/nshlib/Makefile b/nshlib/Makefile index 67e64bf35..553e1bc40 100644 --- a/nshlib/Makefile +++ b/nshlib/Makefile @@ -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)) diff --git a/nshlib/README.txt b/nshlib/README.txt index d3e71d6b5..b839cc76d 100644 --- a/nshlib/README.txt +++ b/nshlib/README.txt @@ -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 --- diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 1c1609d91..068261bc0 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -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); diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 0f86a8c97..3bce11d40 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -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 * * 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, " " }, @@ -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, " " }, diff --git a/nshlib/nsh_login.c b/nshlib/nsh_login.c index b6134d2e3..675f7a5f5 100644 --- a/nshlib/nsh_login.c +++ b/nshlib/nsh_login.c @@ -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 } } } diff --git a/nshlib/nsh_passwdcmds.c b/nshlib/nsh_passwdcmds.c index 9a8829989..973ac4069 100644 --- a/nshlib/nsh_passwdcmds.c +++ b/nshlib/nsh_passwdcmds.c @@ -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 */ diff --git a/nshlib/nsh_stdlogin.c b/nshlib/nsh_stdlogin.c index 1e86e48a1..099994531 100644 --- a/nshlib/nsh_stdlogin.c +++ b/nshlib/nsh_stdlogin.c @@ -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 } } } diff --git a/nshlib/nsh_telnetlogin.c b/nshlib/nsh_telnetlogin.c index 5cb82ce42..f4960edd6 100644 --- a/nshlib/nsh_telnetlogin.c +++ b/nshlib/nsh_telnetlogin.c @@ -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 } }