From 27fe4a9d813455654322ae1daf577b089064e30f Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 23 Oct 2020 18:00:12 -0700 Subject: [PATCH] ircd::m::app: Add restriction binpath; improve stdio to room; improve console cmd. --- include/ircd/m/app.h | 1 + matrix/app.cc | 94 +++++++++++++++++++++++++++++++++++++++----- matrix/homeserver.cc | 3 +- modules/console.cc | 36 ++++++++++++----- 4 files changed, 113 insertions(+), 21 deletions(-) diff --git a/include/ircd/m/app.h b/include/ircd/m/app.h index ea303c7d3..0ce046437 100644 --- a/include/ircd/m/app.h +++ b/include/ircd/m/app.h @@ -24,6 +24,7 @@ struct ircd::m::app std::string feature; json::object config; json::array arg; + std::string binpath; std::vector argv; exec child; context worker_context; diff --git a/matrix/app.cc b/matrix/app.cc index 29f92c427..fce10457d 100644 --- a/matrix/app.cc +++ b/matrix/app.cc @@ -71,7 +71,10 @@ ircd::m::app::fini() }; for(auto *const &app : apps) + { + app->child.join(15); delete app; + } } // @@ -95,10 +98,47 @@ ircd::m::app::app(const m::event::idx &event_idx) { config.at("arg") } -,argv +,binpath{[&] { - std::begin(arg), std::end(arg) -} + if(!path) + throw m::FORBIDDEN + { + "Configure the 'ircd.m.app.path' to permit." + }; + + const json::string file + { + arg.at(0) + }; + + string_view part[2]; + part[0] = path; + part[1] = file; + const auto ret + { + fs::path_string(part) + }; + + if(!bin.count(ret)) + throw m::NOT_FOUND + { + "Executable '%s' not found in bin directory at `%s'", + file, + string_view{path}, + }; + + return ret; +}()} +,argv{[&] +{ + std::vector ret + { + std::begin(arg), std::end(arg) + }; + + ret.at(0) = binpath; + return ret; +}()} ,child { argv @@ -137,6 +177,11 @@ try m::get(event_idx, "sender") }; + child.dock.wait([this] + { + return child.pid >= 0; + }); + log::info { log, "app:%lu starting %s in %s for %s @ `%s' id:%lu pid:%ld", @@ -150,22 +195,53 @@ try }; char buf alignas(4096) [16_KiB]; - for(run::barrier{};; ) + for(run::barrier{};;) { + window_buffer wb(buf); + wb([](const mutable_buffer &buf) + { + return copy(buf, "
"_sv);
+		});
+
+		bool eof {false};
+		wb([this, &eof](const mutable_buffer &buf)
+		{
+			const auto ret(read(this->child, buf));
+			eof = empty(ret);
+			return ret;
+		});
+
+		wb([](const mutable_buffer &buf)
+		{
+			return copy(buf, "
"_sv); + }); + const string_view &output { - read(child, buf) + wb.completed() }; - if(empty(output)) + if(eof) { - child.join(); + log::debug + { + log, "app:%lu :end of file", + event_idx, + }; + return; } + const string_view alt + { + "no alt text" + }; + const auto message_id { - m::notice(room_id, user_id, output) + !ircd::write_avoid? + m::msghtml(room_id, user_id, output, alt, "m.notice"): + m::event::id::buf{} }; log::debug @@ -176,7 +252,7 @@ try string_view{message_id}, string_view{room_id}, trunc(output, 64), - size(output) > 64? "..."_sv: ""_sv, + size(output) > 64? "...": "", }; } } diff --git a/matrix/homeserver.cc b/matrix/homeserver.cc index e37273c28..e4dc8e5c6 100644 --- a/matrix/homeserver.cc +++ b/matrix/homeserver.cc @@ -279,8 +279,7 @@ try if(key && !key->verify_keys.empty()) m::keys::cache::set(key->verify_keys); - if(!ircd::maintenance) - m::app::init(); + m::app::init(); if(!ircd::maintenance) signon(*this); diff --git a/modules/console.cc b/modules/console.cc index f86d7bfd7..72bbcd712 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -16229,6 +16229,7 @@ console_cmd__exec__list(opt &out, const string_view &line) << " " << exec->id << " " << exec->pid << " " << exec->code + << " " << exec->path << std::endl; return true; @@ -16284,20 +16285,30 @@ bool console_cmd__app(opt &out, const string_view &line) { for(const auto *const &app : ircd::m::app::list) + { + const auto room_id(m::room_id(app->event_idx)); + const auto event_id(m::event_id(app->event_idx)); + out << " " << std::right << std::setw(5) << app->child.id << " " << std::right << std::setw(5) << app->child.code << " " << std::right << std::setw(10) << app->child.pid - << " " << std::left << std::setw(40) << string_view{m::room_id(app->event_idx)} - << " " << std::left << std::setw(40) << string_view{m::event_id(app->event_idx)} - << " :" << app->argv.at(0) - << std::endl; + << " " << std::left << std::setw(40) << room_id + << " " << std::left << std::setw(40) << event_id + << " `" << app->argv.at(0) << "'" + ; + + if(app->child.eptr) + out << " :" << what(app->child.eptr); + + out << std::endl; + } return true; } bool -console_cmd__app__start(opt &out, const string_view &line) +console_cmd__app__load(opt &out, const string_view &line) { const params param{line, " ", { @@ -16319,18 +16330,22 @@ console_cmd__app__start(opt &out, const string_view &line) m::room(room_id).get("ircd.app", name) }; - std::unique_ptr app + auto *const app { - std::make_unique(event_idx) + std::make_unique(event_idx).release() }; - out << "Started PID " << app->child.pid << "..." << std::endl; - app.release(); + const auto pid + { + app->child.run() + }; + + out << "Started PID " << pid << "..." << std::endl; return true; } bool -console_cmd__app__stop(opt &out, const string_view &line) +console_cmd__app__unload(opt &out, const string_view &line) { const params param{line, " ", { @@ -16358,6 +16373,7 @@ console_cmd__app__stop(opt &out, const string_view &line) if(app->event_idx == event_idx) { out << "Stopped PID " << app->child.pid << "..." << std::endl; + app->child.join(15); delete app; return true; }