Skip to content

File wsh_shell_user.c

File List > src > wsh_shell_user.c

Go to the documentation of this file

#include "wsh_shell_user.h"

static void WshShellUser_DefHashFunc(const WshShell_Char_t* pcSalt, const WshShell_Char_t* pcPass,
                                     WshShell_Char_t* pHash) {
    WshShell_Size_t saltLen = WSH_SHELL_STRLEN(pcSalt);
    WshShell_Size_t passLen = WSH_SHELL_STRLEN(pcPass);

    if (saltLen > WSH_SHELL_SALT_LEN || passLen > WSH_SHELL_PASS_LEN) {
        WSH_SHELL_ASSERT(0);
        return;
    }

    char saltPass[WSH_SHELL_SALT_LEN + WSH_SHELL_PASS_LEN + 1];
    WSH_SHELL_MEMCPY(saltPass, pcSalt, saltLen);
    WSH_SHELL_MEMCPY(saltPass + saltLen, pcPass, passLen);
    saltPass[saltLen + passLen] = '\0';

    WshShell_Size_t hash =
        WshShellMisc_CalcJenkinsHash((const WshShell_U8_t*)saltPass, saltLen + passLen);

    WSH_SHELL_SNPRINTF(pHash, WSH_SHELL_SALT_PASS_HASH_LEN + 1, "%08x", hash);
}

WSH_SHELL_RET_STATE_t WshShellUser_Attach(WshShellUser_Table_t* pShellUsers,
                                          const WshShellUser_t* pcUserTable,
                                          WshShell_Size_t userNum,
                                          WshShellUser_HashFunc_t extHashFunc) {
    WSH_SHELL_ASSERT(pShellUsers && pcUserTable && userNum > 0);
    if (!pShellUsers || !pcUserTable || userNum == 0)
        return WSH_SHELL_RET_STATE_ERR_PARAM;

    if (pShellUsers->List != NULL)
        return WSH_SHELL_RET_STATE_ERR_BUSY;  // Already inited

    pShellUsers->List = pcUserTable;
    pShellUsers->Num  = userNum;
    pShellUsers->Hash = extHashFunc ? extHashFunc : WshShellUser_DefHashFunc;

    return WSH_SHELL_RET_STATE_SUCCESS;
}

void WshShellUser_DeAttach(WshShellUser_Table_t* pShellUsers) {
    WSH_SHELL_ASSERT(pShellUsers);

    if (pShellUsers)
        *pShellUsers = (WshShellUser_Table_t){0};
}

WshShell_Size_t WshShellUser_GetUsersNum(WshShellUser_Table_t* pShellUsers) {
    WSH_SHELL_ASSERT(pShellUsers);
    if (!pShellUsers || !pShellUsers->List)
        return 0;

    return pShellUsers->Num;
}

const WshShellUser_t* WshShellUser_GetUserByIndex(WshShellUser_Table_t* pShellUsers,
                                                  WshShell_Size_t idx) {
    WSH_SHELL_ASSERT(pShellUsers);
    if (!pShellUsers || !pShellUsers->List)
        return NULL;

    WSH_SHELL_ASSERT(idx < pShellUsers->Num);

    return idx < pShellUsers->Num ? &pShellUsers->List[idx] : NULL;
}

WshShell_Bool_t WshShellUser_CheckCredentials(WshShellUser_Table_t* pShellUsers,
                                              WshShell_Size_t UserID,
                                              const WshShell_Char_t* pcLogin,
                                              const WshShell_Char_t* pcPass) {
    WSH_SHELL_ASSERT(pShellUsers && pcLogin && pcPass);
    if (!pShellUsers || !pShellUsers->List || !pcLogin || !pcPass)
        return false;

    WSH_SHELL_ASSERT(UserID < pShellUsers->Num);

    if (UserID >= pShellUsers->Num)
        return false;

    WshShell_Size_t loginLen = WSH_SHELL_STRNLEN(pcLogin, WSH_SHELL_LOGIN_LEN + 1);
    WshShell_Size_t passLen  = WSH_SHELL_STRNLEN(pcPass, WSH_SHELL_PASS_LEN + 1);

    if (loginLen > WSH_SHELL_LOGIN_LEN || passLen > WSH_SHELL_PASS_LEN)
        return false;

    const WshShellUser_t* pUser = &pShellUsers->List[UserID];

    if (WSH_SHELL_STRNCMP(pUser->Login, pcLogin, loginLen) != 0)
        return false;

    WshShell_Char_t locSaltPassHash[WSH_SHELL_SALT_PASS_HASH_LEN + 1] = {0};
    pShellUsers->Hash(pUser->Salt, pcPass, locSaltPassHash);

    if (WSH_SHELL_STRNCMP(locSaltPassHash, pUser->Hash, WSH_SHELL_SALT_PASS_HASH_LEN + 1) != 0)
        return false;

    return true;
}

const WshShellUser_t* WshShellUser_FindByCredentials(WshShellUser_Table_t* pShellUsers,
                                                     const WshShell_Char_t* pcLogin,
                                                     const WshShell_Char_t* pcPass) {
    WSH_SHELL_ASSERT(pShellUsers && pcLogin && pcPass);
    if (!pShellUsers || !pShellUsers->List || !pcLogin || !pcPass)
        return NULL;

    for (WshShell_Size_t usr = 0; usr < WshShellUser_GetUsersNum(pShellUsers); usr++) {
        if (WshShellUser_CheckCredentials(pShellUsers, usr, pcLogin, pcPass))
            return WshShellUser_GetUserByIndex(pShellUsers, usr);
    }

    return NULL;
}