mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 01:23:24 -08:00
[Client] Stop sending the saved login when its checkbox is unticked (#7713)
Unticking 'Save password' only disabled auto-connect: the dialog still handed the stored verifier to the connection, so a password typed at the same time was ignored, and a server that still has the legacy hash refused the login before it could upgrade the account. Clear the verifier in effect on untick, restore it on re-tick unless a password has been typed, and drop the stale 'Password saved' hint. The downgrade abort can now point at unticking the box and logging in with the password, without the extra reconnect round-trip. Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
96f8c3a423
commit
99422c2bf0
3 changed files with 25 additions and 6 deletions
|
|
@ -296,11 +296,13 @@ void DlgConnect::updateDisplayInfo(const QString &saveName)
|
||||||
playernameEdit->setFocus();
|
playernameEdit->setFocus();
|
||||||
savePasswordCheckBox->setChecked(savePasswordStatus);
|
savePasswordCheckBox->setChecked(savePasswordStatus);
|
||||||
storedVerifier.clear();
|
storedVerifier.clear();
|
||||||
|
savedVerifier.clear();
|
||||||
|
|
||||||
if (savePasswordStatus) {
|
if (savePasswordStatus) {
|
||||||
const QString stored = _data.at(4);
|
const QString stored = _data.at(4);
|
||||||
if (stored.startsWith("$")) {
|
if (stored.startsWith("$")) {
|
||||||
storedVerifier = stored;
|
storedVerifier = stored;
|
||||||
|
savedVerifier = stored;
|
||||||
passwordEdit->clear();
|
passwordEdit->clear();
|
||||||
passwordEdit->setPlaceholderText(tr("Password saved"));
|
passwordEdit->setPlaceholderText(tr("Password saved"));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -337,6 +339,7 @@ void DlgConnect::newHostSelected(bool state)
|
||||||
passwordEdit->clear();
|
passwordEdit->clear();
|
||||||
passwordEdit->setPlaceholderText(QString());
|
passwordEdit->setPlaceholderText(QString());
|
||||||
storedVerifier.clear();
|
storedVerifier.clear();
|
||||||
|
savedVerifier.clear();
|
||||||
saveEdit->clear();
|
saveEdit->clear();
|
||||||
saveEdit->setPlaceholderText(tr("Unique Server Name"));
|
saveEdit->setPlaceholderText(tr("Unique Server Name"));
|
||||||
saveEdit->setDisabled(false);
|
saveEdit->setDisabled(false);
|
||||||
|
|
@ -352,9 +355,19 @@ void DlgConnect::passwordSaved(QT_STATE_CHANGED_T state)
|
||||||
Q_UNUSED(state);
|
Q_UNUSED(state);
|
||||||
if (savePasswordCheckBox->isChecked()) {
|
if (savePasswordCheckBox->isChecked()) {
|
||||||
autoConnectCheckBox->setEnabled(true);
|
autoConnectCheckBox->setEnabled(true);
|
||||||
|
// Re-ticking keeps a password the user has started typing; otherwise restore the saved
|
||||||
|
// login this dialog was opened with, so unticking and changing your mind is harmless.
|
||||||
|
if (passwordEdit->text().isEmpty()) {
|
||||||
|
storedVerifier = savedVerifier;
|
||||||
|
passwordEdit->setPlaceholderText(savedVerifier.isEmpty() ? QString() : tr("Password saved"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
autoConnectCheckBox->setChecked(false);
|
autoConnectCheckBox->setChecked(false);
|
||||||
autoConnectCheckBox->setEnabled(false);
|
autoConnectCheckBox->setEnabled(false);
|
||||||
|
// Unticking means the password typed below is sent for this connection: stop sending the
|
||||||
|
// saved verifier instead, and stop claiming a password is saved.
|
||||||
|
storedVerifier.clear();
|
||||||
|
passwordEdit->setPlaceholderText(QString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,10 +375,11 @@ void DlgConnect::actOk()
|
||||||
{
|
{
|
||||||
ServersSettings &servers = SettingsCache::instance().servers();
|
ServersSettings &servers = SettingsCache::instance().servers();
|
||||||
|
|
||||||
// Never write a newly typed plaintext password to disk when a verifier is already stored:
|
// Never write a newly typed plaintext password to disk when a verifier is available: the
|
||||||
// the typed value is used for this connection and a fresh verifier is persisted after a
|
// typed value is used for this connection and a fresh verifier is persisted after a
|
||||||
// successful login. Without a stored verifier we keep the previous (plaintext legacy) behavior.
|
// successful login. Without any verifier we keep the previous (plaintext legacy) behavior.
|
||||||
const QString passwordToSave = storedVerifier.isEmpty() ? passwordEdit->text() : storedVerifier;
|
const QString verifierToSave = storedVerifier.isEmpty() ? savedVerifier : storedVerifier;
|
||||||
|
const QString passwordToSave = verifierToSave.isEmpty() ? passwordEdit->text() : verifierToSave;
|
||||||
|
|
||||||
if (newHostButton->isChecked()) {
|
if (newHostButton->isChecked()) {
|
||||||
if (saveEdit->text().isEmpty()) {
|
if (saveEdit->text().isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,10 @@ private:
|
||||||
QPushButton *btnConnect, *btnForgotPassword, *btnRefreshServers, *btnDeleteServer;
|
QPushButton *btnConnect, *btnForgotPassword, *btnRefreshServers, *btnDeleteServer;
|
||||||
QMap<QString, std::pair<QString, UserConnection_Information>> savedHostList;
|
QMap<QString, std::pair<QString, UserConnection_Information>> savedHostList;
|
||||||
HandlePublicServers *hps;
|
HandlePublicServers *hps;
|
||||||
|
//! \brief Saved "$scrypt$..." verifier as loaded for the selected profile, kept so that
|
||||||
|
//! re-ticking "Save password" after unticking restores it.
|
||||||
|
QString savedVerifier;
|
||||||
|
//! \brief Verifier in effect for this connection: empty while "Save password" is unticked.
|
||||||
QString storedVerifier;
|
QString storedVerifier;
|
||||||
const QString placeHolderText = tr("Downloading...");
|
const QString placeHolderText = tr("Downloading...");
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -50,11 +50,12 @@ namespace
|
||||||
// The server warns that this account still uses the legacy password hash while this client
|
// The server warns that this account still uses the legacy password hash while this client
|
||||||
// holds a scrypt verifier. Sending the verifier would downgrade the proof, so the client
|
// holds a scrypt verifier. Sending the verifier would downgrade the proof, so the client
|
||||||
// stops; the login only succeeds after the saved verifier is gone and the user types the
|
// stops; the login only succeeds after the saved verifier is gone and the user types the
|
||||||
// password, which also upgrades the account.
|
// password, which also upgrades the account. Unticking "Save password" drops the verifier
|
||||||
|
// for the next connection.
|
||||||
constexpr const char *const LOGIN_ABORT_AUTH_DOWNGRADE = QT_TRANSLATE_NOOP(
|
constexpr const char *const LOGIN_ABORT_AUTH_DOWNGRADE = QT_TRANSLATE_NOOP(
|
||||||
"RemoteClient",
|
"RemoteClient",
|
||||||
"The server still uses an old password format for this account, so the saved login on this computer cannot be "
|
"The server still uses an old password format for this account, so the saved login on this computer cannot be "
|
||||||
"used. Untick 'Save password' in the Connect window and connect; when it opens again, type your password.");
|
"used. Untick 'Save password' in the Connect window and log in with your password.");
|
||||||
// The account is still on the legacy hash and only the plaintext password can produce it.
|
// The account is still on the legacy hash and only the plaintext password can produce it.
|
||||||
constexpr const char *const LOGIN_ABORT_PASSWORD_REQUIRED =
|
constexpr const char *const LOGIN_ABORT_PASSWORD_REQUIRED =
|
||||||
QT_TRANSLATE_NOOP("RemoteClient",
|
QT_TRANSLATE_NOOP("RemoteClient",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue