support early BB login command in multi-key detector crypt
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user