Browse Source

added doxygen comments to shellmatta auth
made external methods robust
fiddled around with some interfaces

stefan 1 year ago
parent
commit
26a9116bc1
3 changed files with 235 additions and 74 deletions
  1. 1 1
      api/shellmatta.h
  2. 5 0
      src/shellmatta.c
  3. 229 73
      src/shellmatta_auth.c

+ 1 - 1
api/shellmatta.h

@@ -282,7 +282,7 @@ shellmatta_retCode_t shellmatta_auth_login(                 shellmatta_handle_t
 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,
+                                                            char                    *data,
                                                             uint32_t                *length);
 
 #endif

+ 5 - 0
src/shellmatta.c

@@ -175,6 +175,11 @@ shellmatta_retCode_t shellmatta_resetShell( shellmatta_handle_t handle, bool pri
         inst->hereLength            = 0u;
         shellmatta_opt_init(inst, 0u);
 
+#ifdef SHELLMATTA_AUTHENTICATION
+        inst->userId = 0u;
+        inst->userPointer = NULL;
+#endif
+
         if(true == printPrompt)
         {
             /** -# print a prompt if requested */

+ 229 - 73
src/shellmatta_auth.c

@@ -26,6 +26,14 @@
 #include <stddef.h>
 #include <string.h>
 
+/**
+ * @brief       wraps the input to the login command and mimics the editability of the standard shell input
+ * @param[in, out]  inst    shellmatta instance to work with
+ * @param[in]       data    one byte of data the user put in
+ * @param[in]       hide    true: do not print anything tho the output (e.g. password input)
+ * @return      #SHELLMATTA_BUSY    => reading in data
+ *              #SHELLMATTA_OK      => delimiter (e.g. enter) detected
+ */
 shellmatta_retCode_t inputWrapper(shellmatta_instance_t *inst, char data, bool hide)
 {
     shellmatta_retCode_t ret = SHELLMATTA_BUSY;
@@ -63,15 +71,20 @@ shellmatta_retCode_t inputWrapper(shellmatta_instance_t *inst, char data, bool h
     return ret;
 }
 
-static uint32_t getUserIdFromName(shellmatta_handle_t handle, char *username)
+/**
+ * @brief       searches the user list for a passed username and returns the userId
+ * @param[in]   inst        shellmatta instance to work with
+ * @param[in]   username    username to search for - pointer to string
+ * @return      userId or 0 if user was not found
+ */
+static uint32_t getUserIdFromName(shellmatta_instance_t *inst, char *username)
 {
-    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
-    uint32_t                userId  = 0u;
-    uint32_t                i;
+    uint32_t    userId  = 0u;
+    uint32_t    i;
 
     for (i = 0u; i < inst->userListLength; i++)
     {
-        /** search for user */
+        /** -# search for user */
         if (0 == strcmp(inst->userList[i].username, username))
         {
             userId = inst->userList[i].userId;
@@ -82,7 +95,13 @@ static uint32_t getUserIdFromName(shellmatta_handle_t handle, char *username)
     return userId;
 }
 
-void checkFct(shellmatta_handle_t handle, uint32_t userId, char *password)
+/**
+ * @brief       checks the passed password and logs the user into the instance on success
+ * @param[in, out]  handle      shellmatta handle to work with
+ * @param[in]       userId      userId to check the password for
+ * @param[in]       password    password to check for - pointer to string
+ */
+void checkPassword(shellmatta_handle_t handle, uint32_t userId, char *password)
 {
     shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
     uint32_t                approvedUserId  = 0u;
@@ -96,10 +115,10 @@ void checkFct(shellmatta_handle_t handle, uint32_t userId, char *password)
     {
         for (i = 0u; i < inst->userListLength; i++)
         {
-            /** search for user */
+            /** -# search for user */
             if (inst->userList[i].userId == userId)
             {
-                /** check password */
+                /** -# check password */
                 if (0 == strcmp(inst->userList[i].password, password))
                 {
                     approvedUserId = inst->userList[i].userId;
@@ -109,7 +128,7 @@ void checkFct(shellmatta_handle_t handle, uint32_t userId, char *password)
         }
     }
 
-    /** print login result */
+    /** -# print login result */
     if (0 == approvedUserId)
     {
         shellmatta_write(handle, "username or password is wrong\r\n", 31);
@@ -119,22 +138,7 @@ void checkFct(shellmatta_handle_t handle, uint32_t userId, char *password)
         shellmatta_write(handle, "login successful\r\n", 18);
     }
 
-    inst->userId = approvedUserId;
-    if (0 != userId)
-    {
-        for (i = 0u; i < inst->userListLength; i++)
-        {
-            if (inst->userList[i].userId == approvedUserId)
-            {
-                inst->userPointer = &inst->userList[i];
-                break;
-            }
-        }
-    }
-    else
-    {
-        inst->userPointer = NULL;
-    }
+    (void)shellmatta_auth_login(handle, approvedUserId);
 }
 
 /**
@@ -144,7 +148,7 @@ void checkFct(shellmatta_handle_t handle, uint32_t userId, char *password)
  * @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;
@@ -162,9 +166,10 @@ static shellmatta_retCode_t loginCmdFct(const shellmatta_handle_t handle, const
         {NULL       , '\0', SHELLMATTA_OPT_ARG_NONE}
     };
 
+    /** -# handle the login state machine */
     switch(inst->loginState)
     {
-
+        /** -# init the login procedure - use directly passed credentials if any */
         case SHELLMATTA_AUTH_IDLE:
             ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
             while(SHELLMATTA_OK == ret)
@@ -192,28 +197,31 @@ static shellmatta_retCode_t loginCmdFct(const shellmatta_handle_t handle, const
 
             if ((NULL != username) && (NULL != password))
             {
-                inst->tmpUserId = getUserIdFromName(handle, username);
-                checkFct(handle, inst->tmpUserId, password);
+                inst->tmpUserId = getUserIdFromName(inst, username);
+                checkPassword(handle, inst->tmpUserId, password);
             }
             else
             {
+                /** -# no credentials are passed with the command - start the input */
                 inst->inputCount = 0u;
                 inst->cursor = 0u;
-                /** store pointer to username in buffer */
+                /** -# store pointer to username in buffer */
                 shellmatta_write(handle, "enter username:\r\n", 17);
                 inst->loginState = SHELLMATTA_AUTH_USERNAME;
                 return SHELLMATTA_CONTINUE;
             }
             break;
+
         case SHELLMATTA_AUTH_USERNAME:
+            /** -# read in password characters to the instance buffer */
             (void)shellmatta_read(handle, &argument, &argLen);
             if ((1 == argLen) && (SHELLMATTA_OK == inputWrapper(inst, argument[0], false)))
             {
-                /** store user id */
+                /** -# store user id */
                 inst->buffer[inst->inputCount] = '\0';
                 inst->tmpUserId = getUserIdFromName(handle, inst->buffer);
 
-                /** reinitialize input */
+                /** -# reinitialize input */
                 inst->inputCount = 0u;
                 inst->cursor = 0u;
 
@@ -222,13 +230,16 @@ static shellmatta_retCode_t loginCmdFct(const shellmatta_handle_t handle, const
             }
             ret = SHELLMATTA_CONTINUE;
             break;
+
         case SHELLMATTA_AUTH_PASSWORD:
+            /** -# read in password characters to the instance buffer - hiding output */
             (void)shellmatta_read(handle, &argument, &argLen);
             if ((1 == argLen) && (SHELLMATTA_OK == inputWrapper(inst, argument[0], true)))
             {
+                /** -# check input username and password */
                 inst->buffer[inst->inputCount] = '\0';
                 shellmatta_write(handle, "\r\n", 2);
-                checkFct(handle, inst->tmpUserId, inst->buffer);
+                checkPassword(handle, inst->tmpUserId, inst->buffer);
                 inst->loginState = SHELLMATTA_AUTH_IDLE;
             }
             else
@@ -263,13 +274,7 @@ const shellmatta_cmd_t shellmatta_auth_loginCmd = {"login"
  */
 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;
-
-    /** reset shell and with it the history buffer */
+    /** -# reset shell and with it the history buffer */
     (void)shellmatta_resetShell(handle, false);
 
     shellmatta_write(handle, "good bye\r\n", 10);
@@ -277,7 +282,7 @@ static shellmatta_retCode_t logoutCmdFct(const shellmatta_handle_t handle, const
     (void)arguments;
     (void)length;
 
-    return ret;
+    return SHELLMATTA_OK;
 }
 const shellmatta_cmd_t shellmatta_auth_logoutCmd = {"logout"
                                                   , "lo"
@@ -287,67 +292,218 @@ const shellmatta_cmd_t shellmatta_auth_logoutCmd = {"logout"
                                                   , 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]   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]   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
+ * @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_auth_user_t     *userList,
-                                          uint32_t              userListLength,
-                                          shellmatta_auth_perm_t     *permList,
-                                          uint32_t              permListLength,
-                                          bool                  customLogin,
-                                          shellmatta_auth_check_t    checkFct)
+shellmatta_retCode_t shellmatta_auth_init(shellmatta_handle_t       handle,
+                                          shellmatta_auth_user_t    *userList,
+                                          uint32_t                  userListLength,
+                                          shellmatta_auth_perm_t    *permList,
+                                          uint32_t                  permListLength,
+                                          bool                      customLogin,
+                                          shellmatta_auth_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->loginState = SHELLMATTA_AUTH_IDLE;
-    inst->userId = 0u;
-    inst->tmpUserId = 0u;
-    inst->userPointer = 0u;
-    inst->userList = userList;
-    inst->userListLength = userListLength;
-    inst->permList = permList;
-    inst->permListLength = permListLength;
-    if(customLogin)
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic)
+        &&  (NULL               != userList)
+        &&  (0                  != userListLength)
+        &&  (NULL               != permList)
+        &&  (0                  != permListLength))
     {
-        inst->helpCmd.next = &inst->logoutCmd;
+        inst->loginState = SHELLMATTA_AUTH_IDLE;
+        inst->userId = 0u;
+        inst->tmpUserId = 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;
+        }
     }
-    inst->checkFct = checkFct;
+    else
+    {
+        ret = SHELLMATTA_USE_FAULT;
+    }
+
+    return ret;
+}
 
-    /** assign links to the perm list to each command */
-    cmd = inst->cmdList;
+/**
+ * @brief       manually logs the passed user id in
+ * @param[in]   handle      shellmatta instance handle
+ * @param[in]   userId      userId to login
+ * @return      errorcode   #SHELLMATTA_OK
+ *                          #SHELLMATTA_USE_FAULT (param err)
+ */
+shellmatta_retCode_t shellmatta_auth_login(shellmatta_handle_t handle, uint32_t userId)
+{
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+    uint32_t                i;
 
-    /** -# search for a matching command */
-    while (NULL != cmd)
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic))
     {
-        /** Search for command in perm list */
-        for (i = 0u; i < permListLength; i++)
+        /** -# log passed user id into the instance */
+        inst->userId = userId;
+        if (0 != userId)
         {
-            if (0 == strcmp(cmd->cmd, permList[i].cmd))
+            /** -# set user pointer to print the name in the prompt */
+            for (i = 0u; i < inst->userListLength; i++)
             {
-                cmd->authLink = &permList[i];
-                break;
+                if (inst->userList[i].userId == userId)
+                {
+                    inst->userPointer = &inst->userList[i];
+                    break;
+                }
             }
         }
+        else
+        {
+            inst->userPointer = NULL;
+        }
+    }
+    else
+    {
+        ret = SHELLMATTA_USE_FAULT;
+    }
+    return ret;
+}
+
+/**
+ * @brief       logs the currently logged in user out of the instance
+ * @param[in]   handle      shellmatta instance handle
+ * @return      errorcode   #SHELLMATTA_OK
+ *                          #SHELLMATTA_USE_FAULT (param err)
+ */
+shellmatta_retCode_t shellmatta_auth_logout(shellmatta_handle_t handle)
+{
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic))
+    {
+        inst->userId = 0u;
+        inst->userPointer = NULL;
+    }
+    else
+    {
+        ret = SHELLMATTA_USE_FAULT;
+    }
+    return ret;
+}
+
+/**
+ * @brief       returns the currently logged in userId
+ * @param[in]   handle      shellmatta instance handle
+ * @return      userId or 0 if no user is logged in
+ */
+uint32_t shellmatta_auth_getLoggedInUserId(shellmatta_handle_t handle)
+{
+    uint32_t                userId  = 0u;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
 
-        cmd = cmd->next;
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic))
+    {
+        userId = inst->userId;
+    }
+
+    return userId;
+}
+
+/**
+ * @brief           copies the username into the passed buffer
+ * @param[in]       handle      shellmatta instance handle
+ * @param[out]      data        pointer to buffer to write the username into
+ * @param[in, out]  length      in - length of the passed buffer, out - actual stringlength of the username
+ * @return          errorcode   #SHELLMATTA_OK
+ *                              #SHELLMATTA_ERROR (passed buffer is too small)
+ *                              #SHELLMATTA_USE_FAULT (param err)
+ */
+shellmatta_retCode_t shellmatta_auth_getLoggedInUserName(shellmatta_handle_t handle, char *data, uint32_t *length)
+{
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+    size_t                  userNameLength;
+
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic)
+        &&  (data               != NULL)
+        &&  (length             != NULL))
+    {
+        if (NULL != inst->userPointer)
+        {
+            userNameLength = strlen(inst->userPointer->username);
+
+            if (userNameLength < *length)
+            {
+                (void)strcpy(data, inst->userPointer->username);
+                *length = userNameLength;
+            }
+            else
+            {
+                ret = SHELLMATTA_ERROR;
+            }
+        }
+    }
+    else
+    {
+        ret = SHELLMATTA_USE_FAULT;
     }
     return ret;
 }
 
+/**
+ * @brief       checks if a command is accessible by the logged in user
+ * @param[in]   inst    shellmatta instance to work with
+ * @param[in]   cmd     command to check permissions for
+ * @return      errorcode   #SHELLMATTA_OK      => permitted
+ *                          #SHELLMATTA_ERROR   => not permitted
+ */
 shellmatta_retCode_t shellmatta_auth_is_cmd_permitted(const shellmatta_instance_t *inst, shellmatta_cmd_t *cmd)
 {
     shellmatta_retCode_t    ret     = SHELLMATTA_ERROR;