diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-09-22 15:14:53 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-22 15:14:53 -0400 |
| commit | 5044a6cd2c7d75e2505e5abc6645fc990f343dc9 (patch) | |
| tree | e06b037a1d44876a895fd5ecc47071477e52101b /src/settingsutilities.cpp | |
| parent | f69559fe0bd40629e66ecde6e362b73595d9bd2e (diff) | |
| parent | c1a5f2ef73f4435c08876155d4551c045d5e7594 (diff) | |
Merge pull request #839 from isanae/even-more-logging
Even more logging
Diffstat (limited to 'src/settingsutilities.cpp')
| -rw-r--r-- | src/settingsutilities.cpp | 144 |
1 files changed, 104 insertions, 40 deletions
diff --git a/src/settingsutilities.cpp b/src/settingsutilities.cpp index 7a9dcc35..db7c1818 100644 --- a/src/settingsutilities.cpp +++ b/src/settingsutilities.cpp @@ -213,55 +213,119 @@ 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; +} + +bool deleteWindowsCredential(const QString& key) +{ + const auto credName = credentialName(key); + + if (!CredDeleteW(credName.toStdWString().c_str(), CRED_TYPE_GENERIC, 0)) { + const auto e = GetLastError(); - 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; + // not an error if the key already doesn't exist, and don't log it because + // it happens all the time when the settings dialog is closed since it + // doesn't check first + if (e == ERROR_NOT_FOUND) { + return true; + } - result = CredWriteW(&cred, 0); - delete[] charData; + 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("set 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; } |
