/** * Validates that the provided password is correct. * This is used in the GUI to guard access to certain actions. * * @param szPassword The password to check. * @param pOk Set to true if the password is good, or false otherwise. */ tABC_CC ABC_LoginPasswordOk(Login &login, const char *szPassword, bool *pOk, tABC_Error *pError) { tABC_CC cc = ABC_CC_Ok; tABC_CarePackage *pCarePackage = NULL; tABC_LoginPackage *pLoginPackage = NULL; AutoU08Buf LP; AutoU08Buf LP2; AutoU08Buf MK; *pOk = false; // Load the packages: ABC_CHECK_RET(ABC_LoginDirLoadPackages(login.lobby().dir(), &pCarePackage, &pLoginPackage, pError)); // LP = L + P: ABC_BUF_STRCAT(LP, login.lobby().username().c_str(), szPassword); ABC_CHECK_RET(ABC_CryptoScryptSNRP(LP, pCarePackage->pSNRP2, &LP2, pError)); // Try to decrypt MK: tABC_Error error; if (ABC_CC_Ok == ABC_CryptoDecryptJSONObject(pLoginPackage->EMK_LP2, LP2, &MK, &error)) { *pOk = true; } exit: ABC_CarePackageFree(pCarePackage); ABC_LoginPackageFree(pLoginPackage); return cc; }
static tABC_CC ABC_LoginPasswordDisk(std::shared_ptr<Login> &result, std::shared_ptr<Lobby> lobby, tABC_U08Buf LP, tABC_Error *pError) { tABC_CC cc = ABC_CC_Ok; std::unique_ptr<Login> login; tABC_CarePackage *pCarePackage = NULL; tABC_LoginPackage *pLoginPackage = NULL; AutoU08Buf LP2; AutoU08Buf MK; // Load the packages: ABC_CHECK_RET(ABC_LoginDirLoadPackages(lobby->dir(), &pCarePackage, &pLoginPackage, pError)); // Decrypt MK: ABC_CHECK_RET(ABC_CryptoScryptSNRP(LP, pCarePackage->pSNRP2, &LP2, pError)); ABC_CHECK_RET(ABC_CryptoDecryptJSONObject(pLoginPackage->EMK_LP2, LP2, &MK, pError)); // Decrypt SyncKey: login.reset(new Login(lobby, static_cast<U08Buf>(MK))); ABC_CHECK_NEW(login->init(pLoginPackage), pError); result.reset(login.release()); exit: ABC_CarePackageFree(pCarePackage); ABC_LoginPackageFree(pLoginPackage); return cc; }
/** * Changes the password on an existing login object. * @param szPassword The new password. */ tABC_CC ABC_LoginPasswordSet(Login &login, const char *szPassword, tABC_Error *pError) { tABC_CC cc = ABC_CC_Ok; tABC_CarePackage *pCarePackage = NULL; tABC_LoginPackage *pLoginPackage = NULL; AutoU08Buf oldL1; AutoU08Buf oldLP1; AutoU08Buf oldLRA1; AutoU08Buf LP; AutoU08Buf LP1; AutoU08Buf LP2; // Load the packages: ABC_CHECK_RET(ABC_LoginDirLoadPackages(login.lobby().dir(), &pCarePackage, &pLoginPackage, pError)); // Load the old keys: ABC_CHECK_RET(ABC_LoginGetServerKeys(login, &oldL1, &oldLP1, pError)); if (pLoginPackage->ELRA1) { ABC_CHECK_RET(ABC_CryptoDecryptJSONObject(pLoginPackage->ELRA1, toU08Buf(login.dataKey()), &oldLRA1, pError)); } // Update SNRP2: ABC_CryptoFreeSNRP(pCarePackage->pSNRP2); pCarePackage->pSNRP2 = nullptr; ABC_CHECK_RET(ABC_CryptoCreateSNRPForClient(&pCarePackage->pSNRP2, pError)); // LP = L + P: ABC_BUF_STRCAT(LP, login.lobby().username().c_str(), szPassword); // Update EMK_LP2: json_decref(pLoginPackage->EMK_LP2); ABC_CHECK_RET(ABC_CryptoScryptSNRP(LP, pCarePackage->pSNRP2, &LP2, pError)); ABC_CHECK_RET(ABC_CryptoEncryptJSONObject(toU08Buf(login.dataKey()), LP2, ABC_CryptoType_AES256, &pLoginPackage->EMK_LP2, pError)); // Update ELP1: json_decref(pLoginPackage->ELP1); ABC_CHECK_RET(ABC_CryptoScryptSNRP(LP, pCarePackage->pSNRP1, &LP1, pError)); ABC_CHECK_RET(ABC_CryptoEncryptJSONObject(LP1, toU08Buf(login.dataKey()), ABC_CryptoType_AES256, &pLoginPackage->ELP1, pError)); // Change the server login: ABC_CHECK_RET(ABC_LoginServerChangePassword(oldL1, oldLP1, LP1, oldLRA1, pCarePackage, pLoginPackage, pError)); // Change the on-disk login: ABC_CHECK_RET(ABC_LoginDirSavePackages(login.lobby().dir(), pCarePackage, pLoginPackage, pError)); exit: ABC_CarePackageFree(pCarePackage); ABC_LoginPackageFree(pLoginPackage); return cc; }
/** * Loads a CarePackage object from a string. */ tABC_CC ABC_CarePackageDecode(tABC_CarePackage **ppSelf, char *szCarePackage, tABC_Error *pError) { tABC_CC cc = ABC_CC_Ok; tABC_CarePackage *pSelf = NULL; json_t *pJSON_Root = NULL; json_t *pJSON_SNRP2 = NULL; json_t *pJSON_SNRP3 = NULL; json_t *pJSON_SNRP4 = NULL; int e; // Allocate self: ABC_NEW(pSelf, tABC_CarePackage); // Parse the JSON: json_error_t error; pJSON_Root = json_loads(szCarePackage, 0, &error); ABC_CHECK_ASSERT(pJSON_Root != NULL, ABC_CC_JSONError, "Error parsing CarePackage JSON"); ABC_CHECK_ASSERT(json_is_object(pJSON_Root), ABC_CC_JSONError, "Error parsing CarePackage JSON"); // Unpack the contents: e = json_unpack(pJSON_Root, "{s:o, s:o, s:o, s?o}", JSON_ACCT_SNRP2_FIELD, &pJSON_SNRP2, JSON_ACCT_SNRP3_FIELD, &pJSON_SNRP3, JSON_ACCT_SNRP4_FIELD, &pJSON_SNRP4, JSON_ACCT_ERQ_FIELD, &pSelf->ERQ); ABC_CHECK_SYS(!e, "Error parsing CarePackage JSON"); // Decode SNRP's: ABC_CHECK_RET(ABC_CryptoCreateSNRPForServer(&pSelf->pSNRP1, pError)); ABC_CHECK_RET(ABC_CryptoDecodeJSONObjectSNRP(pJSON_SNRP2, &pSelf->pSNRP2, pError)); ABC_CHECK_RET(ABC_CryptoDecodeJSONObjectSNRP(pJSON_SNRP3, &pSelf->pSNRP3, pError)); ABC_CHECK_RET(ABC_CryptoDecodeJSONObjectSNRP(pJSON_SNRP4, &pSelf->pSNRP4, pError)); // Save everything: if (pSelf->ERQ) json_incref(pSelf->ERQ); *ppSelf = pSelf; pSelf = NULL; exit: if (pSelf) ABC_CarePackageFree(pSelf); if (pJSON_Root) json_decref(pJSON_Root); return cc; }
static tABC_CC ABC_LoginPasswordServer(std::shared_ptr<Login> &result, std::shared_ptr<Lobby> lobby, tABC_U08Buf LP, tABC_Error *pError) { tABC_CC cc = ABC_CC_Ok; std::unique_ptr<Login> login; tABC_CarePackage *pCarePackage = NULL; tABC_LoginPackage *pLoginPackage = NULL; tABC_U08Buf LRA1 = ABC_BUF_NULL; // Do not free AutoU08Buf LP1; AutoU08Buf LP2; AutoU08Buf MK; // Get the CarePackage: ABC_CHECK_RET(ABC_LoginServerGetCarePackage(toU08Buf(lobby->authId()), &pCarePackage, pError)); // Get the LoginPackage: ABC_CHECK_RET(ABC_CryptoScryptSNRP(LP, pCarePackage->pSNRP1, &LP1, pError)); ABC_CHECK_RET(ABC_LoginServerGetLoginPackage(toU08Buf(lobby->authId()), LP1, LRA1, &pLoginPackage, pError)); // Decrypt MK: ABC_CHECK_RET(ABC_CryptoScryptSNRP(LP, pCarePackage->pSNRP2, &LP2, pError)); ABC_CHECK_RET(ABC_CryptoDecryptJSONObject(pLoginPackage->EMK_LP2, LP2, &MK, pError)); // Decrypt SyncKey: login.reset(new Login(lobby, static_cast<U08Buf>(MK))); ABC_CHECK_NEW(login->init(pLoginPackage), pError); // Set up the on-disk login: ABC_CHECK_RET(ABC_LoginDirSavePackages(lobby->dir(), pCarePackage, pLoginPackage, pError)); // Assign the result: result.reset(login.release()); exit: ABC_CarePackageFree(pCarePackage); ABC_LoginPackageFree(pLoginPackage); return cc; }
/** * Constructs a fresh CarePackage object with default values for all fields. */ tABC_CC ABC_CarePackageNew(tABC_CarePackage **ppSelf, tABC_Error *pError) { tABC_CC cc = ABC_CC_Ok; tABC_CarePackage *pSelf = NULL; // Allocate self: ABC_NEW(pSelf, tABC_CarePackage); // Generate SNRP's: ABC_CHECK_RET(ABC_CryptoCreateSNRPForServer(&pSelf->pSNRP1, pError)); ABC_CHECK_RET(ABC_CryptoCreateSNRPForClient(&pSelf->pSNRP2, pError)); ABC_CHECK_RET(ABC_CryptoCreateSNRPForClient(&pSelf->pSNRP3, pError)); ABC_CHECK_RET(ABC_CryptoCreateSNRPForClient(&pSelf->pSNRP4, pError)); *ppSelf = pSelf; pSelf = NULL; exit: if (pSelf) ABC_CarePackageFree(pSelf); return cc; }