#include "radius.h"
#include "radproto/error.h"
#include "stg/common.h"
+#include <boost/tokenizer.hpp>
+#include <vector>
+#include <utility>
#include <iterator>
+#include <algorithm>
#include <iostream>
using STG::RADIUS;
using STG::RAD_SETTINGS;
+using AttrValue = RAD_SETTINGS::AttrValue;
+using ASection = RAD_SETTINGS::ASection;
extern "C" STG::Plugin* GetPlugin()
{
return &plugin;
}
+namespace
+{
+ std::string ShowRules(const std::vector<std::pair<std::string, AttrValue>>& attributes)
+ {
+ std::string result;
+ for (const auto& at : attributes)
+ {
+ if (!result.empty())
+ result += ", ";
+
+ if (at.second.type == AttrValue::Type::PARAM_NAME)
+ result.append(at.first + " = " + at.second.value);
+ else
+ result.append(at.first + " = '" + at.second.value + "'");
+ }
+ return result;
+ }
+}
+
+std::vector<std::pair<std::string, AttrValue>> RAD_SETTINGS::ParseRules(const std::string& value, const std::string& paramName)
+{
+ using tokenizer = boost::tokenizer<boost::char_separator<char>>;
+ const boost::char_separator<char> sep(",");
+
+ const tokenizer tokens(value, sep);
+
+ std::vector<std::pair<std::string, AttrValue>> res;
+ for (const auto& token : tokens)
+ {
+ const boost::char_separator<char> sp(" =");
+ const tokenizer tok(token, sp);
+
+ std::vector<std::string> keyValue;
+ for (const auto& t : tok)
+ keyValue.push_back(t);
+
+ if (keyValue.size() != 2)
+ {
+ m_logger("The '%s' attribute specification has an incorrect format: '%s'.", paramName.c_str(), token.c_str());
+ printfd(__FILE__, "The '%s' attribute specification has an incorrect format: '%s'.", paramName.c_str(), token.c_str());
+ return {};
+ }
+
+ auto type = AttrValue::Type::PARAM_NAME;
+ std::string valueName = keyValue[1];
+ if (valueName.front() == '\'' && valueName.back() == '\'')
+ {
+ type = AttrValue::Type::VALUE;
+ valueName.erase(0, 1);
+ valueName.erase(valueName.length() - 1, 1);
+ }
+ else if ((valueName.front() == '\'' && valueName.back() != '\'') || (valueName.front() != '\'' && valueName.back() == '\''))
+ {
+ m_logger("Error ParseRules: '%s' attribute parameter value is invalid.\n", paramName.c_str());
+ printfd(__FILE__, "Error ParseRules: '%s' attribute parameter value is invalid.\n", paramName.c_str());
+ return {};
+ }
+ res.emplace_back(keyValue[0], AttrValue{valueName, type});
+ }
+ return res;
+}
+
+ASection RAD_SETTINGS::parseASection(const std::vector<ParamValue>& conf)
+{
+ ASection res;
+ const auto mit = std::find(conf.begin(), conf.end(), ParamValue("match", {}));
+ if (mit != conf.end())
+ res.match = ParseRules(mit->value[0], mit->param);
+
+ const auto sit = std::find(conf.begin(), conf.end(), ParamValue("send", {}));
+ if (sit != conf.end())
+ res.send = ParseRules(sit->value[0], sit->param);
+
+ return res;
+}
+
RAD_SETTINGS::RAD_SETTINGS()
: m_port(1812),
- m_dictionaries("/usr/share/freeradius/dictionary")
+ m_dictionaries("/usr/share/freeradius/dictionary"),
+ m_logger(PluginLogger::get("radius"))
{}
int RAD_SETTINGS::ParseSettings(const ModuleSettings & s)
m_secret = "";
}
else
- {
m_secret = pvi->value[0];
- }
pv.param = "Dictionaries";
pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
if (pvi != s.moduleParams.end() && !pvi->value.empty())
m_dictionaries = pvi->value[0];
+
+ const auto authIt = std::find(s.moduleParams.begin(), s.moduleParams.end(), ParamValue("auth", {}));
+ if (authIt != s.moduleParams.end())
+ m_auth = parseASection(authIt->sections);
+
+ const auto autzIt = std::find(s.moduleParams.begin(), s.moduleParams.end(), ParamValue("autz", {}));
+ if (autzIt != s.moduleParams.end())
+ m_autz = parseASection(autzIt->sections);
+
+ printfd(__FILE__, " auth.match = \"%s\"\n", ShowRules(m_auth.match).c_str());
+ printfd(__FILE__, " auth.send = \"%s\"\n", ShowRules(m_auth.send).c_str());
+ printfd(__FILE__, " autz.match = \"%s\"\n", ShowRules(m_autz.match).c_str());
+ printfd(__FILE__, " autz.send = \"%s\"\n", ShowRules(m_autz.send).c_str());
+
return 0;
}
try
{
if (!m_server)
- m_server = std::make_unique<Server>(m_ioService, m_radSettings.GetSecret(), m_radSettings.GetPort(), m_radSettings.GetDictionaries(), std::move(token), m_logger, m_users);
- m_ioService.run();
+ m_server = std::make_unique<Server>(m_ioContext, m_radSettings.GetSecret(), m_radSettings.GetPort(), m_radSettings.GetDictionaries(), std::move(token), m_logger, m_users);
+ m_ioContext.run();
}
catch (const std::exception& e)
{
public:
RAD_SETTINGS();
virtual ~RAD_SETTINGS() {}
- const std::string & GetStrError() const { return m_errorStr; }
- int ParseSettings(const ModuleSettings & s);
+
+ struct AttrValue
+ {
+ enum class Type
+ {
+ PARAM_NAME,
+ VALUE
+ };
+ std::string value;
+ Type type;
+ };
+
+ struct ASection
+ {
+ using Pairs = std::vector<std::pair<std::string, AttrValue>>;
+ Pairs match;
+ Pairs send;
+ };
+
+ const std::string& GetStrError() const { return m_errorStr; }
+ int ParseSettings(const ModuleSettings& s);
uint16_t GetPort() const { return m_port; }
- const std::string & GetDictionaries() const { return m_dictionaries; }
- const std::string & GetSecret() const { return m_secret; }
+ const std::string& GetDictionaries() const { return m_dictionaries; }
+ const std::string& GetSecret() const { return m_secret; }
+ const ASection& getAuth() const { return m_auth; }
+ const ASection& getAutz() const { return m_autz; }
private:
+ std::vector<std::pair<std::string, AttrValue>> ParseRules(const std::string& value, const std::string& paramName);
+ ASection parseASection(const std::vector<ParamValue>& conf);
+
std::string m_errorStr;
uint16_t m_port;
std::string m_dictionaries;
std::string m_secret;
+
+ ASection m_auth;
+ ASection m_autz;
+
+ PluginLogger m_logger;
};
class RADIUS : public Auth
RADIUS(const RADIUS&) = delete;
RADIUS& operator=(const RADIUS&) = delete;
- void SetUsers(Users* u) { m_users = u; }
- void SetSettings(const ModuleSettings & s) override { m_settings = s; }
+ void SetUsers(Users* u) override { m_users = u; }
+ void SetSettings(const ModuleSettings& s) override { m_settings = s; }
int ParseSettings() override;
int Start() override;
int Stop() override;
- int Reload(const ModuleSettings & /*ms*/) override { return 0; }
+ int Reload(const ModuleSettings& /*ms*/) override { return 0; }
bool IsRunning() override;
void SetRunning(bool val);
- const std::string & GetStrError() const override { return m_errorStr; }
+ const std::string& GetStrError() const override { return m_errorStr; }
std::string GetVersion() const override;
uint16_t GetStartPosition() const override { return 0; }
uint16_t GetStopPosition() const override { return 0; }
- int SendMessage(const Message & msg, uint32_t ip) const override { return 0; }
+ int SendMessage(const Message& /*msg*/, uint32_t /*ip*/) const override { return 0; }
private:
std::mutex m_mutex;
- boost::asio::io_service m_ioService;
+ boost::asio::io_context m_ioContext;
int Run(std::stop_token token);
mutable std::string m_errorStr;