// static bool OTKeyring::KWallet_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); KWallet::Wallet* pWallet = OTKeyring::OpenKWallet(); if (nullptr != pWallet) { const QString qstrKey(strUser.Get()); QString qstrPwd; // Get the password // if (pWallet->readPassword(qstrKey, qstrPwd) == 0) { const std::string str_password = qstrPwd.toStdString(); // todo security: notice str_password // isn't zero'd here. OTString strData(str_password); OTASCIIArmor ascData; const bool bLoaded = strData.Exists() && ascData.LoadFromString(strData); strData.zeroMemory(); if (!bLoaded) otErr << __FUNCTION__ << ": Failed trying to decode secret " "from KWallet contents.\n"; else { OTData thePayload(ascData); ascData.zeroMemory(); if (thePayload.IsEmpty()) otErr << __FUNCTION__ << ": Failed trying to decode secret " "OTData from OTASCIIArmor from " "KWallet contents.\n"; else { thePassword.setMemory(thePayload.GetPayloadPointer(), thePayload.GetSize()); thePayload.zeroMemory(); // for security. return true; } } } else otErr << __FUNCITON__ << ": Failed trying to retrieve secret from KWallet.\n"; } // Not an error: what if it just hasn't been set there yet? // otWarn << "OTKeyring::KWallet_RetrieveSecret: No secret found.\n"; return false; }
// static bool OTKeyring::FlatFile_RetrieveSecret(const String& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); const std::string str_pw_folder(OTKeyring::FlatFile_GetPasswordFolder()); if (!str_pw_folder.empty()) { String strExactPath; strExactPath.Format("%s%s%s", str_pw_folder.c_str(), Log::PathSeparator(), strUser.Get()); const std::string str_ExactPath(strExactPath.Get()); // Get the password // OTASCIIArmor ascData; if (!ascData.LoadFromExactPath(str_ExactPath)) otErr << "OTKeyring::FlatFile_RetrieveSecret: " << "Failed trying to decode secret from flat file contents." << "\n"; else { OTData thePayload(ascData); ascData.zeroMemory(); if (thePayload.IsEmpty()) otErr << __FUNCTION__ << ": Failed trying to decode secret " "OTData from OTASCIIArmor from " "flat file contents.\n"; else { thePassword.setMemory(thePayload.GetPointer(), thePayload.GetSize()); thePayload.zeroMemory(); // for security. return true; } } } // Not an error: what if it just hasn't been set there yet? // otWarn << __FUNCTION__ << ": Unable to retrieve any derived key, since " "password_folder not provided in config file.\n"; return false; }
// static bool OTKeyring::Gnome_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); GnomeKeyringResult theResult = GNOME_KEYRING_RESULT_IO_ERROR; gchar* gchar_p_password = nullptr; // if the password exists in the keyring, set it in // thePassword (output argument.) // int32_t nCount = -1; int64_t lSleep = 1; while ((GNOME_KEYRING_RESULT_OK != theResult)) { ++nCount; // 0 on first iteration. theResult = gnome_keyring_find_password_sync( GNOME_KEYRING_NETWORK_PASSWORD, &gchar_p_password, "user", strUser.Get(), "protocol", "opentxs", // todo: hardcoding. nullptr); if (GNOME_KEYRING_RESULT_OK == theResult) break; if (nCount > 2) // todo hardcoding. break; // we try a few times -- not infinite times! OTString strGnomeError(gnome_keyring_result_to_message(theResult)); // OTString strGnomeError; // switch (theResult) { // case GNOME_KEYRING_RESULT_OK: strGnomeError // = "GNOME_KEYRING_RESULT_OK"; break; // case GNOME_KEYRING_RESULT_DENIED: strGnomeError // = "GNOME_KEYRING_RESULT_DENIED"; break; // case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON: strGnomeError // = "GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON"; break; // case GNOME_KEYRING_RESULT_ALREADY_UNLOCKED: strGnomeError // = "GNOME_KEYRING_RESULT_ALREADY_UNLOCKED"; break; // case GNOME_KEYRING_RESULT_NO_SUCH_KEYRING: strGnomeError // = "GNOME_KEYRING_RESULT_NO_SUCH_KEYRING"; break; // case GNOME_KEYRING_RESULT_BAD_ARGUMENTS: strGnomeError // = "GNOME_KEYRING_RESULT_BAD_ARGUMENTS"; break; // case GNOME_KEYRING_RESULT_IO_ERROR: strGnomeError // = "GNOME_KEYRING_RESULT_IO_ERROR"; break; // case GNOME_KEYRING_RESULT_CANCELLED: strGnomeError // = "GNOME_KEYRING_RESULT_CANCELLED"; break; // case GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS: // strGnomeError = "GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS"; break; // case GNOME_KEYRING_RESULT_NO_MATCH: strGnomeError // = "GNOME_KEYRING_RESULT_NO_MATCH"; break; // // default: // strGnomeError = "Unknown! Very strange!"; // break; // } otErr << __FUNCTION__ << ": gnome_keyring_find_password_sync returned " << strGnomeError.Get() << '\n'; otErr << "Remedy: Sleeping for " << lSleep << " seconds and then retrying (attempt " << (nCount + 2) << '\n'; // on first iteration, nCount is 0, and this will say "attempt 2" aka // "second attempt," which is correct. sleep(lSleep); lSleep *= 2; // double it each time } if ((theResult == GNOME_KEYRING_RESULT_OK) && (nullptr != gchar_p_password)) { size_t sizePassword = OTString::safe_strlen(gchar_p_password, MAX_STRING_LENGTH); if (sizePassword > 0) { OTString strData(gchar_p_password, sizePassword); gnome_keyring_free_password(gchar_p_password); gchar_p_password = nullptr; OTASCIIArmor ascData; const bool bLoaded = strData.Exists() && ascData.LoadFromString(strData); strData.zeroMemory(); if (!bLoaded) otErr << __FUNCTION__ << ": Failed trying to decode secret " "from Gnome Keyring contents:\n\n" << strData.Get() << "\n\n"; else { OTData thePayload(ascData); ascData.zeroMemory(); if (thePayload.IsEmpty()) otErr << __FUNCTION__ << ": Failed trying to decode secret " "OTData from OTASCIIArmor " << "from Gnome Keyring contents:\n\n" << strData.Get() << "\n\n"; else { thePassword.setMemory(thePayload.GetPayloadPointer(), thePayload.GetSize()); thePayload.zeroMemory(); // for security. return true; } return false; } } } // Not an error: what if it just hasn't been set there yet? // otOut << "OTKeyring::Gnome_RetrieveSecret: " << "No secret found: gnome_keyring_find_password_sync: " << gnome_keyring_result_to_message(theResult) << '\n'; return false; }