]> git.stg.codes - stg.git/commitdiff
Merge remote-tracking branch 'github/master' master
authorMaksym Mamontov <madf@madf.info>
Mon, 27 Jan 2025 15:03:37 +0000 (17:03 +0200)
committerMaksym Mamontov <madf@madf.info>
Mon, 27 Jan 2025 15:03:37 +0000 (17:03 +0200)
projects/stargazer/plugins/CMakeLists.txt
projects/stargazer/plugins/other/radius/radius.cpp
projects/stargazer/plugins/other/radius/radius.h
projects/stargazer/plugins/other/radius/server.cpp [new file with mode: 0644]
projects/stargazer/plugins/other/radius/server.h [new file with mode: 0644]

index a53349eaac8cb5a3807f56f569f350fd296a1de6..b6e4d3264a292826b86376d454432ae369bd7cc5 100644 (file)
@@ -14,7 +14,8 @@ endif ( BUILD_MOD_AO )
 if ( BUILD_MOD_RADIUS )
     find_package ( Boost REQUIRED )
 
-    add_library ( mod_radius MODULE other/radius/radius.cpp )
+    add_library ( mod_radius MODULE other/radius/radius.cpp
+                                    other/radius/server.cpp)
     target_link_libraries ( mod_radius PRIVATE scriptexecuter logger common )
     set_target_properties ( mod_radius PROPERTIES PREFIX "" )
 
@@ -34,7 +35,8 @@ if ( BUILD_MOD_RADIUS )
 
     add_dependencies ( mod_radius async-radius )
 
-    target_link_libraries ( mod_radius PRIVATE radproto Boost::boost )
+    find_package ( OpenSSL 1.0.0 REQUIRED )
+    target_link_libraries ( mod_radius PRIVATE radproto Boost::boost OpenSSL::Crypto)
 
     if ( CLANG_TIDY_EXE )
         set_target_properties ( mod_radius PROPERTIES CXX_CLANG_TIDY "${DO_CLANG_TIDY}" )
index 3ec0f705b0fd61d5a6288073a13ee2066f3b1c34..78c80b4df9e32a2d832038f2da5acf6711d7a494 100644 (file)
@@ -1,4 +1,13 @@
 #include "radius.h"
+#include "server.h"
+#include "radproto/error.h"
+
+#include "stg/common.h"
+
+#include <boost/asio.hpp>
+#include <string>
+#include <iostream>
+#include <cstdint> //uint8_t, uint32_t
 
 using STG::RADIUS;
 
@@ -14,6 +23,57 @@ std::string RADIUS::GetVersion() const
 }
 
 RADIUS::RADIUS()
+    : m_logger(PluginLogger::get("radius")),
+      m_running(false)
+{
+}
+
+int RADIUS::Start()
+{
+    m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
+    return 0;
+}
+
+int RADIUS::Stop()
+{
+    if (!m_thread.joinable())
+        return 0;
+
+    m_thread.request_stop();
+
+    m_thread.join();
+    return 0;
+}
+
+void RADIUS::SetRunning(bool val)
+{
+    const std::lock_guard lock(m_mutex);
+    m_running = val;
+}
+
+bool RADIUS::IsRunning()
 {
+    const std::lock_guard lock(m_mutex);
+    return m_running;
 }
 
+int RADIUS::Run(std::stop_token token)
+{
+    SetRunning(true);
+
+    try
+    {
+        boost::asio::io_service ioService;
+        Server server(ioService, "secret", 1812, "/usr/share/freeradius/dictionary");
+        ioService.run();
+    }
+    catch (const std::exception& e)
+    {
+        m_errorStr = "Exception in RADIUS::Run(): " + std::string(e.what());
+        m_logger("Exception in RADIUS:: Run(): %s", e.what());
+        printfd(__FILE__, "Exception in RADIUS:: Run(). Message: '%s'\n", e.what());
+    }
+
+    SetRunning(false);
+    return 0;
+}
index 4cc84e264004cd28a53c5a0777b3a9dc4fc05190..4e06e463e581ec8ae91432a541f5a884b94a02ba 100644 (file)
@@ -1,7 +1,11 @@
 #pragma once
 
 #include "stg/auth.h"
+#include "stg/logger.h"
+
 #include <string>
+#include <mutex>
+#include <jthread.hpp>
 
 namespace STG
 {
@@ -10,12 +14,13 @@ namespace STG
         public:
             RADIUS();
 
-            int Start() override { return 0; }
-            int Stop() override { return 0; }
+            int Start() override;
+            int Stop() override;
             int Reload(const ModuleSettings & /*ms*/) override { return 0; }
-            bool IsRunning() override { return isRunning; }
+            bool IsRunning() override;
+            void SetRunning(bool val);
             int ParseSettings() override { return 0; }
-            const std::string & GetStrError() const override { return 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; }
@@ -23,8 +28,12 @@ namespace STG
             int SendMessage(const Message & msg, uint32_t ip) const override { return 0; }
 
         private:
-            mutable std::string errorStr;
-            bool isRunning;
+            std::mutex m_mutex;
+            mutable std::string m_errorStr;
+            std::jthread m_thread;
+            bool m_running;
+            PluginLogger m_logger;
 
+            int Run(std::stop_token token);
     };
 }
diff --git a/projects/stargazer/plugins/other/radius/server.cpp b/projects/stargazer/plugins/other/radius/server.cpp
new file mode 100644 (file)
index 0000000..4d16b6c
--- /dev/null
@@ -0,0 +1,68 @@
+#include "server.h"
+#include "radproto/packet_codes.h"
+#include <functional>
+#include <iostream>
+
+using STG::Server;
+using boost::system::error_code;
+
+Server::Server(boost::asio::io_service& io_service, const std::string& secret, uint16_t port, const std::string& filePath)
+    : m_radius(io_service, secret, port),
+      m_dictionaries(filePath)
+{
+    startReceive();
+}
+
+void Server::startReceive()
+{
+    m_radius.asyncReceive([this](const auto& error, const auto& packet, const boost::asio::ip::udp::endpoint& source){ handleReceive(error, packet, source); });
+}
+
+RadProto::Packet Server::makeResponse(const RadProto::Packet& request)
+{
+    std::vector<RadProto::Attribute*> attributes;
+    attributes.push_back(new RadProto::String(m_dictionaries.attributeCode("User-Name"), "test"));
+    attributes.push_back(new RadProto::Integer(m_dictionaries.attributeCode("NAS-Port"), 20));
+    std::array<uint8_t, 4> address {127, 104, 22, 17};
+    attributes.push_back(new RadProto::IpAddress(m_dictionaries.attributeCode("NAS-IP-Address"), address));
+    std::vector<uint8_t> bytes {'1', '2', '3', 'a', 'b', 'c'};
+    attributes.push_back(new RadProto::Bytes(m_dictionaries.attributeCode("Callback-Number"), bytes));
+    std::vector<uint8_t> chapPassword {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
+    attributes.push_back(new RadProto::ChapPassword(m_dictionaries.attributeCode("CHAP-Password"), 1, chapPassword));
+
+    std::vector<RadProto::VendorSpecific> vendorSpecific;
+    std::vector<uint8_t> vendorValue {0, 0, 0, 3};
+    vendorSpecific.push_back(RadProto::VendorSpecific(m_dictionaries.vendorCode("Dlink"), m_dictionaries.vendorAttributeCode("Dlink", "Dlink-User-Level"), vendorValue));
+
+    if (request.type() == RadProto::ACCESS_REQUEST)
+        return RadProto::Packet(RadProto::ACCESS_ACCEPT, request.id(), request.auth(), attributes, vendorSpecific);
+
+    return RadProto::Packet(RadProto::ACCESS_REJECT, request.id(), request.auth(), attributes, vendorSpecific);
+}
+
+void Server::handleSend(const error_code& ec)
+{
+    if (ec)
+        std::cout << "Error asyncSend: " << ec.message() << "\n";
+
+    startReceive();
+}
+
+void Server::handleReceive(const error_code& error, const std::optional<RadProto::Packet>& packet, const boost::asio::ip::udp::endpoint& source)
+{
+    if (error)
+    {
+        std::cout << "Error asyncReceive: " << error.message() << "\n";
+        return;
+    }
+
+    if (packet == std::nullopt)
+    {
+        std::cout << "Error asyncReceive: the request packet is missing\n";
+        return;
+    }
+    else
+    {
+        m_radius.asyncSend(makeResponse(*packet), source, [this](const auto& ec){ handleSend(ec); });
+    }
+}
diff --git a/projects/stargazer/plugins/other/radius/server.h b/projects/stargazer/plugins/other/radius/server.h
new file mode 100644 (file)
index 0000000..b88889b
--- /dev/null
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "radproto/socket.h"
+#include "radproto/packet.h"
+#include "radproto/dictionaries.h"
+#include <boost/asio.hpp>
+#include <optional>
+#include <cstdint> //uint8_t, uint32_t
+
+namespace STG
+{
+    class Server
+    {
+        public:
+            Server(boost::asio::io_service& io_service, const std::string& secret, uint16_t port, const std::string& filePath);
+
+        private:
+            RadProto::Packet makeResponse(const RadProto::Packet& request);
+            void handleReceive(const boost::system::error_code& error, const std::optional<RadProto::Packet>& packet, const boost::asio::ip::udp::endpoint& source);
+            void handleSend(const boost::system::error_code& ec);
+            void startReceive();
+
+            RadProto::Socket m_radius;
+            RadProto::Dictionaries m_dictionaries;
+    };
+}