[proxy,modules] dyn-channel-dump one packet per file

This commit is contained in:
Armin Novak 2023-06-28 14:22:33 +02:00 committed by akallabeth
parent 0876fb555d
commit ed93474a07

View File

@ -31,6 +31,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <atomic>
#include <filesystem> #include <filesystem>
#include <freerdp/server/proxy/proxy_modules_api.h> #include <freerdp/server/proxy/proxy_modules_api.h>
@ -61,28 +62,19 @@ class ChannelData
bool add(const std::string& name, bool back) bool add(const std::string& name, bool back)
{ {
auto id = idstr(name, back); std::lock_guard guard(_mux);
if (_map.find(id) != _map.end()) if (_map.find(name) == _map.end())
{ _map.insert({ name, 0 });
WLog_ERR(TAG, "Duplicate stream dump entry '%s'", id.c_str());
return false;
}
auto path = filepath(name, back);
auto s = std::ofstream(path);
if (!s.is_open() || !s.good())
{
WLog_ERR(TAG, "Failed to create stream dump entry '%s'", id.c_str());
return false;
}
_map.insert({ id, std::move(s) });
return true; return true;
} }
std::ofstream& stream(const std::string& name, bool back) std::ofstream stream(const std::string& name, bool back)
{ {
return _map[idstr(name, back)]; std::lock_guard guard(_mux);
auto& atom = _map[name];
auto count = atom++;
auto path = filepath(name, back, count);
return std::ofstream(path);
} }
bool dump_enabled(const std::string& name) const bool dump_enabled(const std::string& name) const
@ -97,10 +89,13 @@ class ChannelData
_channels_to_dump.end(); _channels_to_dump.end();
} }
std::filesystem::path filepath(const std::string& channel, bool back) const std::filesystem::path filepath(const std::string& channel, bool back, uint64_t count) const
{ {
auto name = idstr(channel, back); auto name = idstr(channel, back);
auto path = _base / name; char cstr[32] = {};
_snprintf(cstr, sizeof(cstr), "%016" PRIx64 "-", count);
auto path = _base / cstr;
path += name;
path += ".dump"; path += ".dump";
return path; return path;
} }
@ -120,7 +115,9 @@ class ChannelData
private: private:
std::filesystem::path _base; std::filesystem::path _base;
std::vector<std::string> _channels_to_dump; std::vector<std::string> _channels_to_dump;
std::map<std::string, std::ofstream> _map;
std::mutex _mux;
std::map<std::string, uint64_t> _map;
}; };
static ChannelData* dump_get_plugin_data(proxyPlugin* plugin, proxyData* pdata) static ChannelData* dump_get_plugin_data(proxyPlugin* plugin, proxyData* pdata)
@ -172,19 +169,16 @@ static BOOL dump_dyn_channel_intercept_list(proxyPlugin* plugin, proxyData* pdat
auto cdata = dump_get_plugin_data(plugin, pdata); auto cdata = dump_get_plugin_data(plugin, pdata);
if (!cdata) if (!cdata)
return FALSE; return FALSE;
auto front = cdata->filepath(data->name, false);
auto back = cdata->filepath(data->name, true);
if (!cdata->add(data->name, false)) if (!cdata->add(data->name, false))
{ {
WLog_ERR(TAG, "failed to create file '%s'", front.c_str()); WLog_ERR(TAG, "failed to create files for '%s'", data->name);
} }
if (!cdata->add(data->name, true)) if (!cdata->add(data->name, true))
{ {
WLog_ERR(TAG, "failed to create file '%s'", back.c_str()); WLog_ERR(TAG, "failed to create files for '%s'", data->name);
} }
WLog_INFO(TAG, "Dumping channel '%s' to '%s' and '%s'", data->name, front.c_str(), WLog_INFO(TAG, "Dumping channel '%s'", data->name);
back.c_str());
} }
return TRUE; return TRUE;
} }
@ -219,7 +213,7 @@ static BOOL dump_dyn_channel_intercept(proxyPlugin* plugin, proxyData* pdata, vo
if (!cdata) if (!cdata)
return FALSE; return FALSE;
auto& stream = cdata->stream(data->name, data->isBackData); auto stream = cdata->stream(data->name, data->isBackData);
auto buffer = reinterpret_cast<const char*>(Stream_ConstBuffer(data->data)); auto buffer = reinterpret_cast<const char*>(Stream_ConstBuffer(data->data));
if (!stream.is_open() || !stream.good()) if (!stream.is_open() || !stream.good())
{ {
@ -232,6 +226,7 @@ static BOOL dump_dyn_channel_intercept(proxyPlugin* plugin, proxyData* pdata, vo
WLog_ERR(TAG, "Could not write to stream"); WLog_ERR(TAG, "Could not write to stream");
return FALSE; return FALSE;
} }
stream.flush();
} }
return TRUE; return TRUE;