don't require full login information on patch server

This commit is contained in:
Martin Michelsen
2023-12-28 09:57:47 -08:00
parent 29a4347f2b
commit 09ac8921fe
3 changed files with 55 additions and 20 deletions
+8
View File
@@ -127,6 +127,14 @@ shared_ptr<License> LicenseIndex::get(uint32_t serial_number) const {
}
}
shared_ptr<License> LicenseIndex::get_by_bb_username(const string& bb_username) const {
try {
return this->bb_username_to_license.at(bb_username);
} catch (const out_of_range&) {
throw missing_license();
}
}
vector<shared_ptr<License>> LicenseIndex::all() const {
vector<shared_ptr<License>> ret;
ret.reserve(this->serial_number_to_license.size());
+1
View File
@@ -100,6 +100,7 @@ public:
size_t count() const;
std::shared_ptr<License> get(uint32_t serial_number) const;
std::shared_ptr<License> get_by_bb_username(const std::string& bb_username) const;
std::vector<std::shared_ptr<License>> all() const;
void add(std::shared_ptr<License> l);
+46 -20
View File
@@ -5003,34 +5003,60 @@ static void on_04_P(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
const auto& cmd = check_size_t<C_Login_Patch_04>(data);
auto s = c->require_server_state();
try {
auto l = s->license_index->verify_bb(cmd.username.decode(), cmd.password.decode());
c->set_license(l);
string username = cmd.username.decode();
string password = cmd.password.decode();
} catch (const LicenseIndex::incorrect_password& e) {
send_message_box(c, string_printf("Login failed: %s", e.what()));
c->should_disconnect = true;
return;
// There are 3 cases here:
// - No login information at all: just proceed without checking license
// - Username only: check that license exists if allow_unregistered_users is off
// - Username and password: call verify_bb
if (!username.empty() && !password.empty()) {
try {
auto l = s->license_index->verify_bb(username, password);
c->set_license(l);
} catch (const LicenseIndex::missing_license& e) {
if (!s->allow_unregistered_users) {
} catch (const LicenseIndex::incorrect_password& e) {
send_message_box(c, string_printf("Login failed: %s", e.what()));
c->should_disconnect = true;
return;
} else {
auto l = s->license_index->create_license();
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
l->bb_username = cmd.username.decode();
l->bb_password = cmd.password.decode();
s->license_index->add(l);
if (!s->is_replay) {
l->save();
} catch (const LicenseIndex::missing_license& e) {
if (!s->allow_unregistered_users) {
send_message_box(c, string_printf("Login failed: %s", e.what()));
c->should_disconnect = true;
return;
} else {
auto l = s->license_index->create_license();
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
l->bb_username = cmd.username.decode();
l->bb_password = cmd.password.decode();
s->license_index->add(l);
if (!s->is_replay) {
l->save();
}
c->set_license(l);
string l_str = l->str();
c->log.info("Created license %s", l_str.c_str());
}
c->set_license(l);
string l_str = l->str();
c->log.info("Created license %s", l_str.c_str());
}
} else if (!username.empty() && !s->allow_unregistered_users) {
try {
auto l = s->license_index->get_by_bb_username(username);
c->set_license(l);
} catch (const LicenseIndex::missing_license& e) {
send_message_box(c, string_printf("Login failed: %s", e.what()));
c->should_disconnect = true;
return;
}
} else {
auto l = s->license_index->create_temporary_license();
l->serial_number = random_object<uint32_t>() & 0x7FFFFFFF;
l->bb_username = "__unknown__";
l->bb_password = "__unknown__";
c->set_license(l);
}
// On BB we can use colors and newlines should be \n; on PC we can't use