From 8efceb299213d8c3f22eb60cf9a848c567d9bfc5 Mon Sep 17 00:00:00 2001 From: Michael Ducy Date: Fri, 8 Feb 2019 15:45:20 -0500 Subject: [PATCH] Add HTTP output handler --- falco.yaml | 4 +++ userspace/falco/configuration.cpp | 16 +++++++++++ userspace/falco/falco_outputs.cpp | 47 +++++++++++++++++++++++++++++++ userspace/falco/falco_outputs.h | 8 ++++++ userspace/falco/lua/output.lua | 10 +++++++ 5 files changed, 85 insertions(+) diff --git a/falco.yaml b/falco.yaml index c01a8f0de6e..84d289319de 100644 --- a/falco.yaml +++ b/falco.yaml @@ -138,3 +138,7 @@ program_output: enabled: false keep_alive: false program: mail -s "Falco Notification" someone@example.com + +http_output: + enabled: false + url: http://some.url \ No newline at end of file diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index a778caaf2c4..bb959e27936 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -131,6 +131,22 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio m_outputs.push_back(program_output); } + falco_outputs::output_config http_output; + http_output.name = "http"; + if (m_config->get_scalar("http_output", "enabled", false)) + { + string url; + url = m_config->get_scalar("http_output", "url", ""); + + if (url == string("")) + { + throw sinsp_exception("Error reading config file (" + m_config_file + "): http output enabled but no url in configuration block"); + } + http_output.options["url"] = url; + + m_outputs.push_back(http_output); + } + if (m_outputs.size() == 0) { throw invalid_argument("Error reading config file (" + m_config_file + "): No outputs configured. Please configure at least one output file output enabled but no filename in configuration block"); diff --git a/userspace/falco/falco_outputs.cpp b/userspace/falco/falco_outputs.cpp index 97341e0b1b8..265ca004129 100644 --- a/userspace/falco/falco_outputs.cpp +++ b/userspace/falco/falco_outputs.cpp @@ -27,6 +27,12 @@ limitations under the License. using namespace std; +const static struct luaL_reg ll_falco_outputs [] = +{ + {"handle_http", &falco_outputs::handle_http}, + {NULL,NULL} +}; + falco_outputs::falco_outputs(falco_engine *engine) : m_falco_engine(engine), m_initialized(false), @@ -80,6 +86,8 @@ void falco_outputs::init(bool json_output, falco_logger::init(m_ls); + luaL_openlib(m_ls, "c_outputs", ll_falco_outputs, 0); + m_notifications_tb.init(rate, max_burst); m_buffered = buffered; @@ -169,3 +177,42 @@ void falco_outputs::reopen_outputs() throw falco_exception(string(lerr)); } } + +int falco_outputs::handle_http(lua_State *ls) +{ + CURL *curl = NULL; + CURLcode res = CURLE_FAILED_INIT; + struct curl_slist *slist1; + slist1 = NULL; + + if (!lua_isstring(ls, -1) || + !lua_isstring(ls, -2)) + { + lua_pushstring(ls, "Invalid arguments passed to handle_http()"); + lua_error(ls); + } + + string url = (char *) lua_tostring(ls, 1); + string msg = (char *) lua_tostring(ls, 2); + + curl = curl_easy_init(); + if(curl) + { + slist1 = curl_slist_append(slist1, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L); + + res = curl_easy_perform(curl); + + if(res != CURLE_OK) { + falco_logger::log(LOG_ERR,"libcurl error: " + string(curl_easy_strerror(res))); + } + curl_easy_cleanup(curl); + curl = NULL; + curl_slist_free_all(slist1); + slist1 = NULL; + } + return 1; +} \ No newline at end of file diff --git a/userspace/falco/falco_outputs.h b/userspace/falco/falco_outputs.h index 0d9cbcebdbd..888c0183461 100644 --- a/userspace/falco/falco_outputs.h +++ b/userspace/falco/falco_outputs.h @@ -21,6 +21,12 @@ limitations under the License. #include +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} + #include "gen_filter.h" #include "json_evt.h" #include "falco_common.h" @@ -62,6 +68,8 @@ class falco_outputs : public falco_common void reopen_outputs(); + static int handle_http(lua_State *ls); + private: falco_engine *m_falco_engine; diff --git a/userspace/falco/lua/output.lua b/userspace/falco/lua/output.lua index 0314cd65bec..a5f65e6fc89 100644 --- a/userspace/falco/lua/output.lua +++ b/userspace/falco/lua/output.lua @@ -142,6 +142,16 @@ function mod.program_reopen(options) end end +function mod.http(priority, priority_num, msg, options) + c_outputs.handle_http(options.url, msg) +end + +function mod.http_cleanup() +end + +function mod.http_reopen() +end + function output_event(event, rule, source, priority, priority_num, format) -- If format starts with a *, remove it, as we're adding our own -- prefix here.