From 885d125fc48ff922d4e963ba1b3ad677622b34cc Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Mon, 25 Sep 2023 09:07:48 -0700 Subject: [PATCH] eliminate the concept of temporary licenses --- TODO.md | 4 ++++ src/License.cc | 18 ++++++---------- src/License.hh | 7 +------ src/ProxyServer.cc | 3 ++- src/ReceiveCommands.cc | 42 +++++++++++++++++++++++--------------- src/ServerState.cc | 3 --- system/config.example.json | 9 ++++---- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/TODO.md b/TODO.md index b3d42a24..e1d44226 100644 --- a/TODO.md +++ b/TODO.md @@ -16,6 +16,10 @@ - Fix symbol chat header (including face_spec) across PC/GC boundary - Check size of name field in GuildCardPC + TODO; // Make save files permission and use it for $saverec too + TODO; // Make sure JP v1.02, 1.03, 1.04 can connect and load DOL files + + ## Episode 3 - Make disconnecting during a tournament match cause you to forfeit the match diff --git a/src/License.cc b/src/License.cc index 2e45fb9f..4e4084b0 100644 --- a/src/License.cc +++ b/src/License.cc @@ -42,12 +42,10 @@ JSON License::json() const { } void License::save() const { - if (!(this->flags & License::Flag::TEMPORARY)) { - auto json = this->json(); - string json_data = json.serialize(JSON::SerializeOption::FORMAT | JSON::SerializeOption::HEX_INTEGERS); - string filename = string_printf("system/licenses/%010" PRIu32 ".json", this->serial_number); - save_file(filename, json_data); - } + auto json = this->json(); + string json_data = json.serialize(JSON::SerializeOption::FORMAT | JSON::SerializeOption::HEX_INTEGERS); + string filename = string_printf("system/licenses/%010" PRIu32 ".json", this->serial_number); + save_file(filename, json_data); } void License::delete_file() const { @@ -93,7 +91,7 @@ struct BinaryLicense { uint64_t ban_end_time; // end time of ban (zero = not banned) } __attribute__((packed)); -LicenseIndex::LicenseIndex() : autosave(true) { +LicenseIndex::LicenseIndex() { if (!isdir("system/licenses")) { mkdir("system/licenses", 0755); } @@ -113,7 +111,7 @@ LicenseIndex::LicenseIndex() : autosave(true) { license.gc_password = bin_license.gc_password; license.bb_username = bin_license.username; license.bb_password = bin_license.bb_password; - license.flags = bin_license.privileges & (~License::Flag::TEMPORARY); + license.flags = bin_license.privileges; license.ban_end_time = bin_license.ban_end_time; license.ep3_current_meseta = 0; license.ep3_total_meseta_earned = 0; @@ -132,10 +130,6 @@ LicenseIndex::LicenseIndex() : autosave(true) { } } -void LicenseIndex::set_autosave(bool autosave) { - this->autosave = autosave; -} - size_t LicenseIndex::count() const { return this->serial_number_to_license.size(); } diff --git a/src/License.hh b/src/License.hh index 0a1e7e18..c5584564 100644 --- a/src/License.hh +++ b/src/License.hh @@ -25,9 +25,8 @@ struct License { MODERATOR = 0x00000007, ADMINISTRATOR = 0x000000FF, ROOT = 0x010000FF, - TEMPORARY = 0x80000000, - UNUSED_BITS = 0x7EFFFF00, + UNUSED_BITS = 0xFEFFFF00, // clang-format on }; @@ -73,8 +72,6 @@ public: LicenseIndex(); ~LicenseIndex() = default; - void set_autosave(bool autosave); - size_t count() const; std::shared_ptr get(uint32_t serial_number) const; std::vector> all() const; @@ -88,8 +85,6 @@ public: std::shared_ptr verify_bb(const std::string& username, const std::string& password) const; protected: - bool autosave; - std::unordered_map> bb_username_to_license; std::unordered_map> serial_number_to_license; }; diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index e6103ffb..6fdedfce 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -339,9 +339,10 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 l->serial_number = fnv1a32(cmd.username) & 0x7FFFFFFF; l->bb_username = cmd.username; l->bb_password = cmd.password; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); license = l; + string l_str = l->str(); + ses->log.info("Created license %s", l_str.c_str()); } login_command_bb = std::move(data); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 25166be0..cc2d5ecc 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -355,9 +355,10 @@ static void on_DB_V3(shared_ptr c, uint16_t, uint32_t, const string& dat l->serial_number = serial_number; l->access_key = cmd.access_key; l->gc_password = cmd.password; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); send_command(c, 0x9A, 0x02); } } @@ -389,9 +390,10 @@ static void on_88_DCNTE(shared_ptr c, uint16_t, uint32_t, const string& shared_ptr l(new License()); l->serial_number = serial_number; l->access_key = cmd.access_key; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); send_command(c, 0x88, 0x00); } } @@ -423,9 +425,10 @@ static void on_8B_DCNTE(shared_ptr c, uint16_t, uint32_t, const string& shared_ptr l(new License()); l->serial_number = serial_number; l->access_key = cmd.access_key; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); } } @@ -468,9 +471,10 @@ static void on_90_DC(shared_ptr c, uint16_t, uint32_t, const string& dat shared_ptr l(new License()); l->serial_number = serial_number; l->access_key = cmd.access_key; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); send_command(c, 0x90, 0x01); } } @@ -510,9 +514,10 @@ static void on_93_DC(shared_ptr c, uint16_t, uint32_t, const string& dat shared_ptr l(new License()); l->serial_number = serial_number; l->access_key = cmd.access_key; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); } } @@ -577,9 +582,9 @@ static void on_9A(shared_ptr c, uint16_t, uint32_t, const string& data) } catch (const LicenseIndex::missing_license& e) { // On V3, the client should have sent a different command containing the - // password already, which should have created and added a temporary - // license. So, if no license exists at this point, disconnect the client - // even if unregistered clients are allowed. + // password already, which should have created and added a license. So, if + // no license exists at this point, disconnect the client even if + // unregistered clients are allowed. shared_ptr l; if ((c->version() == GameVersion::GC) || (c->version() == GameVersion::XB)) { send_command(c, 0x9A, 0x04); @@ -589,9 +594,10 @@ static void on_9A(shared_ptr c, uint16_t, uint32_t, const string& data) shared_ptr l(new License()); l->serial_number = serial_number; l->access_key = cmd.access_key; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); send_command(c, 0x9A, 0x02); } else { throw runtime_error("unsupported game version"); @@ -643,9 +649,10 @@ static void on_9C(shared_ptr c, uint16_t, uint32_t, const string& data) if (c->version() == GameVersion::GC) { l->gc_password = cmd.password; } - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); send_command(c, 0x9C, 0x01); } } @@ -753,9 +760,9 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, const str } catch (const LicenseIndex::missing_license& e) { // On V3, the client should have sent a different command containing the - // password already, which should have created and added a temporary - // license. So, if no license exists at this point, disconnect the client - // even if unregistered clients are allowed. + // password already, which should have created and added a license. So, if + // no license exists at this point, disconnect the client even if + // unregistered clients are allowed. shared_ptr l; if ((c->version() == GameVersion::GC) || (c->version() == GameVersion::XB)) { send_command(c, 0x04, 0x04); @@ -765,9 +772,10 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, const str shared_ptr l(new License()); l->serial_number = serial_number; l->access_key = base_cmd->access_key; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); } else { throw runtime_error("unsupported game version"); } @@ -813,9 +821,10 @@ static void on_93_BB(shared_ptr c, uint16_t, uint32_t, const string& dat l->serial_number = fnv1a32(cmd.username) & 0x7FFFFFFF; l->bb_username = cmd.username; l->bb_password = cmd.password; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); } } @@ -3861,9 +3870,10 @@ static void on_04_P(shared_ptr c, uint16_t, uint32_t, const string& data l->serial_number = fnv1a32(cmd.username) & 0x7FFFFFFF; l->bb_username = cmd.username; l->bb_password = cmd.password; - l->flags |= License::Flag::TEMPORARY; s->license_index->add(l); c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); } } diff --git a/src/ServerState.cc b/src/ServerState.cc index de977b31..fee80857 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -785,9 +785,6 @@ void ServerState::load_bb_private_keys() { void ServerState::load_licenses() { config_log.info("Loading license list"); this->license_index.reset(new LicenseIndex()); - if (this->is_replay) { - this->license_index->set_autosave(false); - } } void ServerState::load_patch_indexes() { diff --git a/system/config.example.json b/system/config.example.json index 180f7cb8..f9fe96ca 100644 --- a/system/config.example.json +++ b/system/config.example.json @@ -218,12 +218,11 @@ // If this option is disabled, the server only allows users who have licenses // on the server to connect. If this is enabled, all users will be allowed to - // connect even if they don't have licenses. Each time a user connects with an + // connect even if they don't have licenses. When a user connects with an // unregistered license (serial number and access key combination, or username - // and password combination on BB), a temporary license is created for them, - // which lasts until the server is shut down. These temporary licenses are not - // saved in the licenses directory. For BB, player and account data is still - // saved on the server, even for users with temporary licenses. + // and password combination on BB), a new license is created for them. + // Licenses are addressed by serial numbers; on BB, the new license's serial + // number is a hash of the username. "AllowUnregisteredUsers": true, // User to run the server as. If present, newserv will attempt to switch to