mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-11 16:44:48 -07:00
use hashed passwords in all commands (#4493)
* protocol changes * server changes * client changes for password reset and registration * add hashed password to change password in client * always use hashed password to log in * add warning to client when using plain text password * require real password for changing email on server this is backwards compatible as users logged in with a real password on older clients will not need this, only users logged in with a hashed password * implement password dialog when changing email * require min password length * use qstringlist to build query instead * use clear instead of = "" * add max to password dialog * use proper const ness in abstractclient * reject too long passwords instead of trimming
This commit is contained in:
parent
fcafcb340a
commit
2fc85e0c08
17 changed files with 330 additions and 96 deletions
|
|
@ -119,7 +119,7 @@ message Command_Register {
|
|||
// User name client wants to register
|
||||
required string user_name = 1;
|
||||
// Hashed password to be inserted into database
|
||||
required string password = 2;
|
||||
optional string password = 2;
|
||||
// Email address of the client for user validation
|
||||
optional string email = 3;
|
||||
// gender = 4; // obsolete
|
||||
|
|
@ -127,6 +127,7 @@ message Command_Register {
|
|||
optional string country = 5;
|
||||
optional string real_name = 6;
|
||||
optional string clientid = 7;
|
||||
optional string hashed_password = 8;
|
||||
}
|
||||
|
||||
// User wants to activate an account
|
||||
|
|
@ -149,6 +150,7 @@ message Command_AccountEdit {
|
|||
optional string email = 2;
|
||||
// gender = 3; // obsolete
|
||||
optional string country = 4;
|
||||
optional string password_check = 100; // password is required to change sensitive information
|
||||
}
|
||||
|
||||
message Command_AccountImage {
|
||||
|
|
@ -164,6 +166,8 @@ message Command_AccountPassword {
|
|||
}
|
||||
optional string old_password = 1;
|
||||
optional string new_password = 2;
|
||||
// optional string hashed_old_password = 3; // we don't want users to steal hashed passwords and change them
|
||||
optional string hashed_new_password = 4;
|
||||
}
|
||||
|
||||
message Command_ForgotPasswordRequest {
|
||||
|
|
@ -182,6 +186,7 @@ message Command_ForgotPasswordReset {
|
|||
optional string clientid = 2;
|
||||
optional string token = 3;
|
||||
optional string new_password = 4;
|
||||
optional string hashed_new_password = 5;
|
||||
}
|
||||
|
||||
message Command_ForgotPasswordChallenge {
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ public:
|
|||
virtual bool registerUser(const QString & /* userName */,
|
||||
const QString & /* realName */,
|
||||
const QString & /* password */,
|
||||
bool /* passwordNeedsHash */,
|
||||
const QString & /* emailAddress */,
|
||||
const QString & /* country */,
|
||||
bool /* active = false */)
|
||||
|
|
@ -151,10 +152,16 @@ public:
|
|||
{
|
||||
return 0;
|
||||
};
|
||||
virtual bool
|
||||
changeUserPassword(const QString & /* user */, const QString & /* password */, bool /* passwordNeedsHash */)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
virtual bool changeUserPassword(const QString & /* user */,
|
||||
const QString & /* oldPassword */,
|
||||
bool /* oldPasswordNeedsHash */,
|
||||
const QString & /* newPassword */,
|
||||
const bool & /* force */)
|
||||
bool /* newPasswordNeedsHash */)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ Server_ProtocolHandler::Server_ProtocolHandler(Server *_server,
|
|||
Server_DatabaseInterface *_databaseInterface,
|
||||
QObject *parent)
|
||||
: QObject(parent), Server_AbstractUserInterface(_server), deleted(false), databaseInterface(_databaseInterface),
|
||||
authState(NotLoggedIn), acceptsUserListChanges(false), acceptsRoomListChanges(false),
|
||||
authState(NotLoggedIn), usingRealPassword(false), acceptsUserListChanges(false), acceptsRoomListChanges(false),
|
||||
idleClientWarningSent(false), timeRunning(0), lastDataReceived(0), lastActionReceived(0)
|
||||
|
||||
{
|
||||
|
|
@ -447,8 +447,12 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
|
|||
QString password;
|
||||
bool needsHash = false;
|
||||
if (cmd.has_password()) {
|
||||
password = nameFromStdString(cmd.password());
|
||||
if (cmd.password().length() > MAX_NAME_LENGTH)
|
||||
return Response::RespWrongPassword;
|
||||
password = QString::fromStdString(cmd.password());
|
||||
needsHash = true;
|
||||
} else if (cmd.hashed_password().length() > MAX_NAME_LENGTH) {
|
||||
return Response::RespContextError;
|
||||
} else {
|
||||
password = nameFromStdString(cmd.hashed_password());
|
||||
}
|
||||
|
|
@ -515,6 +519,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
|
|||
return Response::RespAccountNotActivated;
|
||||
default:
|
||||
authState = res;
|
||||
usingRealPassword = needsHash;
|
||||
}
|
||||
|
||||
// limit the number of non-privileged users that can connect to the server based on configuration settings
|
||||
|
|
@ -791,6 +796,8 @@ Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room
|
|||
const int gameId = databaseInterface->getNextGameId();
|
||||
if (gameId == -1)
|
||||
return Response::RespInternalError;
|
||||
if (cmd.password().length() > MAX_NAME_LENGTH)
|
||||
return Response::RespContextError;
|
||||
|
||||
auto level = userInfo->user_level();
|
||||
bool isJudge = level & ServerInfo_User::IsJudge;
|
||||
|
|
@ -818,10 +825,10 @@ Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room
|
|||
|
||||
// When server doesn't permit registered users to exist, do not honor only-reg setting
|
||||
bool onlyRegisteredUsers = cmd.only_registered() && (server->permitUnregisteredUsers());
|
||||
Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, nameFromStdString(cmd.password()),
|
||||
cmd.max_players(), gameTypes, cmd.only_buddies(), onlyRegisteredUsers,
|
||||
cmd.spectators_allowed(), cmd.spectators_need_password(),
|
||||
cmd.spectators_can_talk(), cmd.spectators_see_everything(), room);
|
||||
Server_Game *game = new Server_Game(
|
||||
copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes,
|
||||
cmd.only_buddies(), onlyRegisteredUsers, cmd.spectators_allowed(), cmd.spectators_need_password(),
|
||||
cmd.spectators_can_talk(), cmd.spectators_see_everything(), room);
|
||||
|
||||
game->addPlayer(this, rc, asSpectator, asJudge, false);
|
||||
room->addGame(game);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ protected:
|
|||
bool deleted;
|
||||
Server_DatabaseInterface *databaseInterface;
|
||||
AuthenticationResult authState;
|
||||
bool usingRealPassword;
|
||||
bool acceptsUserListChanges;
|
||||
bool acceptsRoomListChanges;
|
||||
bool idleClientWarningSent;
|
||||
|
|
|
|||
|
|
@ -241,6 +241,8 @@ Response::ResponseCode Server_Room::processJoinGameCommand(const Command_JoinGam
|
|||
ResponseContainer &rc,
|
||||
Server_AbstractUserInterface *userInterface)
|
||||
{
|
||||
if (cmd.password().length() > MAX_NAME_LENGTH)
|
||||
return Response::RespWrongPassword;
|
||||
// This function is called from the Server thread and from the S_PH thread.
|
||||
// server->roomsMutex is always locked.
|
||||
|
||||
|
|
@ -265,8 +267,9 @@ Response::ResponseCode Server_Room::processJoinGameCommand(const Command_JoinGam
|
|||
|
||||
QMutexLocker gameLocker(&game->gameMutex);
|
||||
|
||||
Response::ResponseCode result = game->checkJoin(userInterface->getUserInfo(), nameFromStdString(cmd.password()),
|
||||
cmd.spectator(), cmd.override_restrictions(), cmd.join_as_judge());
|
||||
Response::ResponseCode result =
|
||||
game->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(),
|
||||
cmd.override_restrictions(), cmd.join_as_judge());
|
||||
if (result == Response::RespOk)
|
||||
game->addPlayer(userInterface, rc, cmd.spectator(), cmd.join_as_judge());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue