Revert "[Security] Add challenge-response auth with scrypt verifiers and stop storing plaintext passwords"

This reverts commit 088e932882.


Took 6 minutes
This commit is contained in:
Lukas Brübach 2026-08-25 20:52:25 +02:00
parent 088e932882
commit 47df709f37
33 changed files with 23 additions and 675 deletions

View file

@ -81,9 +81,6 @@ void ConnectionController::wireClientSignals()
connect(remoteClient, &RemoteClient::sigPromptForForgotPasswordChallenge, this,
&ConnectionController::onPromptForgotPasswordChallenge);
connect(remoteClient, &RemoteClient::sigPasswordVerifierReady, this,
&ConnectionController::onPasswordVerifierReady);
}
void ConnectionController::connectToServer()
@ -92,36 +89,16 @@ void ConnectionController::connectToServer()
connect(dlgConnect, &DlgConnect::sigStartForgotPasswordRequest, this, &ConnectionController::forgotPasswordRequest);
if (dlgConnect->exec()) {
pendingSaveName = dlgConnect->getSaveName();
pendingSavePassword = dlgConnect->getSavePassword();
remoteClient->setStoredVerifier(dlgConnect->getStoredVerifier());
remoteClient->connectToServer(dlgConnect->getHost(), static_cast<unsigned int>(dlgConnect->getPort()),
dlgConnect->getPlayerName(), dlgConnect->getPassword());
}
}
void ConnectionController::onPasswordVerifierReady(const QString &hostname,
const QString &userName,
const QString &verifier)
{
Q_UNUSED(hostname);
Q_UNUSED(userName);
if (pendingSavePassword) {
SettingsCache::instance().servers().setServerPassword(pendingSaveName, verifier);
}
}
void ConnectionController::connectToServerDirect(const QString &host,
unsigned int port,
const QString &playerName,
const QString &password,
const QString &storedVerifier,
const QString &saveName,
bool savePassword)
const QString &password)
{
pendingSaveName = saveName;
pendingSavePassword = savePassword;
remoteClient->setStoredVerifier(storedVerifier);
remoteClient->connectToServer(host, port, playerName, password);
}

View file

@ -35,13 +35,8 @@ public:
void registerToServer();
void forgotPasswordRequest();
void connectToServer();
void connectToServerDirect(const QString &host,
unsigned int port,
const QString &playerName,
const QString &password,
const QString &storedVerifier = QString(),
const QString &saveName = QString(),
bool savePassword = false);
void
connectToServerDirect(const QString &host, unsigned int port, const QString &playerName, const QString &password);
void disconnectFromServer();
void refreshWindowTitle()
@ -82,9 +77,6 @@ private slots:
void onPromptForgotPasswordReset();
void onPromptForgotPasswordChallenge();
// Persists the derived scrypt verifier after a successful challenge-response login
void onPasswordVerifierReady(const QString &hostname, const QString &userName, const QString &verifier);
private:
void wireClientSignals();
void updateWindowTitle();
@ -101,10 +93,6 @@ private:
// Kept as a member so the forgot-password signal can be wired to it
DlgConnect *dlgConnect{nullptr};
// Captured from the connect dialog when a connection is initiated
QString pendingSaveName;
bool pendingSavePassword{false};
};
#endif // COCKATRICE_REMOTE_CONNECTION_CONTROLLER_H

View file

@ -273,15 +273,9 @@ void DlgConnect::updateDisplayInfo(const QString &saveName)
playernameEdit->setText(_data.at(3));
playernameEdit->setFocus();
savePasswordCheckBox->setChecked(savePasswordStatus);
storedVerifier.clear();
if (savePasswordStatus) {
const QString stored = _data.at(4);
if (stored.startsWith("$")) {
storedVerifier = stored;
} else {
passwordEdit->setText(stored);
}
passwordEdit->setText(_data.at(4));
}
if (!_data.at(6).isEmpty()) {
@ -307,7 +301,6 @@ void DlgConnect::newHostSelected(bool state)
portEdit->setDisabled(false);
playernameEdit->clear();
passwordEdit->clear();
storedVerifier.clear();
saveEdit->clear();
saveEdit->setPlaceholderText(tr("Unique Server Name"));
saveEdit->setDisabled(false);
@ -340,13 +333,10 @@ void DlgConnect::actOk()
}
servers.addNewServer(saveEdit->text().trimmed(), hostEdit->text().trimmed(), portEdit->text().trimmed(),
playernameEdit->text().trimmed(),
passwordEdit->text().isEmpty() ? storedVerifier : passwordEdit->text(),
savePasswordCheckBox->isChecked());
playernameEdit->text().trimmed(), passwordEdit->text(), savePasswordCheckBox->isChecked());
} else {
servers.updateExistingServer(saveEdit->text().trimmed(), hostEdit->text().trimmed(), portEdit->text().trimmed(),
playernameEdit->text().trimmed(),
passwordEdit->text().isEmpty() ? storedVerifier : passwordEdit->text(),
playernameEdit->text().trimmed(), passwordEdit->text(),
savePasswordCheckBox->isChecked());
}

View file

@ -10,7 +10,6 @@
#include "../interface/widgets/server/handle_public_servers.h"
#include "../interface/widgets/server/user/user_info_connection.h"
#include <QCheckBox>
#include <QDialog>
#include <QLineEdit>
#include <libcockatrice/utility/macros.h>
@ -48,19 +47,6 @@ public:
{
return passwordEdit->text();
}
//! \brief Stored "$scrypt$..." verifier for challenge-response servers (never the plaintext password).
[[nodiscard]] QString getStoredVerifier() const
{
return storedVerifier;
}
[[nodiscard]] QString getSaveName() const
{
return saveEdit->text();
}
[[nodiscard]] bool getSavePassword() const
{
return savePasswordCheckBox->isChecked();
}
public slots:
void downloadThePublicServers();
@ -91,7 +77,6 @@ private:
QPushButton *btnConnect, *btnForgotPassword, *btnRefreshServers, *btnDeleteServer;
QMap<QString, std::pair<QString, UserConnection_Information>> savedHostList;
HandlePublicServers *hps;
QString storedVerifier;
const QString placeHolderText = tr("Downloading...");
};
#endif

View file

@ -18,10 +18,7 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
auto &servers = SettingsCache::instance().servers();
if (servers.getSavePassword()) {
const QString stored = servers.getPassword();
if (!stored.startsWith("$")) {
oldPasswordEdit->setText(stored);
}
oldPasswordEdit->setText(servers.getPassword());
}
oldPasswordLabel->setBuddy(oldPasswordEdit);

View file

@ -283,9 +283,7 @@ void UserInfoBox::changePassword(const QString &oldPassword, const QString &newP
{
Command_AccountPassword cmd;
cmd.set_old_password(oldPassword.toStdString());
if (client->getServerSupportsChallengeResponse()) {
cmd.set_hashed_new_password(PasswordHasher::generatePasswordVerifier(newPassword).toStdString());
} else if (client->getServerSupportsPasswordHash()) {
if (client->getServerSupportsPasswordHash()) {
auto passwordSalt = PasswordHasher::generateRandomSalt();
QString hashedPassword = PasswordHasher::computeHash(newPassword, passwordSalt);
cmd.set_hashed_new_password(hashedPassword.toStdString());

View file

@ -753,9 +753,8 @@ void MainWindow::changeEvent(QEvent *event)
!SettingsCache::instance().debug().getLocalGameOnStartup()) {
qCInfo(WindowMainStartupAutoconnectLog) << "Attempting auto-connect...";
DlgConnect dlg(this);
connectionController->connectToServerDirect(
dlg.getHost(), static_cast<unsigned int>(dlg.getPort()), dlg.getPlayerName(), dlg.getPassword(),
dlg.getStoredVerifier(), dlg.getSaveName(), dlg.getSavePassword());
connectionController->connectToServerDirect(dlg.getHost(), static_cast<unsigned int>(dlg.getPort()),
dlg.getPlayerName(), dlg.getPassword());
}
}
}