X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/9a3ec37da47b35901d0ad25a257398895c37bfb1..8c6fa3fbaccc22127280bf77a48fab5a3ee0716e:/projects/stargazer/plugins/other/radius/radius.cpp?ds=sidebyside diff --git a/projects/stargazer/plugins/other/radius/radius.cpp b/projects/stargazer/plugins/other/radius/radius.cpp index daa8634c..45a9d0e1 100644 --- a/projects/stargazer/plugins/other/radius/radius.cpp +++ b/projects/stargazer/plugins/other/radius/radius.cpp @@ -23,6 +23,7 @@ #include "stg/store.h" #include "stg/users.h" #include "stg/plugin_creator.h" +#include "stg/common.h" #include #include @@ -53,7 +54,7 @@ extern "C" PLUGIN * GetPlugin() } RADIUS::RADIUS() - : m_config(m_settings), + : m_config(), m_running(false), m_stopped(true), m_users(NULL), @@ -90,6 +91,11 @@ int RADIUS::Start() int RADIUS::Stop() { + std::set::const_iterator it = m_logins.begin(); + for (; it != m_logins.end(); ++it) + m_users->Unauthorize(*it, this, "Stopping RADIUS plugin."); + m_logins.clear(); + if (m_stopped) return 0; @@ -105,6 +111,9 @@ int RADIUS::Stop() return 0; } + if (m_config.connectionType == Config::UNIX) + unlink(m_config.bindAddress.c_str()); + m_error = "Failed to stop thread."; m_logger(m_error); return -1; @@ -134,8 +143,6 @@ bool RADIUS::reconnect() { shutdown(m_listenSocket, SHUT_RDWR); close(m_listenSocket); - if (m_config.connectionType == Config::UNIX) - unlink(m_config.bindAddress.c_str()); } if (m_config.connectionType == Config::UNIX) m_listenSocket = createUNIX(); @@ -165,6 +172,7 @@ int RADIUS::createUNIX() const memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, m_config.bindAddress.c_str(), m_config.bindAddress.length()); + unlink(m_config.bindAddress.c_str()); if (bind(fd, reinterpret_cast(&addr), sizeof(addr)) == -1) { shutdown(fd, SHUT_RDWR); @@ -173,6 +181,9 @@ int RADIUS::createUNIX() const m_logger(m_error); return 0; } + chown(m_config.bindAddress.c_str(), m_config.sockUID, m_config.sockGID); + if (m_config.sockMode != static_cast(-1)) + chmod(m_config.bindAddress.c_str(), m_config.sockMode); return fd; } @@ -193,7 +204,7 @@ int RADIUS::createTCP() const int res = getaddrinfo(m_config.bindAddress.c_str(), m_config.portStr.c_str(), &hints, &ais); if (res != 0) { - m_error = "Error resolvin address '" + m_config.bindAddress + "': " + gai_strerror(res); + m_error = "Error resolving address '" + m_config.bindAddress + "': " + gai_strerror(res); m_logger(m_error); return 0; } @@ -230,6 +241,7 @@ int RADIUS::createTCP() const void RADIUS::runImpl() { m_running = true; + m_stopped = false; while (m_running) { fd_set fds; @@ -243,6 +255,8 @@ void RADIUS::runImpl() int res = select(maxFD() + 1, &fds, NULL, NULL, &tv); if (res < 0) { + if (errno == EINTR) + continue; m_error = std::string("'select' is failed: '") + strerror(errno) + "'."; m_logger(m_error); break; @@ -332,7 +346,8 @@ void RADIUS::acceptUNIX() m_logger(m_error); return; } - m_conns.push_back(new Conn(*m_users, m_logger, m_config, res, addr.sun_path)); + printfd(__FILE__, "New UNIX connection: '%s'\n", addr.sun_path); + m_conns.push_back(new Conn(*m_users, m_logger, *this, m_config, res, addr.sun_path)); } void RADIUS::acceptTCP() @@ -348,5 +363,28 @@ void RADIUS::acceptTCP() return; } std::string remote = inet_ntostring(addr.sin_addr.s_addr) + ":" + x2str(ntohs(addr.sin_port)); - m_conns.push_back(new Conn(*m_users, m_logger, m_config, res, remote)); + printfd(__FILE__, "New TCP connection: '%s'\n", remote.c_str()); + m_conns.push_back(new Conn(*m_users, m_logger, *this, m_config, res, remote)); +} + +void RADIUS::authorize(const USER& user) +{ + uint32_t ip = 0; + const std::string& login(user.GetLogin()); + if (!m_users->Authorize(login, ip, 0xffFFffFF, this)) + { + m_error = "Unable to authorize user '" + login + "' with ip " + inet_ntostring(ip) + "."; + m_logger(m_error); + } + else + m_logins.insert(login); +} + +void RADIUS::unauthorize(const std::string& login, const std::string& reason) +{ + const std::set::const_iterator it = m_logins.find(login); + if (it == m_logins.end()) + return; + m_logins.erase(it); + m_users->Unauthorize(login, this, reason); }