support early BB login command in multi-key detector crypt

This commit is contained in:
Martin Michelsen
2022-09-03 21:03:55 -07:00
parent 861d4e432a
commit 8937333a2b
6 changed files with 15 additions and 12 deletions
+3 -3
View File
@@ -756,7 +756,7 @@ PSOEncryption::Type PSOBBEncryption::type() const {
PSOBBMultiKeyDetectorEncryption::PSOBBMultiKeyDetectorEncryption(
const vector<shared_ptr<const PSOBBEncryption::KeyFile>>& possible_keys,
const string& expected_first_data,
const unordered_set<string>& expected_first_data,
const void* seed,
size_t seed_size)
: possible_keys(possible_keys),
@@ -772,7 +772,7 @@ void PSOBBMultiKeyDetectorEncryption::encrypt(void* data, size_t size, bool adva
void PSOBBMultiKeyDetectorEncryption::decrypt(void* data, size_t size, bool advance) {
if (!this->active_crypt.get()) {
if (size != this->expected_first_data.size()) {
if (size != 8) {
throw logic_error("initial decryption size does not match expected first data size");
}
@@ -782,7 +782,7 @@ void PSOBBMultiKeyDetectorEncryption::decrypt(void* data, size_t size, bool adva
*this->active_key, this->seed.data(), this->seed.size()));
string test_data(reinterpret_cast<const char*>(data), size);
this->active_crypt->decrypt(test_data.data(), test_data.size(), false);
if (test_data == this->expected_first_data) {
if (this->expected_first_data.count(test_data)) {
break;
}
this->active_key.reset();
+2 -2
View File
@@ -169,7 +169,7 @@ class PSOBBMultiKeyDetectorEncryption : public PSOEncryption {
public:
PSOBBMultiKeyDetectorEncryption(
const std::vector<std::shared_ptr<const PSOBBEncryption::KeyFile>>& possible_keys,
const std::string& expected_first_data,
const std::unordered_set<std::string>& expected_first_data,
const void* seed,
size_t seed_size);
@@ -189,7 +189,7 @@ protected:
std::vector<std::shared_ptr<const PSOBBEncryption::KeyFile>> possible_keys;
std::shared_ptr<const PSOBBEncryption::KeyFile> active_key;
std::shared_ptr<PSOBBEncryption> active_crypt;
std::string expected_first_data;
const std::unordered_set<std::string>& expected_first_data;
std::string seed;
};
+1 -2
View File
@@ -372,9 +372,8 @@ static HandlerResult on_server_bb_03(shared_ptr<ServerState> s,
// client receives the unencrypted data
session.client_channel.send(0x03, 0x00, data);
static const string expected_first_data("\xB4\x00\x93\x00\x00\x00\x00\x00", 8);
session.detector_crypt.reset(new PSOBBMultiKeyDetectorEncryption(
s->bb_private_keys, expected_first_data, cmd.client_key.data(), sizeof(cmd.client_key)));
s->bb_private_keys, bb_crypt_initial_client_commands, cmd.client_key.data(), sizeof(cmd.client_key)));
session.client_channel.crypt_in = session.detector_crypt;
session.client_channel.crypt_out.reset(new PSOBBMultiKeyImitatorEncryption(
session.detector_crypt, cmd.server_key.data(), sizeof(cmd.server_key), true));
+1 -4
View File
@@ -214,11 +214,8 @@ void ProxyServer::on_client_connect(
random_data(client_key.data(), client_key.bytes());
auto cmd = prepare_server_init_contents_bb(server_key, client_key, 0);
session->channel.send(0x03, 0x00, &cmd, sizeof(cmd));
// TODO: Is this actually needed?
// bufferevent_flush(session->bev.get(), EV_READ | EV_WRITE, BEV_FLUSH);
static const string expected_first_data("\xB4\x00\x93\x00\x00\x00\x00\x00", 8);
session->detector_crypt.reset(new PSOBBMultiKeyDetectorEncryption(
this->state->bb_private_keys, expected_first_data, cmd.client_key.data(), sizeof(cmd.client_key)));
this->state->bb_private_keys, bb_crypt_initial_client_commands, cmd.client_key.data(), sizeof(cmd.client_key)));
session->channel.crypt_in = session->detector_crypt;
session->channel.crypt_out.reset(new PSOBBMultiKeyImitatorEncryption(
session->detector_crypt, cmd.server_key.data(), sizeof(cmd.server_key), true));
+7 -1
View File
@@ -49,6 +49,12 @@ const unordered_set<uint32_t> v3_crypt_initial_client_commands({
0x0194019E, // (02) XB extended login (UDP off)
});
const unordered_set<string> bb_crypt_initial_client_commands({
string("\xB4\x00\x93\x00\x00\x00\x00\x00", 8),
string("\xAC\x00\x93\x00\x00\x00\x00\x00", 8),
string("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8),
});
void send_command(shared_ptr<Client> c, uint16_t command, uint32_t flag,
@@ -180,7 +186,7 @@ void send_server_init_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
static const string secondary_expected_first_data("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8);
shared_ptr<PSOBBMultiKeyDetectorEncryption> detector_crypt(new PSOBBMultiKeyDetectorEncryption(
s->bb_private_keys,
use_secondary_message ? secondary_expected_first_data : primary_expected_first_data,
bb_crypt_initial_client_commands,
cmd.client_key.data(),
sizeof(cmd.client_key)));
c->channel.crypt_in = detector_crypt;
+1
View File
@@ -21,6 +21,7 @@
extern const std::unordered_set<uint32_t> v2_crypt_initial_client_commands;
extern const std::unordered_set<uint32_t> v3_crypt_initial_client_commands;
extern const std::unordered_set<std::string> bb_crypt_initial_client_commands;
// TODO: Many of these functions should take a Channel& instead of a
// shared_ptr<Client>. Refactor functions appropriately.