summaryrefslogtreecommitdiff
path: root/src/settings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings.cpp')
-rw-r--r--src/settings.cpp165
1 files changed, 117 insertions, 48 deletions
diff --git a/src/settings.cpp b/src/settings.cpp
index 0ce647fd..7b4b3a67 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -57,6 +57,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QtDebug> // for qDebug, qWarning
#include <Windows.h> // For ShellExecuteW, HINSTANCE, etc
+#include <wincred.h> // For storage
#include <algorithm> // for sort
#include <memory>
@@ -80,10 +81,6 @@ private:
int m_SortRole;
};
-
-static const unsigned char Key2[20] = { 0x99, 0xb8, 0x76, 0x42, 0x3e, 0xc1, 0x60, 0xa4, 0x5b, 0x01,
- 0xdb, 0xf8, 0x43, 0x3a, 0xb7, 0xb6, 0x98, 0xd4, 0x7d, 0xa2 };
-
Settings *Settings::s_Instance = nullptr;
@@ -175,26 +172,60 @@ void Settings::registerPlugin(IPlugin *plugin)
}
}
-QString Settings::obfuscate(const QString &password)
+bool Settings::obfuscate(const QString key, const QString data)
{
- QByteArray temp = password.toUtf8();
+ 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);
+
+ 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;
- QByteArray buffer;
- for (int i = 0; i < temp.length(); ++i) {
- buffer.append(temp.at(i) ^ Key2[i % 20]);
+ result = CredWriteW(&cred, 0);
+ delete[] charData;
}
- return buffer.toBase64();
+ delete[] keyData;
+ return result;
}
-QString Settings::deObfuscate(const QString &password)
+QString Settings::deObfuscate(const QString key)
{
- QByteArray temp(QByteArray::fromBase64(password.toUtf8()));
-
- QByteArray buffer;
- for (int i = 0; i < temp.length(); ++i) {
- buffer.append(temp.at(i) ^ Key2[i % 20]);
+ 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 {
+ if (GetLastError() != ERROR_NOT_FOUND) {
+ wchar_t buffer[256];
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer, (sizeof(buffer) / sizeof(wchar_t)), NULL);
+ qCritical() << "Retrieving encrypted data failed:" << buffer;
+ }
}
- return QString::fromUtf8(buffer.constData());
+ delete[] keyData;
+ return result;
}
QColor Settings::getIdealTextColor(const QColor& rBackgroundColor)
@@ -332,27 +363,26 @@ QString Settings::getNMMVersion() const
return result;
}
-bool Settings::getNexusLogin(QString &username, QString &password) const
+bool Settings::getNexusApiKey(QString &apiKey) const
{
- if (m_Settings.value("Settings/nexus_login", false).toBool()) {
- username = m_Settings.value("Settings/nexus_username", "").toString();
- password = deObfuscate(m_Settings.value("Settings/nexus_password", "").toString());
- return true;
- } else {
+ QString tempKey = deObfuscate("APIKEY");
+ if (tempKey.isEmpty())
return false;
- }
+ apiKey = tempKey;
+ return true;
}
bool Settings::getSteamLogin(QString &username, QString &password) const
{
- if (m_Settings.contains("Settings/steam_username")
- && m_Settings.contains("Settings/steam_password")) {
- username = m_Settings.value("Settings/steam_username").toString();
- password = deObfuscate(m_Settings.value("Settings/steam_password").toString());
- return true;
- } else {
- return false;
+ if (m_Settings.contains("Settings/steam_username")) {
+ QString tempPass = deObfuscate("steam_password");
+ if (!tempPass.isEmpty()) {
+ username = m_Settings.value("Settings/steam_username").toString();
+ password = tempPass;
+ return true;
+ }
}
+ return false;
}
bool Settings::compactDownloads() const
{
@@ -431,11 +461,15 @@ QString Settings::executablesBlacklist() const
).toString();
}
-void Settings::setNexusLogin(QString username, QString password)
+void Settings::setNexusApiKey(QString apiKey)
{
- m_Settings.setValue("Settings/nexus_login", true);
- m_Settings.setValue("Settings/nexus_username", username);
- m_Settings.setValue("Settings/nexus_password", obfuscate(password));
+ if (!obfuscate("APIKEY", apiKey)) {
+ wchar_t buffer[256];
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer, (sizeof(buffer) / sizeof(wchar_t)), NULL);
+ qCritical() << "Storing API key failed:" << buffer;
+ }
}
void Settings::setSteamLogin(QString username, QString password)
@@ -446,10 +480,12 @@ void Settings::setSteamLogin(QString username, QString password)
} else {
m_Settings.setValue("Settings/steam_username", username);
}
- if (password == "") {
- m_Settings.remove("Settings/steam_password");
- } else {
- m_Settings.setValue("Settings/steam_password", obfuscate(password));
+ if (!obfuscate("steam_password", password)) {
+ wchar_t buffer[256];
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer, (sizeof(buffer) / sizeof(wchar_t)), NULL);
+ qCritical() << "Storing or deleting password failed:" << buffer;
}
}
@@ -674,11 +710,43 @@ void Settings::resetDialogs()
QuestionBoxMemory::resetDialogs();
}
+void Settings::processApiKey(const QString &apiKey)
+{
+ if (!obfuscate("APIKEY", apiKey)) {
+ wchar_t buffer[256];
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer, (sizeof(buffer) / sizeof(wchar_t)), NULL);
+ qCritical() << "Storing or deleting API key failed:" << buffer;
+ }
+}
+
+void Settings::clearApiKey(QPushButton *nexusButton)
+{
+ obfuscate("APIKEY", "");
+ nexusButton->setEnabled(true);
+ nexusButton->setText("Connect to Nexus");
+}
+
+void Settings::checkApiKey(QPushButton *nexusButton)
+{
+ if (deObfuscate("APIKEY").isEmpty()) {
+ nexusButton->setEnabled(true);
+ nexusButton->setText("Connect to Nexus");
+ QMessageBox::warning(qApp->activeWindow(), tr("Error"),
+ tr("Failed to retrieve a Nexus API key! Please try again."
+ "A browser window should open asking you to authorize."));
+ }
+}
+
void Settings::query(PluginContainer *pluginContainer, QWidget *parent)
{
SettingsDialog dialog(pluginContainer, parent);
connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs()));
+ connect(&dialog, SIGNAL(processApiKey(const QString &)), this, SLOT(processApiKey(const QString &)));
+ connect(&dialog, SIGNAL(closeApiConnection(QPushButton *)), this, SLOT(checkApiKey(QPushButton *)));
+ connect(&dialog, SIGNAL(revokeApiKey(QPushButton *)), this, SLOT(clearApiKey(QPushButton *)));
std::vector<std::unique_ptr<SettingsTab>> tabs;
@@ -960,9 +1028,7 @@ void Settings::DiagnosticsTab::update()
Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog)
: Settings::SettingsTab(parent, dialog)
- , m_loginCheckBox(dialog.findChild<QCheckBox *>("loginCheckBox"))
- , m_usernameEdit(dialog.findChild<QLineEdit *>("usernameEdit"))
- , m_passwordEdit(dialog.findChild<QLineEdit *>("passwordEdit"))
+ , m_nexusConnect(dialog.findChild<QPushButton *>("nexusConnect"))
, m_offlineBox(dialog.findChild<QCheckBox *>("offlineBox"))
, m_proxyBox(dialog.findChild<QCheckBox *>("proxyBox"))
, m_knownServersList(dialog.findChild<QListWidget *>("knownServersList"))
@@ -970,16 +1036,16 @@ Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog)
dialog.findChild<QListWidget *>("preferredServersList"))
, m_endorsementBox(dialog.findChild<QCheckBox *>("endorsementBox"))
{
- if (parent->automaticLoginEnabled()) {
- m_loginCheckBox->setChecked(true);
- m_usernameEdit->setText(m_Settings.value("Settings/nexus_username", "").toString());
- m_passwordEdit->setText(deObfuscate(m_Settings.value("Settings/nexus_password", "").toString()));
+ if (!deObfuscate("APIKEY").isEmpty()) {
+ m_nexusConnect->setText("Nexus API Key Stored");
+ m_nexusConnect->setDisabled(true);
}
m_offlineBox->setChecked(parent->offlineMode());
m_proxyBox->setChecked(parent->useProxy());
m_endorsementBox->setChecked(parent->endorsementIntegration());
+
// display server preferences
m_Settings.beginGroup("Servers");
for (const QString &key : m_Settings.childKeys()) {
@@ -1009,6 +1075,7 @@ Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog)
void Settings::NexusTab::update()
{
+ /*
if (m_loginCheckBox->isChecked()) {
m_Settings.setValue("Settings/nexus_login", true);
m_Settings.setValue("Settings/nexus_username", m_usernameEdit->text());
@@ -1018,6 +1085,7 @@ void Settings::NexusTab::update()
m_Settings.remove("Settings/nexus_username");
m_Settings.remove("Settings/nexus_password");
}
+ */
m_Settings.setValue("Settings/offline_mode", m_offlineBox->isChecked());
m_Settings.setValue("Settings/use_proxy", m_proxyBox->isChecked());
m_Settings.setValue("Settings/endorsement_integration", m_endorsementBox->isChecked());
@@ -1047,8 +1115,9 @@ Settings::SteamTab::SteamTab(Settings *m_parent, SettingsDialog &m_dialog)
{
if (m_Settings.contains("Settings/steam_username")) {
m_steamUserEdit->setText(m_Settings.value("Settings/steam_username", "").toString());
- if (m_Settings.contains("Settings/steam_password")) {
- m_steamPassEdit->setText(deObfuscate(m_Settings.value("Settings/steam_password", "").toString()));
+ QString password = deObfuscate("steam_password");
+ if (!password.isEmpty()) {
+ m_steamPassEdit->setText(password);
}
}
}