]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/radius/radius.cpp
c93c4ddf70c90f272c10d00315145836d14a375f
[stg.git] / projects / stargazer / plugins / other / radius / radius.cpp
1 #include "radius.h"
2 #include "radproto/error.h"
3 #include "stg/common.h"
4
5 #include <iterator>
6 #include <iostream>
7
8 using STG::RADIUS;
9 using STG::RAD_SETTINGS;
10
11 extern "C" STG::Plugin* GetPlugin()
12 {
13     static RADIUS plugin;
14     return &plugin;
15 }
16
17 RAD_SETTINGS::RAD_SETTINGS()
18     : m_port(1812),
19       m_dictionaries("/usr/share/freeradius/dictionary")
20 {}
21
22 int RAD_SETTINGS::ParseSettings(const ModuleSettings & s)
23 {
24     ParamValue pv;
25     int p;
26
27     pv.param = "Port";
28     auto pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
29     if (pvi != s.moduleParams.end() && !pvi->value.empty())
30     {
31         if (ParseIntInRange(pvi->value[0], 2, 65535, &p) != 0)
32         {
33             m_errorStr = "Cannot parse parameter \'Port\': " + m_errorStr;
34             printfd(__FILE__, "Cannot parse parameter 'Port'\n");
35             return -1;
36         }
37         m_port = static_cast<uint16_t>(p);
38     }
39
40     pv.param = "Secret";
41     pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
42     if (pvi == s.moduleParams.end() || pvi->value.empty())
43     {
44         m_errorStr = "Parameter \'Secret\' not found.";
45         printfd(__FILE__, "Parameter 'Secret' not found\n");
46         m_secret = "";
47     }
48     else
49     {
50         m_secret = pvi->value[0];
51     }
52
53     pv.param = "Dictionaries";
54     pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
55     if (pvi != s.moduleParams.end() && !pvi->value.empty())
56         m_dictionaries = pvi->value[0];
57     return 0;
58 }
59
60 RADIUS::RADIUS()
61     : m_running(false),
62       m_users(NULL),
63       m_logger(PluginLogger::get("radius"))
64 {
65 }
66
67 int RADIUS::ParseSettings()
68 {
69     auto ret = m_radSettings.ParseSettings(m_settings);
70     if (ret != 0)
71         m_errorStr = m_radSettings.GetStrError();
72
73     return ret;
74 }
75
76 std::string RADIUS::GetVersion() const
77 {
78     return "Radius v.1.0";
79 }
80
81 int RADIUS::Start()
82 {
83     m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
84     return 0;
85 }
86
87 int RADIUS::Stop()
88 {
89     if (!m_thread.joinable())
90         return 0;
91
92     m_thread.request_stop();
93
94     if (m_server)
95         m_server->stop();
96
97     m_thread.join();
98     return 0;
99 }
100
101 bool RADIUS::IsRunning()
102 {
103     const std::lock_guard lock(m_mutex);
104     return m_running;
105 }
106
107 void RADIUS::SetRunning(bool val)
108 {
109     const std::lock_guard lock(m_mutex);
110     m_running = val;
111 }
112
113 int RADIUS::Run(std::stop_token token)
114 {
115     SetRunning(true);
116
117     try
118     {
119         if (!m_server)
120            m_server = std::make_unique<Server>(m_ioService, m_radSettings.GetSecret(), m_radSettings.GetPort(), m_radSettings.GetDictionaries(), std::move(token), m_logger, m_users);
121         m_ioService.run();
122     }
123     catch (const std::exception& e)
124     {
125         m_errorStr = "Exception in RADIUS::Run(): " + std::string(e.what());
126         m_logger("Exception in RADIUS:: Run(): %s", e.what());
127         printfd(__FILE__, "Exception in RADIUS:: Run(). Message: '%s'\n", e.what());
128     }
129
130     SetRunning(false);
131     return 0;
132 }