X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/852b085dcef99353ae1bedefbaf654b5b72c9f64..519fd4f22bc83ba85a8377a7ada53fac4e2e2b39:/projects/stargazer/plugins/other/radius/conn.cpp diff --git a/projects/stargazer/plugins/other/radius/conn.cpp b/projects/stargazer/plugins/other/radius/conn.cpp index c0270e78..a209409b 100644 --- a/projects/stargazer/plugins/other/radius/conn.cpp +++ b/projects/stargazer/plugins/other/radius/conn.cpp @@ -20,6 +20,7 @@ #include "conn.h" +#include "radius.h" #include "config.h" #include "stg/json_parser.h" @@ -203,12 +204,29 @@ 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 { public: - Impl(USERS& users, PLUGIN_LOGGER& logger, const Config& config, int fd, const std::string& remote); + Impl(USERS& users, PLUGIN_LOGGER& logger, RADIUS& plugin, const Config& config, int fd, const std::string& remote); ~Impl(); int sock() const { return m_sock; } @@ -221,6 +239,7 @@ class Conn::Impl private: USERS& m_users; PLUGIN_LOGGER& m_logger; + RADIUS& m_plugin; const Config& m_config; int m_sock; std::string m_remote; @@ -228,23 +247,27 @@ class Conn::Impl time_t m_lastPing; time_t m_lastActivity; ProtoParser m_parser; + std::set m_authorized; - 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); } + const Config::Authorize& authorize() const { return stageMember(&Config::Section::authorize); } static void process(void* data); void processPing(); @@ -258,8 +281,8 @@ class Conn::Impl static bool write(void* data, const char* buf, size_t size); }; -Conn::Conn(USERS& users, PLUGIN_LOGGER& logger, const Config& config, int fd, const std::string& remote) - : m_impl(new Impl(users, logger, config, fd, remote)) +Conn::Conn(USERS& users, PLUGIN_LOGGER& logger, RADIUS& plugin, const Config& config, int fd, const std::string& remote) + : m_impl(new Impl(users, logger, plugin, config, fd, remote)) { } @@ -287,9 +310,10 @@ bool Conn::isOk() const return m_impl->isOk(); } -Conn::Impl::Impl(USERS& users, PLUGIN_LOGGER& logger, const Config& config, int fd, const std::string& remote) +Conn::Impl::Impl(USERS& users, PLUGIN_LOGGER& logger, RADIUS& plugin, const Config& config, int fd, const std::string& remote) : m_users(users), m_logger(logger), + m_plugin(plugin), m_config(config), m_sock(fd), m_remote(remote), @@ -303,6 +327,10 @@ Conn::Impl::Impl(USERS& users, PLUGIN_LOGGER& logger, const Config& config, int Conn::Impl::~Impl() { close(m_sock); + + std::set::const_iterator it = m_authorized.begin(); + for (; it != m_authorized.end(); ++it) + m_plugin.unauthorize(*it, "Lost connection to RADIUS server " + m_remote + "."); } bool Conn::Impl::read() @@ -414,6 +442,11 @@ void Conn::Impl::processData() if (!matched) continue; answer(*user); + if (authorize().check(*user, m_parser.data())) + { + m_plugin.authorize(*user); + m_authorized.insert(user->GetLogin()); + } break; } @@ -449,6 +482,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);