diff options
-rw-r--r-- | include/modules/httpd.h | 12 | ||||
-rw-r--r-- | src/modules/m_httpd.cpp | 9 | ||||
-rw-r--r-- | src/modules/m_httpd_acl.cpp | 26 |
3 files changed, 36 insertions, 11 deletions
diff --git a/include/modules/httpd.h b/include/modules/httpd.h index 86234d53f..5e3e780dc 100644 --- a/include/modules/httpd.h +++ b/include/modules/httpd.h @@ -24,6 +24,7 @@ #pragma once #include "base.h" +#include "event.h" #include <string> #include <sstream> @@ -237,3 +238,14 @@ class HTTPdAPI : public dynamic_reference<HTTPdAPIBase> { } }; + +class HTTPACLEventListener : public Events::ModuleEventListener +{ + public: + HTTPACLEventListener(Module* mod) + : ModuleEventListener(mod, "event/http-acl") + { + } + + virtual ModResult OnHTTPACLCheck(HTTPRequest& req) = 0; +}; diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index bbd9f1275..0dd028924 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -31,6 +31,7 @@ class ModuleHttpServer; static ModuleHttpServer* HttpModule; static bool claimed; static insp::intrusive_list<HttpServerSocket> sockets; +static Events::ModuleEventProvider* aclevprov; /** HTTP socket states */ @@ -323,9 +324,10 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru InternalState = HTTP_SERVE_SEND_DATA; claimed = false; + ModResult MOD_RESULT; HTTPRequest acl((Module*)HttpModule, "httpd_acl", request_type, uri, &headers, this, ip, postdata); - acl.Send(); - if (!claimed) + FIRST_MOD_RESULT_CUSTOM(*aclevprov, HTTPACLEventListener, OnHTTPACLCheck, MOD_RESULT, (acl)); + if (MOD_RESULT != MOD_RES_DENY) { HTTPRequest url((Module*)HttpModule, "httpd_url", request_type, uri, &headers, this, ip, postdata); url.Send(); @@ -372,11 +374,14 @@ class ModuleHttpServer : public Module { HTTPdAPIImpl APIImpl; unsigned int timeoutsec; + Events::ModuleEventProvider acleventprov; public: ModuleHttpServer() : APIImpl(this) + , acleventprov(this, "event/http-acl") { + aclevprov = &acleventprov; } void init() CXX11_OVERRIDE diff --git a/src/modules/m_httpd_acl.cpp b/src/modules/m_httpd_acl.cpp index 58bbbde2a..866fa0e86 100644 --- a/src/modules/m_httpd_acl.cpp +++ b/src/modules/m_httpd_acl.cpp @@ -36,7 +36,7 @@ class HTTPACL blacklist(set_blacklist) { } }; -class ModuleHTTPAccessList : public Module +class ModuleHTTPAccessList : public Module, public HTTPACLEventListener { std::string stylesheet; std::vector<HTTPACL> acl_list; @@ -44,7 +44,8 @@ class ModuleHTTPAccessList : public Module public: ModuleHTTPAccessList() - : API(this) + : HTTPACLEventListener(this) + , API(this) { } @@ -104,12 +105,10 @@ class ModuleHTTPAccessList : public Module API->SendResponse(response); } - void OnEvent(Event& event) CXX11_OVERRIDE + bool IsAccessAllowed(HTTPRequest* http) { - if (event.id == "httpd_acl") { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling httpd acl event"); - HTTPRequest* http = (HTTPRequest*)&event; for (std::vector<HTTPACL>::const_iterator this_acl = acl_list.begin(); this_acl != acl_list.end(); ++this_acl) { @@ -128,7 +127,7 @@ class ModuleHTTPAccessList : public Module ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Denying access to blacklisted resource %s (matched by pattern %s) from ip %s (matched by entry %s)", http->GetURI().c_str(), this_acl->path.c_str(), http->GetIP().c_str(), entry.c_str()); BlockAccess(http, 403); - return; + return false; } } } @@ -150,7 +149,7 @@ class ModuleHTTPAccessList : public Module ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Denying access to whitelisted resource %s (matched by pattern %s) from ip %s (Not in whitelist)", http->GetURI().c_str(), this_acl->path.c_str(), http->GetIP().c_str()); BlockAccess(http, 403); - return; + return false; } } if (!this_acl->password.empty() && !this_acl->username.empty()) @@ -186,7 +185,7 @@ class ModuleHTTPAccessList : public Module if (user == this_acl->username && pass == this_acl->password) { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "HTTP authorization: password and username match"); - return; + return true; } else /* Invalid password */ @@ -205,13 +204,22 @@ class ModuleHTTPAccessList : public Module /* No password given at all, access denied */ BlockAccess(http, 401, "WWW-Authenticate", "Basic realm=\"Restricted Object\""); } + return false; } /* A path may only match one ACL (the first it finds in the config file) */ - return; + break; } } } + return true; + } + + ModResult OnHTTPACLCheck(HTTPRequest& req) CXX11_OVERRIDE + { + if (IsAccessAllowed(&req)) + return MOD_RES_PASSTHRU; + return MOD_RES_DENY; } Version GetVersion() CXX11_OVERRIDE |