summaryrefslogtreecommitdiff
path: root/src/settingsutilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/settingsutilities.cpp')
-rw-r--r--src/settingsutilities.cpp142
1 files changed, 102 insertions, 40 deletions
diff --git a/src/settingsutilities.cpp b/src/settingsutilities.cpp
index 7a9dcc35..6c99a602 100644
--- a/src/settingsutilities.cpp
+++ b/src/settingsutilities.cpp
@@ -213,55 +213,117 @@ void warnIfNotCheckable(const QAbstractButton* b)
}
-bool setWindowsCredential(const QString key, const QString data)
+QString credentialName(const QString& key)
{
- QString finalKey("ModOrganizer2_" + key);
- wchar_t* keyData = new wchar_t[finalKey.size()+1];
- finalKey.toWCharArray(keyData);
- keyData[finalKey.size()] = L'\0';
- bool result = false;
- if (data.isEmpty()) {
- result = CredDeleteW(keyData, CRED_TYPE_GENERIC, 0);
- if (!result)
- if (GetLastError() == ERROR_NOT_FOUND)
- result = true;
- } else {
- wchar_t* charData = new wchar_t[data.size()];
- data.toWCharArray(charData);
+ return "ModOrganizer2_" + key;
+}
- CREDENTIALW cred = {};
- cred.Flags = 0;
- cred.Type = CRED_TYPE_GENERIC;
- cred.TargetName = keyData;
- cred.CredentialBlob = (LPBYTE)charData;
- cred.CredentialBlobSize = sizeof(wchar_t) * data.size();
- cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
+bool deleteWindowsCredential(const QString& key)
+{
+ const auto credName = credentialName(key);
- result = CredWriteW(&cred, 0);
- delete[] charData;
+ if (!CredDeleteW(credName.toStdWString().c_str(), CRED_TYPE_GENERIC, 0)) {
+ const auto e = GetLastError();
+ if (e == ERROR_NOT_FOUND) {
+ // not an error if the key already doesn't exist
+ log::debug("can't delete windows credential {}, doesn't exist", credName);
+ return true;
+ } else {
+ log::error(
+ "failed to delete windows credential {}, {}",
+ credName, formatSystemMessage(e));
+ return false;
+ }
}
- delete[] keyData;
- return result;
+
+ log::debug("deleted windows credential {}", credName);
+
+ return true;
}
-QString getWindowsCredential(const QString key)
+bool addWindowsCredential(const QString& key, const QString& data)
{
- QString result;
- QString finalKey("ModOrganizer2_" + key);
- wchar_t* keyData = new wchar_t[finalKey.size()+1];
- finalKey.toWCharArray(keyData);
- keyData[finalKey.size()] = L'\0';
- PCREDENTIALW creds;
- if (CredReadW(keyData, 1, 0, &creds)) {
- wchar_t *charData = (wchar_t *)creds->CredentialBlob;
- result = QString::fromWCharArray(charData, creds->CredentialBlobSize / sizeof(wchar_t));
- CredFree(creds);
- } else {
+ const auto credName = credentialName(key);
+
+ const auto wname = credName.toStdWString();
+ const auto wdata = data.toStdWString();
+
+ const auto* blob = reinterpret_cast<const BYTE*>(wdata.data());
+ const auto blobSize = wdata.size() * sizeof(decltype(wdata)::value_type);
+
+ CREDENTIALW cred = {};
+ cred.Flags = 0;
+ cred.Type = CRED_TYPE_GENERIC;
+ cred.TargetName = const_cast<wchar_t*>(wname.c_str());
+ cred.CredentialBlob = const_cast<BYTE*>(blob);
+ cred.CredentialBlobSize = static_cast<DWORD>(blobSize);
+ cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
+
+ if (!CredWriteW(&cred, 0)) {
+ const auto e = GetLastError();
+
+ log::error(
+ "failed to delete windows credential {}, {}",
+ credName, formatSystemMessage(e));
+
+ return false;
+ }
+
+ log::debug("added windows credential {}", credName);
+
+ return true;
+}
+
+struct CredentialFreer
+{
+ void operator()(CREDENTIALW* c)
+ {
+ if (c) {
+ CredFree(c);
+ }
+ }
+};
+
+using CredentialPtr = std::unique_ptr<CREDENTIALW, CredentialFreer>;
+
+QString getWindowsCredential(const QString& key)
+{
+ const QString credName = credentialName(key);
+
+ CREDENTIALW* rawCreds = nullptr;
+
+ const auto ret = CredReadW(
+ credName.toStdWString().c_str(), CRED_TYPE_GENERIC, 0, &rawCreds);
+
+ CredentialPtr creds(rawCreds);
+
+ if (!ret) {
const auto e = GetLastError();
+
if (e != ERROR_NOT_FOUND) {
- log::error("Retrieving encrypted data failed: {}", formatSystemMessage(e));
+ log::error(
+ "failed to retrieve windows credential {}: {}",
+ credName, formatSystemMessage(e));
}
+
+ return {};
+ }
+
+ QString value;
+ if (creds->CredentialBlob) {
+ value = QString::fromWCharArray(
+ reinterpret_cast<const wchar_t*>(creds->CredentialBlob),
+ creds->CredentialBlobSize / sizeof(wchar_t));
+ }
+
+ return value;
+}
+
+bool setWindowsCredential(const QString& key, const QString& data)
+{
+ if (data.isEmpty()) {
+ return deleteWindowsCredential(key);
+ } else {
+ return addWindowsCredential(key, data);
}
- delete[] keyData;
- return result;
}