mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
Challenge-response authentication: the client derives a scrypt verifier (RFC 7914, EVP_PBE_scrypt, N=32768, r=8, p=1) and authenticates with HMAC-SHA256(key, nonce), so neither the password nor its hash is transmitted. The stored format becomes "$scrypt$<n>$<r>$<p>$<salt>$<verifier>" and Response_PasswordSalt now carries the cost parameters. Strict servers only accept scrypt verifiers; legacy accounts are migrated after a successful login. Fix #344 for challenge-response servers: a saved profile stores the derived verifier under the password key instead of the plaintext password. The connect dialog loads it without revealing it, autoconnect passes it through, the change-password dialog no longer prefills the old password field with it, and the client only persists the verifier when "Save password" is checked. Took 3 minutes Took 1 minute Took 10 seconds Took 7 minutes
79 lines
2.6 KiB
C++
79 lines
2.6 KiB
C++
#include "featureset.h"
|
|
|
|
#include <QMap>
|
|
|
|
FeatureSet::FeatureSet()
|
|
{
|
|
}
|
|
|
|
QMap<QString, bool> FeatureSet::getDefaultFeatureList()
|
|
{
|
|
initalizeFeatureList(featureList);
|
|
return featureList;
|
|
}
|
|
|
|
void FeatureSet::initalizeFeatureList(QMap<QString, bool> &_featureList)
|
|
{
|
|
// default features [name], [is required to connect]
|
|
_featureList.insert("client_id", false);
|
|
_featureList.insert("client_ver", false);
|
|
_featureList.insert("feature_set", false);
|
|
_featureList.insert("user_ban_history", false);
|
|
_featureList.insert("room_chat_history", false);
|
|
_featureList.insert("client_warnings", false);
|
|
_featureList.insert("mod_log_lookup", false);
|
|
_featureList.insert("idle_client", false);
|
|
_featureList.insert("forgot_password", false);
|
|
_featureList.insert("websocket", false);
|
|
_featureList.insert("hashed_password_login", false);
|
|
_featureList.insert("challenge_response_auth", false);
|
|
// These are temp to force users onto a newer client
|
|
_featureList.insert("2.7.0_min_version", false);
|
|
_featureList.insert("2.8.0_min_version", false);
|
|
}
|
|
|
|
void FeatureSet::enableRequiredFeature(QMap<QString, bool> &_featureList, const QString &featureName)
|
|
{
|
|
if (_featureList.contains(featureName)) {
|
|
_featureList.insert(featureName, true);
|
|
}
|
|
}
|
|
|
|
void FeatureSet::disableRequiredFeature(QMap<QString, bool> &_featureList, const QString &featureName)
|
|
{
|
|
if (_featureList.contains(featureName)) {
|
|
_featureList.insert(featureName, false);
|
|
}
|
|
}
|
|
|
|
QMap<QString, bool>
|
|
FeatureSet::addFeature(QMap<QString, bool> &_featureList, const QString &featureName, bool isFeatureRequired)
|
|
{
|
|
_featureList.insert(featureName, isFeatureRequired);
|
|
return _featureList;
|
|
}
|
|
|
|
QMap<QString, bool> FeatureSet::identifyMissingFeatures(const QMap<QString, bool> &suppliedFeatures,
|
|
QMap<QString, bool> requiredFeatures)
|
|
{
|
|
QMap<QString, bool> missingList;
|
|
QMap<QString, bool>::iterator i;
|
|
for (i = requiredFeatures.begin(); i != requiredFeatures.end(); ++i) {
|
|
if (!suppliedFeatures.contains(i.key())) {
|
|
missingList.insert(i.key(), i.value());
|
|
}
|
|
}
|
|
return missingList;
|
|
}
|
|
|
|
bool FeatureSet::isRequiredFeaturesMissing(const QMap<QString, bool> &suppliedFeatures,
|
|
QMap<QString, bool> requiredFeatures)
|
|
{
|
|
QMap<QString, bool>::iterator i;
|
|
for (i = requiredFeatures.begin(); i != requiredFeatures.end(); ++i) {
|
|
if (i.value() && suppliedFeatures.contains(i.key())) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|