Strip usernames used in the MP UI and command line of trailing whitespace

This also affects line breaks. There's no point in displaying confusing
errors to the player in the off-chance that they manage to introduce
leading or trailing whitespace in the username field. The server doesn't
accept whitespace but that doesn't mean we can't try to guess what the
user really meant to do, and extra whitespace around a name is a pretty
trivial mistake to make.

The password field, on the other hand, ought to accept it since it's
possible to even have line break characters in it (as tested with
Firefox on the live phpBB registration form for forums.w.o).
This commit is contained in:
Iris Morelle 2019-02-12 00:37:02 -03:00
parent 7976d69973
commit 9bc6161c3c
2 changed files with 21 additions and 9 deletions

View file

@ -170,6 +170,7 @@
* GUI.pyw can now terminate a running maintenance script
* Fix SDL_DestroyRenderer assertion failure under XMonad. (part of issue #3716)
* Fix map item names not being translated in the scenario editor.
* Usernames specified in the MP UI and command line are now stripped of leading and trailing whitespace, including newlines.
### Multiplayer server
* Fix stale temporary bans continuing to have an effect on players until cleared by
phpBB on the next ban/unban operation.

View file

@ -19,6 +19,8 @@ See the COPYING file for more details.
#include "log.hpp"
#include "serialization/string_utils.hpp"
#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <memory>
@ -127,7 +129,10 @@ namespace preferences
void set_login(const std::string& login)
{
preferences::set("login", '@' + login + '@');
auto login_clean = login;
boost::trim(login_clean);
preferences::set("login", '@' + login_clean + '@');
}
bool remember_password()
@ -148,40 +153,46 @@ namespace preferences
std::string password(const std::string& server, const std::string& login)
{
auto login_clean = login;
boost::trim(login_clean);
if(!remember_password()) {
if(!credentials.empty() && credentials[0].username == login && credentials[0].server == server) {
auto temp = decrypt(credentials[0].key, build_key(server, login));
if(!credentials.empty() && credentials[0].username == login_clean && credentials[0].server == server) {
auto temp = decrypt(credentials[0].key, build_key(server, login_clean));
return std::string(temp.begin(), temp.end());
} else {
return "";
}
}
auto cred = std::find_if(credentials.begin(), credentials.end(), [&](const login_info& cred) {
return cred.server == server && cred.username == login;
return cred.server == server && cred.username == login_clean;
});
if(cred == credentials.end()) {
return "";
}
auto temp = decrypt(cred->key, build_key(server, login));
auto temp = decrypt(cred->key, build_key(server, login_clean));
return std::string(temp.begin(), temp.end());
}
void set_password(const std::string& server, const std::string& login, const std::string& key)
{
auto login_clean = login;
boost::trim(login_clean);
secure_buffer temp(key.begin(), key.end());
if(!remember_password()) {
clear_credentials();
credentials.emplace_back(login, server, encrypt(temp, build_key(server, login)));
credentials.emplace_back(login_clean, server, encrypt(temp, build_key(server, login_clean)));
return;
}
auto cred = std::find_if(credentials.begin(), credentials.end(), [&](const login_info& cred) {
return cred.server == server && cred.username == login;
return cred.server == server && cred.username == login_clean;
});
if(cred == credentials.end()) {
// This is equivalent to emplace_back, but also returns the iterator to the new element
cred = credentials.emplace(credentials.end(), login, server);
cred = credentials.emplace(credentials.end(), login_clean, server);
}
cred->key = encrypt(temp, build_key(server, login));
cred->key = encrypt(temp, build_key(server, login_clean));
}
void load_credentials()