Browse Source

added basic login/logout logic

stefan 1 year ago
parent
commit
f58fe1de29
7 changed files with 367 additions and 79 deletions
  1. 97 68
      api/shellmatta.h
  2. 23 8
      example/main.c
  3. 3 2
      makefile
  4. 14 0
      src/shellmatta.c
  5. 212 0
      src/shellmatta_auth.c
  6. 6 0
      src/shellmatta_auth.h
  7. 12 1
      src/shellmatta_utils.c

+ 97 - 68
api/shellmatta.h

@@ -101,33 +101,26 @@ typedef shellmatta_retCode_t (*shellmatta_cmdFct_t)(const shellmatta_handle_t
  */
  */
 typedef shellmatta_retCode_t (*shellmatta_write_t)(const char* data, uint32_t length);
 typedef shellmatta_retCode_t (*shellmatta_write_t)(const char* data, uint32_t length);
 
 
-/**
- * @brief structure of one shellmatta command
- */
-typedef struct shellmatta_cmd
-{
-    char                    *cmd;       /**< command name                           */
-    char                    *cmdAlias;  /**< command alias                          */
-    char                    *helpText;  /**< help text to print in "help" command   */
-    char                    *usageText; /**< usage text - printed on "help cmd"     */
-#ifdef SHELLMATTA_AUTHENTICATION
-    uint32_t                minRoleId;  /**< minimum user role id for this command  */
-#endif
-    shellmatta_cmdFct_t     cmdFct;     /**< pointer to the cmd callack function    */
-    struct shellmatta_cmd   *next;      /**< pointer to next command or NULL        */
-} shellmatta_cmd_t;
-
-
 #ifdef SHELLMATTA_AUTHENTICATION
 #ifdef SHELLMATTA_AUTHENTICATION
 /**
 /**
  * @brief user role matrix
  * @brief user role matrix
  */
  */
 typedef struct
 typedef struct
 {
 {
-    uint32_t    roleId;     /**< id of the user role (!= 0)                         */
+    uint32_t    userId;     /**< id of the user (!= 0)                              */
     const char  *username;  /**< name of the user role                              */
     const char  *username;  /**< name of the user role                              */
     const char  *password;  /**< password of the user role or NULL (custom auth)    */
     const char  *password;  /**< password of the user role or NULL (custom auth)    */
-} user_role_t;
+} shellmatta_user_t;
+
+/**
+ * @brief typedefinition of one line of the authentication table
+ */
+typedef struct
+{
+    const char*    cmd;           /**< command to grand access to               */
+    const uint32_t *userIds;      /**< list of user ids with access to the cmd  */
+    const uint32_t userIdslength; /**< length of the user list                  */
+} shellmatta_perm_t;
 
 
 /**
 /**
  * @brief custom shellmatta authentication method
  * @brief custom shellmatta authentication method
@@ -135,52 +128,86 @@ typedef struct
  * @param[in]   password    password for the login
  * @param[in]   password    password for the login
  * @return      #SHELLMATTA_OK if the username and password is correct
  * @return      #SHELLMATTA_OK if the username and password is correct
  */
  */
-typedef shellmatta_retCode_t (*shellmatta_auth_check_t)(const char* username, const char* password);
+typedef shellmatta_retCode_t (*shellmatta_check_t)(const char* username, const char* password);
+
+/**
+ * @brief login states
+ */
+typedef enum
+{
+    SHELLMATTA_AUTH_IDLE,       /**< authentication system waits    */
+    SHELLMATTA_AUTH_USERNAME,   /**< input of username              */
+    SHELLMATTA_AUTH_PASSWORD    /**< input of password              */
+} shellmatta_auth_status_t;
 
 
 #endif
 #endif
 
 
+/**
+ * @brief structure of one shellmatta command
+ */
+typedef struct shellmatta_cmd
+{
+    char                    *cmd;       /**< command name                           */
+    char                    *cmdAlias;  /**< command alias                          */
+    char                    *helpText;  /**< help text to print in "help" command   */
+    char                    *usageText; /**< usage text - printed on "help cmd"     */
+    shellmatta_cmdFct_t     cmdFct;     /**< pointer to the cmd callack function    */
+    struct shellmatta_cmd   *next;      /**< pointer to next command or NULL        */
+#ifdef SHELLMATTA_AUTHENTICATION
+    shellmatta_perm_t       *authLink;  /**< internally used - pointer to perm list */
+#endif
+} shellmatta_cmd_t;
+
+
 /**
 /**
  * @brief structure of one shellmatta instance
  * @brief structure of one shellmatta instance
  */
  */
 typedef struct
 typedef struct
 {
 {
-    uint32_t            magic;              /**< magic number to check if initialized   */
-    char                *buffer;            /**< input buffer                           */
-    uint32_t            bufferSize;         /**< size of the input buffer               */
-    uint32_t            inputCount;         /**< offset of the current write operation  */
-    uint32_t            byteCounter;        /**< counter used to loop over input data   */
-    uint32_t            lastNewlineIdx;     /**< index of the lest newline              */
-    uint32_t            cursor;             /**< offset where the cursor is at          */
-    uint32_t            stdinIdx;           /**< start index of stdin in buffer         */
-    uint32_t            stdinLength;        /**< length of the stdin data               */
-    char                *historyBuffer;     /**< buffer to store the last commands      */
-    uint32_t            historyBufferSize;  /**< size of the history buffer             */
-    uint32_t            historyStart;       /**< index of the oldest stored command     */
-    uint32_t            historyEnd;         /**< index of the newest stored command     */
-    uint32_t            historyRead;        /**< index of the current search            */
-    bool                historyReadUp;      /**< flag to show the last history dir      */
-    uint32_t            tabCounter;         /**< counts the tabulator key presses       */
-    uint32_t            escapeCounter;      /**< counts the characters of an escape seq */
-    char                escapeChars[4u];    /**< buffer to save the escape characters   */
-    uint32_t            hereStartIdx;       /**< heredoc start of "<<"                  */
-    uint32_t            hereDelimiterIdx;   /**< heredoc delimiter index in input       */
-    uint32_t            hereLength;         /**< length of the heredoc delimiter        */
-    bool                echoEnabled;        /**< if true the input is printed           */
-    bool                dirty;              /**< dirty flag to show changes             */
-    const char          *prompt;            /**< prompt is printed after every command  */
-    char                delimiter;          /**< delimiter (return) to terminate a cmd  */
-    shellmatta_mode_t   mode;               /**< mode of the shell                      */
-    shellmatta_write_t  write;              /**< pointer to write function              */
-    shellmatta_cmd_t    helpCmd;            /**< help command structure                 */
-    shellmatta_cmd_t    *cmdList;           /**< pointer to the first command           */
-    shellmatta_cmd_t    *continuousCmd;     /**< command to be called continuously      */
-    shellmatta_cmd_t    *busyCmd;           /**< command to be polled (busy mode)       */
-    bool                cmdListIsConst;     /**< true if the #cmdList was passed during
-                                                 initialization                         */
-    shellmatta_opt_t    optionParser;       /**< option parser sructure                 */
+    uint32_t            magic;                  /**< magic number to check if initialized   */
+    char                *buffer;                /**< input buffer                           */
+    uint32_t            bufferSize;             /**< size of the input buffer               */
+    uint32_t            inputCount;             /**< offset of the current write operation  */
+    uint32_t            byteCounter;            /**< counter used to loop over input data   */
+    uint32_t            lastNewlineIdx;         /**< index of the lest newline              */
+    uint32_t            cursor;                 /**< offset where the cursor is at          */
+    uint32_t            stdinIdx;               /**< start index of stdin in buffer         */
+    uint32_t            stdinLength;            /**< length of the stdin data               */
+    char                *historyBuffer;         /**< buffer to store the last commands      */
+    uint32_t            historyBufferSize;      /**< size of the history buffer             */
+    uint32_t            historyStart;           /**< index of the oldest stored command     */
+    uint32_t            historyEnd;             /**< index of the newest stored command     */
+    uint32_t            historyRead;            /**< index of the current search            */
+    bool                historyReadUp;          /**< flag to show the last history dir      */
+    uint32_t            tabCounter;             /**< counts the tabulator key presses       */
+    uint32_t            escapeCounter;          /**< counts the characters of an escape seq */
+    char                escapeChars[4u];        /**< buffer to save the escape characters   */
+    uint32_t            hereStartIdx;           /**< heredoc start of "<<"                  */
+    uint32_t            hereDelimiterIdx;       /**< heredoc delimiter index in input       */
+    uint32_t            hereLength;             /**< length of the heredoc delimiter        */
+    bool                echoEnabled;            /**< if true the input is printed           */
+    bool                dirty;                  /**< dirty flag to show changes             */
+    const char          *prompt;                /**< prompt is printed after every command  */
+    char                delimiter;              /**< delimiter (return) to terminate a cmd  */
+    shellmatta_mode_t   mode;                   /**< mode of the shell                      */
+    shellmatta_write_t  write;                  /**< pointer to write function              */
+    shellmatta_cmd_t    helpCmd;                /**< help command structure                 */
+    shellmatta_cmd_t    *cmdList;               /**< pointer to the first command           */
+    shellmatta_cmd_t    *continuousCmd;         /**< command to be called continuously      */
+    shellmatta_cmd_t    *busyCmd;               /**< command to be polled (busy mode)       */
+    bool                cmdListIsConst;         /**< true if the #cmdList was passed during
+                                                     initialization                         */
+    shellmatta_opt_t    optionParser;           /**< option parser sructure                 */
 #ifdef SHELLMATTA_AUTHENTICATION
 #ifdef SHELLMATTA_AUTHENTICATION
-    uint32_t            roleId;             /**< role ID of the current session         */
-    user_role_t         *userRoleMatrix     /**< user role matrix structure             */
+    shellmatta_cmd_t    loginCmd;               /**< login command structure                */
+    shellmatta_cmd_t    logoutCmd;              /**< logout command structure               */
+    uint32_t            userId;                 /**< user ID of the current session         */
+    shellmatta_user_t   *userPointer;           /**< pointer to the user in the user list   */
+    shellmatta_user_t   *userList;              /**< user list                              */
+    uint32_t            userListLength;         /**< length of the user list                */
+    shellmatta_perm_t   *permList;              /**< permission list                        */
+    uint32_t            permListLength;         /**< length of the permission list          */
+    shellmatta_check_t  checkFct;               /**< custom credential check function       */
 #endif
 #endif
 } shellmatta_instance_t;
 } shellmatta_instance_t;
 
 
@@ -241,18 +268,20 @@ shellmatta_retCode_t shellmatta_printf(     shellmatta_handle_t handle,
 
 
 #ifdef SHELLMATTA_AUTHENTICATION
 #ifdef SHELLMATTA_AUTHENTICATION
 
 
-shellmatta_retCode_t shellmatta_auth_init(                  shellmatta_handle_t     handle,
-                                                            user_role_t             *userRoleMatrix,
-                                                            uint32_t                length,
-                                                            bool                    customLogin,
-                                                            shellmatta_auth_check_t checkFct);
-shellmatta_retCode_t shellmatta_auth_login(                 shellmatta_handle_t handle,
-                                                            uint32_t            roleId);
-shellmatta_retCode_t shellmatta_auth_logout(                shellmatta_handle_t handle);
-uint32_t             shellmatta_auth_getLoggedInRole(       shellmatta_handle_t handle);
-shellmatta_retCode_t shellmatta_auth_getLoggedInUserName(   shellmatta_handle_t handle,
-                                                            char                **data,
-                                                            uint32_t            *length);
+shellmatta_retCode_t shellmatta_auth_init(                  shellmatta_handle_t   handle,
+                                                            shellmatta_user_t     *userList,
+                                                            uint32_t              userListLength,
+                                                            shellmatta_perm_t     *permList,
+                                                            uint32_t              permListLength,
+                                                            bool                  customLogin,
+                                                            shellmatta_check_t    checkFct);
+shellmatta_retCode_t shellmatta_auth_login(                 shellmatta_handle_t   handle,
+                                                            uint32_t              userId);
+shellmatta_retCode_t shellmatta_auth_logout(                shellmatta_handle_t   handle);
+uint32_t             shellmatta_auth_getLoggedInUserId(     shellmatta_handle_t   handle);
+shellmatta_retCode_t shellmatta_auth_getLoggedInUserName(   shellmatta_handle_t   handle,
+                                                            char                  **data,
+                                                            uint32_t              *length);
 
 
 #endif
 #endif
 
 

+ 23 - 8
example/main.c

@@ -31,7 +31,7 @@ static shellmatta_retCode_t doSomething(shellmatta_handle_t handle, const char *
     shellmatta_printf(handle, "%s - length: %u", arguments, length);
     shellmatta_printf(handle, "%s - length: %u", arguments, length);
     return SHELLMATTA_OK;
     return SHELLMATTA_OK;
 }
 }
-shellmatta_cmd_t doSomethingCmd = {"doSomething", "do", "Function does something", "use me, please", doSomething, NULL};
+shellmatta_cmd_t doSomethingCmd = {"doSomething", "do", "Function does something", "use me, please", doSomething, NULL, NULL};
 
 
 static shellmatta_retCode_t doSome(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t doSome(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
 {
@@ -45,7 +45,7 @@ static shellmatta_retCode_t doSome(shellmatta_handle_t handle, const char *argum
 
 
     return SHELLMATTA_OK;
     return SHELLMATTA_OK;
 }
 }
-shellmatta_cmd_t doSomeCmd = {"adoSome2", "adof2", "Function does something", "use me, please", doSome, NULL};
+shellmatta_cmd_t doSomeCmd = {"adoSome2", "adof2", "Function does something", "use me, please", doSome, NULL, NULL};
 
 
 static shellmatta_retCode_t removeCmdFct(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t removeCmdFct(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
 {
@@ -58,7 +58,7 @@ static shellmatta_retCode_t removeCmdFct(shellmatta_handle_t handle, const char
 
 
     return SHELLMATTA_OK;
     return SHELLMATTA_OK;
 }
 }
-shellmatta_cmd_t removeCommand = {"remove", "r", "Function removes a command", "", removeCmdFct, NULL};
+shellmatta_cmd_t removeCommand = {"remove", "r", "Function removes a command", "", removeCmdFct, NULL, NULL};
 
 
 
 
 static shellmatta_retCode_t quit(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t quit(shellmatta_handle_t handle, const char *arguments, uint32_t length)
@@ -71,7 +71,7 @@ static shellmatta_retCode_t quit(shellmatta_handle_t handle, const char *argumen
 
 
     return SHELLMATTA_OK;
     return SHELLMATTA_OK;
 }
 }
-shellmatta_cmd_t quitCommand = {"quit", "q", "Function quits the shell", "", quit, NULL};
+shellmatta_cmd_t quitCommand = {"quit", "q", "Function quits the shell", "", quit, NULL, NULL};
 
 
 static shellmatta_retCode_t empty(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t empty(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
 {
@@ -83,7 +83,7 @@ static shellmatta_retCode_t empty(shellmatta_handle_t handle, const char *argume
 
 
     return SHELLMATTA_OK;
     return SHELLMATTA_OK;
 }
 }
-shellmatta_cmd_t emptyCommand = {"empty", NULL, NULL, NULL, empty, NULL};
+shellmatta_cmd_t emptyCommand = {"empty", NULL, NULL, NULL, empty, NULL, NULL};
 
 
 static shellmatta_retCode_t reset(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t reset(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
 {
@@ -127,7 +127,7 @@ static shellmatta_retCode_t reset(shellmatta_handle_t handle, const char *argume
 
 
     return SHELLMATTA_OK;
     return SHELLMATTA_OK;
 }
 }
-shellmatta_cmd_t resetCommand = {"reset", NULL, "resets the shellmatta instance", "reset [--prompt true/false]", reset, NULL};
+shellmatta_cmd_t resetCommand = {"reset", NULL, "resets the shellmatta instance", "reset [--prompt true/false]", reset, NULL, NULL};
 
 
 static shellmatta_retCode_t continuous(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t continuous(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
 {
@@ -151,7 +151,7 @@ static shellmatta_retCode_t continuous(shellmatta_handle_t handle, const char *a
     }
     }
     return ret;
     return ret;
 }
 }
-shellmatta_cmd_t continuousCommand = {"continuous", "cont", "prints continously all input bytes", "continuous", continuous, NULL};
+shellmatta_cmd_t continuousCommand = {"continuous", "cont", "prints continously all input bytes", "continuous", continuous, NULL, NULL};
 
 
 static shellmatta_retCode_t busy(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t busy(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
 {
@@ -173,7 +173,7 @@ static shellmatta_retCode_t busy(shellmatta_handle_t handle, const char *argumen
 
 
     return ret;
     return ret;
 }
 }
-shellmatta_cmd_t busyCommand = {"busy", NULL, NULL, NULL, busy, NULL};
+shellmatta_cmd_t busyCommand = {"busy", NULL, NULL, NULL, busy, NULL, NULL};
 
 
 
 
 shellmatta_retCode_t writeFct(const char* data, uint32_t length)
 shellmatta_retCode_t writeFct(const char* data, uint32_t length)
@@ -221,6 +221,21 @@ int main(int argc, char **argv)
     shellmatta_addCmd(handle, &continuousCommand);
     shellmatta_addCmd(handle, &continuousCommand);
     shellmatta_addCmd(handle, &busyCommand);
     shellmatta_addCmd(handle, &busyCommand);
 
 
+
+    shellmatta_user_t userList[] = {
+        {1, "shimatta", "12345678"},
+        {2, "not_shimatta", "87654321"}
+    };
+
+    uint32_t doSomeCmdPerms[] = {1, 2};
+    uint32_t removeCommandPerms[] = {1};
+    shellmatta_perm_t permList[] = {
+        {"adoSome2", doSomeCmdPerms, sizeof(doSomeCmdPerms)/sizeof(doSomeCmdPerms[0])},
+        {"remove", removeCommandPerms, sizeof(removeCommandPerms)/sizeof(removeCommandPerms[0])}
+    };
+
+    shellmatta_auth_init(handle, userList, 2, permList, 2, false, NULL);
+
     while(exitRequest == false)
     while(exitRequest == false)
     {
     {
         char c;
         char c;

+ 3 - 2
makefile

@@ -20,7 +20,8 @@ SOURCES :=  src/shellmatta.c                \
             src/shellmatta_history.c        \
             src/shellmatta_history.c        \
             src/shellmatta_utils.c          \
             src/shellmatta_utils.c          \
             src/shellmatta_escape.c         \
             src/shellmatta_escape.c         \
-            src/shellmatta_opt.c
+            src/shellmatta_opt.c            \
+            src/shellmatta_auth.c
 
 
 INCLUDES    := api .
 INCLUDES    := api .
 
 
@@ -57,7 +58,7 @@ UNITTEST_CPPOBJ  := $(patsubst %.cpp,$(UNITTEST_OBJ_DIR)%.o,$(UNITTEST_SOURCES))
 INTEGRATIONTEST_CPPOBJ  :=  $(patsubst %.cpp,$(INTEGRATIONTEST_CPP_OBJ_DIR)%.o,$(INTEGRATIONTEST_SOURCES))
 INTEGRATIONTEST_CPPOBJ  :=  $(patsubst %.cpp,$(INTEGRATIONTEST_CPP_OBJ_DIR)%.o,$(INTEGRATIONTEST_SOURCES))
 INTEGRATIONTEST_COBJ    :=  $(patsubst %.c,$(INTEGRATIONTEST_CPP_OBJ_DIR)%.o,$(SOURCES))
 INTEGRATIONTEST_COBJ    :=  $(patsubst %.c,$(INTEGRATIONTEST_CPP_OBJ_DIR)%.o,$(SOURCES))
 
 
-CFLAGS      := $(INCLUDES:%=-I%) -g -Wall -Werror -Wextra -pedantic -DSHELLMATTA_HELP_ALIAS=\(char*\)\"?\"
+CFLAGS      := $(INCLUDES:%=-I%) -g -Wall -Werror -Wextra -pedantic -DSHELLMATTA_HELP_ALIAS=\(char*\)\"?\" -DSHELLMATTA_AUTHENTICATION
 TESTFLAGS   := $(CFLAGS) -fprofile-arcs -ftest-coverage
 TESTFLAGS   := $(CFLAGS) -fprofile-arcs -ftest-coverage
 TESTLFLAGS  := -fprofile-arcs -Wl,--allow-multiple-definition
 TESTLFLAGS  := -fprofile-arcs -Wl,--allow-multiple-definition
 
 

+ 14 - 0
src/shellmatta.c

@@ -23,6 +23,9 @@
 #include "shellmatta_utils.h"
 #include "shellmatta_utils.h"
 #include "shellmatta_escape.h"
 #include "shellmatta_escape.h"
 #include "shellmatta_opt.h"
 #include "shellmatta_opt.h"
+#ifdef SHELLMATTA_AUTHENTICATION
+#include "shellmatta_auth.h"
+#endif
 #include <stddef.h>
 #include <stddef.h>
 #include <string.h>
 #include <string.h>
 #include <stdarg.h>
 #include <stdarg.h>
@@ -105,10 +108,21 @@ shellmatta_retCode_t shellmatta_doInit(
 
 
         /** -# copy the help command structure to this instance */
         /** -# copy the help command structure to this instance */
         memcpy(&(inst->helpCmd), &helpCmd, sizeof(shellmatta_cmd_t));
         memcpy(&(inst->helpCmd), &helpCmd, sizeof(shellmatta_cmd_t));
+#ifdef SHELLMATTA_AUTHENTICATION
+        /** -# copy the auth commands to the instance */
+        memcpy(&(inst->loginCmd), &shellmatta_auth_loginCmd, sizeof(shellmatta_cmd_t));
+        inst->helpCmd.next = &(inst->loginCmd);
+        memcpy(&(inst->logoutCmd), &shellmatta_auth_logoutCmd, sizeof(shellmatta_cmd_t));
+        inst->loginCmd.next = &(inst->logoutCmd);
+#endif
 
 
         if(NULL != cmdList)
         if(NULL != cmdList)
         {
         {
+#ifndef SHELLMATTA_AUTHENTICATION
             inst->helpCmd.next = (shellmatta_cmd_t *) cmdList;
             inst->helpCmd.next = (shellmatta_cmd_t *) cmdList;
+#else
+            inst->logoutCmd.next = (shellmatta_cmd_t *) cmdList;
+#endif
             inst->cmdListIsConst = true;
             inst->cmdListIsConst = true;
         }
         }
 
 

+ 212 - 0
src/shellmatta_auth.c

@@ -20,7 +20,219 @@
 #include "shellmatta.h"
 #include "shellmatta.h"
 #include "shellmatta_auth.h"
 #include "shellmatta_auth.h"
 #include <stdint.h>
 #include <stdint.h>
+#include <stddef.h>
+#include <string.h>
 
 
+static uint32_t checkFct(shellmatta_handle_t handle, char *username, char *password)
+{
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+    uint32_t                userId  = 0u;
+    uint32_t                i;
+
+    if (NULL != inst->checkFct)
+    {
+        userId = inst->checkFct(username, password);
+    }
+    else
+    {
+        for (i = 0u; i < inst->userListLength; i++)
+        {
+            /** search for user */
+            if (0 == strcmp(inst->userList[i].username, username))
+            {
+                /** check password */
+                if (0 == strcmp(inst->userList[i].password, password))
+                {
+                    userId = inst->userList[i].userId;
+                }
+                break;
+            }
+        }
+    }
+
+    /** print login result */
+    if (0 == userId)
+    {
+        shellmatta_write(handle, "username or password is wrong\n", 31);
+    }
+    else
+    {
+        shellmatta_write(handle, "login successful\n", 18);
+    }
+
+    return userId;
+}
+
+/**
+ * @brief       handles the login based on username and password
+ * @param[in]   handle      handle  shellmatta instance handle
+ * @param[in]   arguments   arguments containing a command name or alias
+ * @param[in]   length      length of the arguments
+ * @return      #SHELLMATTA_OK
+ *              #SHELLMATTA_CONTINUE (waiting for input)
+ */
+static shellmatta_retCode_t loginCmdFct(const shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    uint32_t i;
+    char option;
+    char *argument;
+    uint32_t argLen;
+    char *username = NULL;
+    char *password = NULL;
+
+    static const shellmatta_opt_long_t options[] = 
+    {
+        {"username" , 'u',  SHELLMATTA_OPT_ARG_REQUIRED},
+        {"password" , 'p',  SHELLMATTA_OPT_ARG_REQUIRED},
+        {NULL       , '\0', SHELLMATTA_OPT_ARG_NONE}
+    };
+
+    ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
+    while(SHELLMATTA_OK == ret)
+    {
+        switch(option)
+        {
+            case 'u':
+                if(NULL != argument)
+                {
+                    username = argument;
+                }
+                break;
+            case 'p':
+                if(NULL != argument)
+                {
+                    password = argument;
+                }
+                break;
+            default:
+                shellmatta_printf(handle, "Unknown option: %c\r\n", option);
+                break;
+        }
+        ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
+    }
+
+    if ((NULL != username) || (NULL != password))
+    {
+        inst->userId = checkFct(handle, username, password);
+        if (0 != inst->userId)
+        {
+            for (i = 0u; i < inst->userListLength; i++)
+            {
+                if (0 == strcmp(inst->userList[i].username, username))
+                {
+                    inst->userPointer = &inst->userList[i];
+                    break;
+                }
+            }
+        }
+        else
+        {
+            inst->userPointer = NULL;
+        }
+    }
+
+    (void)arguments;
+    (void)length;
+
+    return ret;
+}
+const shellmatta_cmd_t shellmatta_auth_loginCmd = {"login"
+                                                 , "li"
+                                                 , "Login command"
+                                                 , "interactive or use -u <username> -p <password>"
+                                                 , loginCmdFct
+                                                 , NULL
+                                                 , NULL};
+
+
+/**
+ * @brief       handles the logout of the current session
+ * @param[in]   handle      handle  shellmatta instance handle
+ * @param[in]   arguments   arguments containing a command name or alias
+ * @param[in]   length      length of the arguments
+ * @return      #SHELLMATTA_OK
+ */
+static shellmatta_retCode_t logoutCmdFct(const shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+
+    inst->userId = 0u;
+    inst->userPointer = NULL;
+
+    (void)arguments;
+    (void)length;
+
+    return ret;
+}
+const shellmatta_cmd_t shellmatta_auth_logoutCmd = {"logout"
+                                                  , "lo"
+                                                  , "Logout command"
+                                                  , "logs out the currently logged in user"
+                                                  , logoutCmdFct
+                                                  , NULL
+                                                  , NULL};
+
+
+/**
+ * @brief       initializes the shellmatta authentication system
+ * @param[in]   handle          shellmatta instance handle
+ * @param[in]   userList        list to specify all users pointer to a list of type #shellmatta_user_t
+ * @param[in]   userListLength  length of the user list
+ * @param[in]   permList        list to specify the command permissions pointer to a list of type #shellmatta_perm_t
+ * @param[in]   permListLength  length of the perm list
+ * @param[in]   customLogin     true: no internal login command is provided
+ * @param[in]   checkFct        pointer to custom credential check function of type #shellmatta_check_t
+ * @return      errorcode   #SHELLMATTA_OK
+ *                          #SHELLMATTA_USE_FAULT (param err)
+ */
+shellmatta_retCode_t shellmatta_auth_init(shellmatta_handle_t   handle,
+                                          shellmatta_user_t     *userList,
+                                          uint32_t              userListLength,
+                                          shellmatta_perm_t     *permList,
+                                          uint32_t              permListLength,
+                                          bool                  customLogin,
+                                          shellmatta_check_t    checkFct)
+{
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+    uint32_t                i;
+    shellmatta_cmd_t        *cmd;
+
+    inst->userId = 0u;
+    inst->userPointer = 0u;
+    inst->userList = userList;
+    inst->userListLength = userListLength;
+    inst->permList = permList;
+    inst->permListLength = permListLength;
+    if(customLogin)
+    {
+        inst->helpCmd.next = &inst->logoutCmd;
+    }
+    inst->checkFct = checkFct;
+
+    /** assign links to the perm list to each command */
+    cmd = inst->cmdList;
+
+    /** -# search for a matching command */
+    while (NULL != cmd)
+    {
+        /** Search for command in perm list */
+        for (i = 0u; i < permListLength; i++)
+        {
+            if (0 == strcmp(cmd->cmd, permList[i].cmd))
+            {
+                cmd->authLink = &permList[i];
+                break;
+            }
+        }
+
+        cmd = cmd->next;
+    }
+    return ret;
+}
 
 
 /**
 /**
  * @}
  * @}

+ 6 - 0
src/shellmatta_auth.h

@@ -22,6 +22,12 @@
 #include "shellmatta.h"
 #include "shellmatta.h"
 #include <stdint.h>
 #include <stdint.h>
 
 
+/** @brief login command to enable a user to login */
+extern const shellmatta_cmd_t shellmatta_auth_loginCmd;
+
+/** @brief logout command */
+extern const shellmatta_cmd_t shellmatta_auth_logoutCmd;
+
 
 
 #endif
 #endif
 
 

+ 12 - 1
src/shellmatta_utils.c

@@ -436,7 +436,11 @@ const shellmatta_cmd_t helpCmd = {SHELLMATTA_HELP_COMMAND
                                 , SHELLMATTA_HELP_HELP_TEXT
                                 , SHELLMATTA_HELP_HELP_TEXT
                                 , SHELLMATTA_HELP_USAGE_TEXT
                                 , SHELLMATTA_HELP_USAGE_TEXT
                                 , helpCmdFct
                                 , helpCmdFct
-                                , NULL};
+                                , NULL
+#ifdef SHELLMATTA_AUTHENTICATION
+                                , NULL
+#endif
+                                };
 
 
 /**
 /**
  * @brief       terminates an input and prints the prompt again
  * @brief       terminates an input and prints the prompt again
@@ -453,6 +457,13 @@ void utils_terminateInput(shellmatta_instance_t *inst)
     inst->continuousCmd     = NULL;
     inst->continuousCmd     = NULL;
     inst->busyCmd           = NULL;
     inst->busyCmd           = NULL;
     inst->write("\r\n", 2u);
     inst->write("\r\n", 2u);
+#ifdef SHELLMATTA_AUTHENTICATION
+    if (NULL != inst->userPointer)
+    {
+        inst->write(inst->userPointer->username, strlen(inst->userPointer->username));
+        inst->write("@", 1);
+    }
+#endif
     inst->write(inst->prompt, strlen(inst->prompt));
     inst->write(inst->prompt, strlen(inst->prompt));
 }
 }