(Multiplayer login error with certain username or password formats)

The new username/password serialization format is as follows: @ <field
value> @ Old usernames/passwordswill be converted as necessary when
the user changes their credentials in-game. The user will to hit
#16571 once if they are using an affected username or password saved
by a previous version.

Unfortunately, the underlying cause is still around and this only
fixes this particular case by forcing new usernames and passwords to
be stored in a format that can only be interpreted as a string by the
config class. Dealing with it isn't feasible at this point, so I'll
file a separate bug for the general case and mark it as Postponed
later.
This commit is contained in:
Ignacio R. Morelle 2011-12-18 19:33:53 +00:00
parent bb1510c055
commit fc9e7ef291
5 changed files with 89 additions and 4 deletions

View file

@ -69,6 +69,8 @@ Version 1.9.12+svn:
* Optimized screen update (zooming, ToD change, etc)
* Optimized framerate by removing a lot of empty terrain images
* Optimized perfomance cost of complex local ToD areas
* Fixed bug #16571: Multiplayer login error with certain username or
password formats
Version 1.9.12:
* Language and i18n:

View file

@ -31,6 +31,8 @@
#include "unit_map.hpp"
#include "wml_exception.hpp"
static lg::log_domain log_config("config");
#define ERR_CFG LOG_STREAM(err , log_config)
namespace {
@ -51,6 +53,29 @@ bool friends_initialized = false;
bool ignores_initialized = false;
bool authenticated = false;
const char WRAP_CHAR = '@';
const std::string EMPTY_WRAPPED_STRING = "@@";
std::string wrap_credentials_field_value(const std::string& value)
{
return WRAP_CHAR + value + WRAP_CHAR;
}
std::string parse_wrapped_credentials_field(const std::string& raw)
{
if(raw.empty() || raw == EMPTY_WRAPPED_STRING) {
// empty (wrapped or not)
return raw;
} else if(raw.length() < 2 || raw[0] != WRAP_CHAR || raw[raw.length() - 1] != WRAP_CHAR ) {
// malformed/not wrapped (shouldn't happen)
ERR_CFG << "malformed user credentials (did you manually edit the preferences file?)\n";
return raw;
}
return raw.substr(1, raw.length() - 2);
}
} // anon namespace
namespace preferences {
@ -333,6 +358,30 @@ void set_campaign_server(const std::string& host)
preferences::set("campaign_server", host);
}
bool wrap_password()
{
const bool have_old_password_format =
(!preferences::have_setting("password_is_wrapped")) && preferences::have_setting("password");
return have_old_password_format ? false : preferences::get("password_is_wrapped", true);
}
void set_wrap_password(bool wrap)
{
preferences::set("password_is_wrapped", wrap);
}
bool wrap_login()
{
const bool have_old_login_format =
(!preferences::have_setting("login_is_wrapped")) && preferences::have_setting("login");
return have_old_login_format ? false : preferences::get("login_is_wrapped", true);
}
void set_wrap_login(bool wrap)
{
preferences::set("login_is_wrapped", wrap);
}
std::string login()
{
const std::string res = preferences::get("login");
@ -347,12 +396,17 @@ std::string login()
}
}
return res;
if(!wrap_login()) {
return res;
} else {
return parse_wrapped_credentials_field(res);
}
}
void set_login(const std::string& username)
{
preferences::set("login", username);
set_wrap_login(true);
preferences::set("login", wrap_credentials_field_value(username));
}
namespace prv {
@ -362,7 +416,12 @@ namespace prv {
std::string password()
{
if(remember_password()) {
return preferences::get("password");
const std::string saved_pass = preferences::get("password");
if(!wrap_password()) {
return saved_pass;
} else {
return parse_wrapped_credentials_field(saved_pass);
}
} else {
return prv::password;
}
@ -372,7 +431,8 @@ void set_password(const std::string& password)
{
prv::password = password;
if(remember_password()) {
preferences::set("password", password);
set_wrap_password(true);
preferences::set("password", wrap_credentials_field_value(password));
}
}

View file

@ -66,6 +66,15 @@ namespace preferences {
std::string campaign_server();
void set_campaign_server(const std::string& host);
/**
* Returns whether the MP username is stored wrapped in markers.
*
* New usernames are stored in a specific format to force string interpretation
* (due to bug #16571).
*/
bool wrap_login();
void set_wrap_login(bool wrap);
std::string login();
void set_login(const std::string& username);
@ -81,6 +90,15 @@ namespace preferences {
extern std::string password;
}
/**
* Returns whether the password is stored wrapped in markers.
*
* New passwords are stored in a specific format to force string interpretation
* (due to bug #16571).
*/
bool wrap_password();
void set_wrap_password(bool wrap);
std::string password();
void set_password(const std::string& password);

View file

@ -138,6 +138,10 @@ void erase(const std::string& key) {
prefs.remove_attribute(key);
}
bool have_setting(const std::string& key) {
return prefs.has_attribute(key);
}
std::string get(const std::string& key) {
return prefs[key];
}

View file

@ -46,6 +46,7 @@ namespace preferences {
std::string get(const std::string& key);
bool get(const std::string &key, bool def);
void erase(const std::string& key);
bool have_setting(const std::string& key);
void disable_preferences_save();