implement BB encryption in --cat-client

This commit is contained in:
Martin Michelsen
2022-09-02 17:29:19 -07:00
parent 01e4518c8e
commit 3a7c3c0fe9
3 changed files with 28 additions and 12 deletions
+14 -9
View File
@@ -36,7 +36,8 @@ using namespace std;
CatSession::CatSession(
shared_ptr<struct event_base> base,
const struct sockaddr_storage& remote,
GameVersion version)
GameVersion version,
shared_ptr<const PSOBBEncryption::KeyFile> bb_key_file)
: Shell(base),
log("[CatSession] ", proxy_server_log.min_level),
channel(
@@ -44,7 +45,8 @@ CatSession::CatSession(
CatSession::dispatch_on_channel_input,
CatSession::dispatch_on_channel_error,
this,
"CatSession") {
"CatSession"),
bb_key_file(bb_key_file) {
if (remote.ss_family != AF_INET) {
throw runtime_error("remote is not AF_INET");
}
@@ -91,13 +93,16 @@ void CatSession::on_channel_input(
}
}
} else { // BB
// TODO: This can easily be done; I'm just lazy. We need to have the user
// pass in a key name, then get that key file from this->state, then create
// the crypts.
// TODO: We really should just move encryption handling into the Channel
// abstraction instead of the above, but this is a bit harder because then
// Channels would have to know about BB key files.
throw runtime_error("CatSession does not implement BB encryption yet");
if (command == 0x03 || command == 0x9B) {
if (!this->bb_key_file) {
throw runtime_error("BB encryption requires a key file");
}
const auto& cmd = check_size_t<S_ServerInit_BB_03_9B>(data,
offsetof(S_ServerInit_DC_PC_V3_02_17_91_9B, after_message), 0xFFFF);
this->channel.crypt_in.reset(new PSOBBEncryption(*this->bb_key_file, &cmd.server_key[0], sizeof(cmd.server_key)));
this->channel.crypt_out.reset(new PSOBBEncryption(*this->bb_key_file, &cmd.client_key[0], sizeof(cmd.client_key)));
this->log.info("Enabled BB encryption");
}
}
string full_cmd = prepend_command_header(
+3 -1
View File
@@ -23,12 +23,14 @@ public:
CatSession(
std::shared_ptr<struct event_base> base,
const struct sockaddr_storage& remote,
GameVersion version);
GameVersion version,
std::shared_ptr<const PSOBBEncryption::KeyFile> bb_key_file);
virtual ~CatSession() = default;
protected:
PrefixedLogger log;
Channel channel;
std::shared_ptr<const PSOBBEncryption::KeyFile> bb_key_file;
virtual void print_prompt();
virtual void execute_command(const std::string& command);
+11 -2
View File
@@ -245,7 +245,8 @@ Specifically:\n\
commands to stdout, and forward any commands typed into stdin to the\n\
remote server. It is assumed that the input and output are terminals, so\n\
all commands are hex-encoded. The --patch, --dc, --pc, --gc, and --bb\n\
options can be used to select the command format end encryption.\n\
options can be used to select the command format and encryption. If --bb\n\
is used, the --key option is also required (as in --decrypt-data above).\n\
--replay-log=FILENAME\n\
This option makes newserv replay terminal log as if it were a client\n\
session. This is used for regression testing, to make sure client\n\
@@ -438,8 +439,16 @@ int main(int argc, char** argv) {
}
case Behavior::CAT_CLIENT: {
shared_ptr<PSOBBEncryption::KeyFile> key;
if (cli_version == GameVersion::BB) {
if (key_file_name.empty()) {
throw runtime_error("a key filename is required for BB client emulation");
}
key.reset(new PSOBBEncryption::KeyFile(
load_object_file<PSOBBEncryption::KeyFile>("system/blueburst/keys/" + key_file_name + ".nsk")));
}
shared_ptr<struct event_base> base(event_base_new(), event_base_free);
CatSession session(base, cat_client_remote, cli_version);
CatSession session(base, cat_client_remote, cli_version, key);
event_base_dispatch(base.get());
break;
}