Sfoglia il codice sorgente

finished login command
added hide mode to be able to insert chars into the buffer without printing them out
shifting stdin buffer for contionuous commands
added input wrapper to mimic behaviour of shellmatta input for username and passwords

stefan 1 anno fa
parent
commit
186d76d30e
7 ha cambiato i file con 224 aggiunte e 100 eliminazioni
  1. 31 29
      api/shellmatta.h
  2. 2 2
      example/main.c
  3. 4 4
      src/shellmatta.c
  4. 158 50
      src/shellmatta_auth.c
  5. 1 1
      src/shellmatta_autocomplete.c
  6. 26 13
      src/shellmatta_utils.c
  7. 2 1
      src/shellmatta_utils.h

+ 31 - 29
api/shellmatta.h

@@ -110,7 +110,7 @@ typedef struct
     uint32_t    userId;     /**< id of the user (!= 0)                              */
     const char  *username;  /**< name of the user role                              */
     const char  *password;  /**< password of the user role or NULL (custom auth)    */
-} shellmatta_user_t;
+} shellmatta_auth_user_t;
 
 /**
  * @brief typedefinition of one line of the authentication table
@@ -120,15 +120,15 @@ 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;
+} shellmatta_auth_perm_t;
 
 /**
  * @brief custom shellmatta authentication method
- * @param[in]   username    username to log in (name of the user role)
+ * @param[in]   userId      user id to log in (name of the user role)
  * @param[in]   password    password for the login
  * @return      #SHELLMATTA_OK if the username and password is correct
  */
-typedef shellmatta_retCode_t (*shellmatta_check_t)(const char* username, const char* password);
+typedef shellmatta_retCode_t (*shellmatta_auth_check_t)(const uint32_t userId, const char* password);
 
 /**
  * @brief login states
@@ -138,7 +138,7 @@ typedef enum
     SHELLMATTA_AUTH_IDLE,       /**< authentication system waits    */
     SHELLMATTA_AUTH_USERNAME,   /**< input of username              */
     SHELLMATTA_AUTH_PASSWORD    /**< input of password              */
-} shellmatta_auth_status_t;
+} shellmatta_auth_state_t;
 
 #endif
 
@@ -154,7 +154,7 @@ typedef struct shellmatta_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 */
+    shellmatta_auth_perm_t  *authLink;  /**< internally used - pointer to perm list */
 #endif
 } shellmatta_cmd_t;
 
@@ -199,15 +199,17 @@ typedef struct
                                                      initialization                         */
     shellmatta_opt_t    optionParser;           /**< option parser sructure                 */
 #ifdef SHELLMATTA_AUTHENTICATION
-    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       */
+    shellmatta_auth_state_t     loginState;     /**< state variable of the login cmd        */
+    shellmatta_cmd_t            loginCmd;       /**< login command structure                */
+    shellmatta_cmd_t            logoutCmd;      /**< logout command structure               */
+    uint32_t                    userId;         /**< user ID of the current session         */
+    uint32_t                    tmpUserId;      /**< remporary user ID during input         */
+    shellmatta_auth_user_t      *userPointer;   /**< pointer to the user in the user list   */
+    shellmatta_auth_user_t      *userList;      /**< user list                              */
+    uint32_t                    userListLength; /**< length of the user list                */
+    shellmatta_auth_perm_t      *permList;      /**< permission list                        */
+    uint32_t                    permListLength; /**< length of the permission list          */
+    shellmatta_auth_check_t     checkFct;       /**< custom credential check function       */
 #endif
 } shellmatta_instance_t;
 
@@ -268,20 +270,20 @@ shellmatta_retCode_t shellmatta_printf(     shellmatta_handle_t handle,
 
 #ifdef SHELLMATTA_AUTHENTICATION
 
-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);
+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_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
 

+ 2 - 2
example/main.c

@@ -222,14 +222,14 @@ int main(int argc, char **argv)
     shellmatta_addCmd(handle, &busyCommand);
 
 
-    shellmatta_user_t userList[] = {
+    shellmatta_auth_user_t userList[] = {
         {1, "shimatta", "12345678"},
         {2, "not_shimatta", "87654321"}
     };
 
     uint32_t doSomeCmdPerms[] = {1, 2};
     uint32_t removeCommandPerms[] = {1};
-    shellmatta_perm_t permList[] = {
+    shellmatta_auth_perm_t permList[] = {
         {"adoSome2", doSomeCmdPerms, sizeof(doSomeCmdPerms)/sizeof(doSomeCmdPerms[0])},
         {"remove", removeCommandPerms, sizeof(removeCommandPerms)/sizeof(removeCommandPerms[0])}
     };

+ 4 - 4
src/shellmatta.c

@@ -518,7 +518,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                             inst->hereLength = inst->inputCount - inst->hereDelimiterIdx;
 
                             inst->dirty = true;
-                            utils_insertChars(inst, &data[inst->byteCounter], 1u);
+                            utils_insertChars(inst, &data[inst->byteCounter], 1u, false);
                             inst->lastNewlineIdx = inst->inputCount;
                         }
                         else
@@ -591,7 +591,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                     {
                         /** -# the party goes on - just print the delimiter and store the position */
                         inst->lastNewlineIdx = inst->inputCount;
-                        utils_insertChars(inst, &data[inst->byteCounter], 1u);
+                        utils_insertChars(inst, &data[inst->byteCounter], 1u, false);
                     }
                 }
 
@@ -629,7 +629,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                             {
                                 case SHELLMATTA_CONTINUE:
                                     /** -# initialize stdin buffer and continuous cmd */
-                                    inst->stdinIdx      = inst->inputCount + 1u;
+                                    inst->stdinIdx      = inst->bufferSize - 2u;
                                     inst->stdinLength   = 0u;
                                     inst->continuousCmd = cmd;
                                     ret                 = cmdRet;
@@ -702,7 +702,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
             else
             {
                 inst->dirty = true;
-                utils_insertChars(inst, &data[inst->byteCounter], 1u);
+                utils_insertChars(inst, &data[inst->byteCounter], 1u, false);
             }
 
             /** -# reset tab counter on not a tab */

+ 158 - 50
src/shellmatta_auth.c

@@ -20,31 +20,89 @@
 #include "shellmatta.h"
 #include "shellmatta_auth.h"
 #include "shellmatta_history.h"
+#include "shellmatta_utils.h"
+#include "shellmatta_escape.h"
 #include <stdint.h>
 #include <stddef.h>
 #include <string.h>
 
-static uint32_t checkFct(shellmatta_handle_t handle, char *username, char *password)
+shellmatta_retCode_t inputWrapper(shellmatta_instance_t *inst, char data, bool hide)
+{
+    shellmatta_retCode_t ret = SHELLMATTA_BUSY;
+
+    /** -# handle escape sequences */
+    if(inst->escapeCounter != 0u)
+    {
+        escape_handleSequence(inst, data);
+    }
+    else if (inst->delimiter == data)
+    {
+        ret = SHELLMATTA_OK;
+    }
+        /** -# ignore newline as first character (to be compatible to
+     * terminals sending newline after return */
+    else if((0u == inst->inputCount) && ('\n' == data))
+    {
+        /* do nothing */
+    }
+    /** -# check for backspace */
+    else if(    ('\b'   == data)
+            ||  ('\x7f' == data))
+    {
+        utils_removeChars(inst, 1u, true);
+    }
+    /** -# check for start of escape sequence */
+    else if('\x1b' == data)
+    {
+        inst->escapeCounter = 1u;
+    }
+    else
+    {
+        utils_insertChars(inst, &data, 1u, hide);
+    }
+    return ret;
+}
+
+static uint32_t getUserIdFromName(shellmatta_handle_t handle, char *username)
 {
     shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
     uint32_t                userId  = 0u;
     uint32_t                i;
 
+    for (i = 0u; i < inst->userListLength; i++)
+    {
+        /** search for user */
+        if (0 == strcmp(inst->userList[i].username, username))
+        {
+            userId = inst->userList[i].userId;
+            break;
+        }
+    }
+
+    return userId;
+}
+
+void checkFct(shellmatta_handle_t handle, uint32_t userId, char *password)
+{
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+    uint32_t                approvedUserId  = 0u;
+    uint32_t                i;
+
     if (NULL != inst->checkFct)
     {
-        userId = inst->checkFct(username, password);
+        approvedUserId = inst->checkFct(userId, password);
     }
     else
     {
         for (i = 0u; i < inst->userListLength; i++)
         {
             /** search for user */
-            if (0 == strcmp(inst->userList[i].username, username))
+            if (inst->userList[i].userId == userId)
             {
                 /** check password */
                 if (0 == strcmp(inst->userList[i].password, password))
                 {
-                    userId = inst->userList[i].userId;
+                    approvedUserId = inst->userList[i].userId;
                 }
                 break;
             }
@@ -52,16 +110,31 @@ static uint32_t checkFct(shellmatta_handle_t handle, char *username, char *passw
     }
 
     /** print login result */
-    if (0 == userId)
+    if (0 == approvedUserId)
     {
-        shellmatta_write(handle, "username or password is wrong\n", 30);
+        shellmatta_write(handle, "username or password is wrong\r\n", 31);
     }
     else
     {
-        shellmatta_write(handle, "login successful\n", 17);
+        shellmatta_write(handle, "login successful\r\n", 18);
     }
 
-    return userId;
+    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;
+    }
 }
 
 /**
@@ -76,62 +149,95 @@ static shellmatta_retCode_t loginCmdFct(const shellmatta_handle_t handle, const
 {
     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[] = 
+    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(inst->loginState)
     {
-        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++)
+        case SHELLMATTA_AUTH_IDLE:
+            ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
+            while(SHELLMATTA_OK == ret)
             {
-                if (0 == strcmp(inst->userList[i].username, username))
+                switch(option)
                 {
-                    inst->userPointer = &inst->userList[i];
-                    break;
+                    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);
             }
-        }
-        else
-        {
-            inst->userPointer = NULL;
-        }
+
+            if ((NULL != username) && (NULL != password))
+            {
+                inst->tmpUserId = getUserIdFromName(handle, username);
+                checkFct(handle, inst->tmpUserId, password);
+            }
+            else
+            {
+                inst->inputCount = 0u;
+                inst->cursor = 0u;
+                /** 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:
+            (void)shellmatta_read(handle, &argument, &argLen);
+            if ((1 == argLen) && (SHELLMATTA_OK == inputWrapper(inst, argument[0], false)))
+            {
+                /** store user id */
+                inst->buffer[inst->inputCount] = '\0';
+                inst->tmpUserId = getUserIdFromName(handle, inst->buffer);
+
+                /** reinitialize input */
+                inst->inputCount = 0u;
+                inst->cursor = 0u;
+
+                shellmatta_write(handle, "\r\nenter password:\r\n", 19);
+                inst->loginState = SHELLMATTA_AUTH_PASSWORD;
+            }
+            ret = SHELLMATTA_CONTINUE;
+            break;
+        case SHELLMATTA_AUTH_PASSWORD:
+            (void)shellmatta_read(handle, &argument, &argLen);
+            if ((1 == argLen) && (SHELLMATTA_OK == inputWrapper(inst, argument[0], true)))
+            {
+                inst->buffer[inst->inputCount] = '\0';
+                shellmatta_write(handle, "\r\n", 2);
+                checkFct(handle, inst->tmpUserId, inst->buffer);
+                inst->loginState = SHELLMATTA_AUTH_IDLE;
+            }
+            else
+            {
+                ret = SHELLMATTA_CONTINUE;
+            }
+            break;
+        default:
+            break;
     }
 
     (void)arguments;
@@ -166,7 +272,7 @@ static shellmatta_retCode_t logoutCmdFct(const shellmatta_handle_t handle, const
     /** reset history buffer */
     history_reset(inst);
 
-    shellmatta_write(handle, "good bye\n", 9);
+    shellmatta_write(handle, "good bye\r\n", 10);
 
     (void)arguments;
     (void)length;
@@ -195,19 +301,21 @@ const shellmatta_cmd_t shellmatta_auth_logoutCmd = {"logout"
  *                          #SHELLMATTA_USE_FAULT (param err)
  */
 shellmatta_retCode_t shellmatta_auth_init(shellmatta_handle_t   handle,
-                                          shellmatta_user_t     *userList,
+                                          shellmatta_auth_user_t     *userList,
                                           uint32_t              userListLength,
-                                          shellmatta_perm_t     *permList,
+                                          shellmatta_auth_perm_t     *permList,
                                           uint32_t              permListLength,
                                           bool                  customLogin,
-                                          shellmatta_check_t    checkFct)
+                                          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;

+ 1 - 1
src/shellmatta_autocomplete.c

@@ -158,7 +158,7 @@ void autocomplete_run(shellmatta_instance_t *inst)
             sizeDiff = minLen - inst->cursor;
 
             /** -# copy the found part into the buffer and display it */
-            utils_insertChars(inst, &(tempCmd[inst->cursor]), sizeDiff);
+            utils_insertChars(inst, &(tempCmd[inst->cursor]), sizeDiff, false);
 
             /** -# on exact match there is no need to double Tab to display all */
             if(true == exactMatch)

+ 26 - 13
src/shellmatta_utils.c

@@ -19,6 +19,9 @@
 
 #include "shellmatta_utils.h"
 #include "shellmatta.h"
+#ifdef SHELLMATTA_AUTHENTICATION
+#include "shellmatta_auth.h"
+#endif
 #include <string.h>
 
 /**
@@ -162,10 +165,12 @@ void utils_forwardCursor(shellmatta_instance_t *inst, uint32_t length)
  * @param[in]   inst    pointer to shellmatta instance
  * @param[in]   data    pointer to the data to be inserted
  * @param[in]   length  length of the data to be inserted
+ * @param[in]   hide    true: only manipulate buffer do not print anything
  */
 void utils_insertChars( shellmatta_instance_t   *inst,
                         char                    *data,
-                        uint32_t                 length)
+                        uint32_t                 length,
+                        bool                     hide)
 {
     uint32_t tmpLength = length;
     /** -# limit the length to the space left in the buffer */
@@ -189,23 +194,30 @@ void utils_insertChars( shellmatta_instance_t   *inst,
 
             /** -# store and print the new chars */
             memcpy(&(inst->buffer[inst->cursor]), data, tmpLength);
-            utils_writeEcho(inst, data, tmpLength);
-
-            /** -# print the other chars and restore the cursor to this position */
-            utils_eraseLine(inst);
-            utils_saveCursorPos(inst);
-            utils_writeEcho(  inst,
-                        &(inst->buffer[inst->cursor + tmpLength]),
-                        inst->inputCount - inst->cursor);
-            utils_restoreCursorPos(inst);
-            inst->cursor        += tmpLength;
-            inst->inputCount    += tmpLength;
+
+            if (false == hide)
+            {
+                utils_writeEcho(inst, data, tmpLength);
+
+                /** -# print the other chars and restore the cursor to this position */
+                utils_eraseLine(inst);
+                utils_saveCursorPos(inst);
+                utils_writeEcho(  inst,
+                            &(inst->buffer[inst->cursor + tmpLength]),
+                            inst->inputCount - inst->cursor);
+                utils_restoreCursorPos(inst);
+            }
+                inst->cursor        += tmpLength;
+                inst->inputCount    += tmpLength;
         }
         /** -# overwrite - if the cursor reaches the end of the input it is pushed further */
         else
         {
             memcpy(&(inst->buffer[inst->cursor]), data, tmpLength);
-            utils_writeEcho(inst, data, tmpLength);
+            if (false == hide)
+            {
+                utils_writeEcho(inst, data, tmpLength);
+            }
             inst->cursor += tmpLength;
             if(inst->cursor > inst->inputCount)
             {
@@ -458,6 +470,7 @@ void utils_terminateInput(shellmatta_instance_t *inst)
     inst->busyCmd           = NULL;
     inst->write("\r\n", 2u);
 #ifdef SHELLMATTA_AUTHENTICATION
+    inst->loginState        = SHELLMATTA_AUTH_IDLE;
     if (NULL != inst->userPointer)
     {
         inst->write(inst->userPointer->username, strlen(inst->userPointer->username));

+ 2 - 1
src/shellmatta_utils.h

@@ -114,7 +114,8 @@ void utils_rewindCursor(shellmatta_instance_t *inst, uint32_t length);
 void utils_forwardCursor(shellmatta_instance_t *inst, uint32_t length);
 void utils_insertChars( shellmatta_instance_t   *inst,
                         char                    *data,
-                        uint32_t                 length);
+                        uint32_t                 length,
+                        bool                     hide);
 void utils_removeChars( shellmatta_instance_t   *inst,
                         uint32_t                 length,
                         bool                     backspace);