From fad2dd8911abd78eaf95005e68c32796650a091a Mon Sep 17 00:00:00 2001 From: Maxim Mamontov Date: Wed, 7 Oct 2015 22:26:46 +0300 Subject: [PATCH 1/1] Added no_match settings to the radius plugin. --- .../stargazer/plugins/other/radius/config.cpp | 41 ++++++++++++++++++- .../stargazer/plugins/other/radius/config.h | 17 +++++++- .../stargazer/plugins/other/radius/conn.cpp | 38 +++++++++++++---- 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/projects/stargazer/plugins/other/radius/config.cpp b/projects/stargazer/plugins/other/radius/config.cpp index 187620dd..6a29f002 100644 --- a/projects/stargazer/plugins/other/radius/config.cpp +++ b/projects/stargazer/plugins/other/radius/config.cpp @@ -167,6 +167,36 @@ T toInt(const std::vector& values) return 0; } +typedef std::map Codes; + +// One-time call to initialize the list of codes. +Codes getCodes() +{ + Codes res; + res["reject"] = Config::REJECT; + res["fail"] = Config::FAIL; + res["ok"] = Config::OK; + res["handled"] = Config::HANDLED; + res["invalid"] = Config::INVALID; + res["userlock"] = Config::USERLOCK; + res["notfound"] = Config::NOTFOUND; + res["noop"] = Config::NOOP; + res["updated"] = Config::UPDATED; + return res; +} + +Config::ReturnCode toReturnCode(const std::vector& values) +{ + static Codes codes(getCodes()); + if (values.empty()) + return Config::REJECT; + std::string code = ToLower(values[0]); + const Codes::const_iterator it = codes.find(code); + if (it == codes.end()) + return Config::REJECT; + return it->second; +} + Config::Pairs parseVector(const std::string& paramName, const std::vector& params) { for (size_t i = 0; i < params.size(); ++i) @@ -175,6 +205,14 @@ Config::Pairs parseVector(const std::string& paramName, const std::vector& params) +{ + for (size_t i = 0; i < params.size(); ++i) + if (params[i].param == paramName) + return toReturnCode(params[i].value); + return Config::REJECT; +} + bool parseBool(const std::string& paramName, const std::vector& params) { for (size_t i = 0; i < params.size(); ++i) @@ -218,7 +256,8 @@ Config::Section parseSection(const std::string& paramName, const std::vector Pairs; typedef std::pair Pair; enum Type { UNIX, TCP }; + enum ReturnCode + { + REJECT, // Reject the request immediately. + FAIL, // Module failed. + OK, // Module is OK, continue. + HANDLED, // The request is handled, no further handling. + INVALID, // The request is invalud. + USERLOCK, // Reject the request, user is locked. + NOTFOUND, // User not found. + NOOP, // Module performed no action. + UPDATED // Module sends some updates. + }; struct Section { Section() {} - Section(const Pairs& ma, const Pairs& mo, const Pairs& re) - : match(ma), modify(mo), reply(re) {} + Section(const Pairs& ma, const Pairs& mo, const Pairs& re, ReturnCode code) + : match(ma), modify(mo), reply(re), returnCode(code) {} Pairs match; Pairs modify; Pairs reply; + ReturnCode returnCode; }; Config() {} diff --git a/projects/stargazer/plugins/other/radius/conn.cpp b/projects/stargazer/plugins/other/radius/conn.cpp index c0270e78..8a416ae0 100644 --- a/projects/stargazer/plugins/other/radius/conn.cpp +++ b/projects/stargazer/plugins/other/radius/conn.cpp @@ -203,6 +203,23 @@ class PacketGen : public Gen StringGen m_type; }; +std::string toString(Config::ReturnCode code) +{ + switch (code) + { + case Config::REJECT: return "reject"; + case Config::FAIL: return "fail"; + case Config::OK: return "ok"; + case Config::HANDLED: return "handled"; + case Config::INVALID: return "invalid"; + case Config::USERLOCK: return "userlock"; + case Config::NOTFOUND: return "notfound"; + case Config::NOOP: return "noop"; + case Config::UPDATED: return "noop"; + } + return "reject"; +} + } class Conn::Impl @@ -229,22 +246,24 @@ class Conn::Impl time_t m_lastActivity; ProtoParser m_parser; - const Config::Pairs& stagePairs(Config::Pairs Config::Section::* pairs) const + template + const T& stageMember(T Config::Section::* member) const { switch (m_parser.stage()) { - case AUTHORIZE: return m_config.autz.*pairs; - case AUTHENTICATE: return m_config.auth.*pairs; - case POSTAUTH: return m_config.postauth.*pairs; - case PREACCT: return m_config.preacct.*pairs; - case ACCOUNTING: return m_config.acct.*pairs; + case AUTHORIZE: return m_config.autz.*member; + case AUTHENTICATE: return m_config.auth.*member; + case POSTAUTH: return m_config.postauth.*member; + case PREACCT: return m_config.preacct.*member; + case ACCOUNTING: return m_config.acct.*member; } throw std::runtime_error("Invalid stage: '" + m_parser.stageStr() + "'."); } - const Config::Pairs& match() const { return stagePairs(&Config::Section::match); } - const Config::Pairs& modify() const { return stagePairs(&Config::Section::modify); } - const Config::Pairs& reply() const { return stagePairs(&Config::Section::reply); } + const Config::Pairs& match() const { return stageMember(&Config::Section::match); } + const Config::Pairs& modify() const { return stageMember(&Config::Section::modify); } + const Config::Pairs& reply() const { return stageMember(&Config::Section::reply); } + Config::ReturnCode returnCode() const { return stageMember(&Config::Section::returnCode); } static void process(void* data); void processPing(); @@ -449,6 +468,7 @@ bool Conn::Impl::answerNo() printfd(__FILE__, "No match. Sending answer...\n"); PacketGen gen("data"); gen.add("result", "no"); + gen.add("return_code", toString(returnCode())); m_lastPing = time(NULL); -- 2.44.2