]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#4274] Checkpoint: just began
authorFrancis Dupont <fdupont@isc.org>
Tue, 20 Jan 2026 10:59:33 +0000 (11:59 +0100)
committerFrancis Dupont <fdupont@isc.org>
Mon, 9 Feb 2026 21:05:44 +0000 (22:05 +0100)
src/hooks/dhcp/radius/client_server.cc
src/hooks/dhcp/radius/client_server.h
src/hooks/dhcp/radius/meson.build
src/hooks/dhcp/radius/radius.cc
src/hooks/dhcp/radius/radius.h
src/hooks/dhcp/radius/radius_access.h
src/hooks/dhcp/radius/radius_parsers.cc
src/hooks/dhcp/radius/radius_tls.cc [new file with mode: 0644]
src/hooks/dhcp/radius/radius_tls.h [new file with mode: 0644]
src/hooks/dhcp/radius/tests/server_unittests.cc

index 94f077752d0661ed7705a245da204ceb659c8151..436417b920a40f357f76a1b863f64fff2f318264 100644 (file)
@@ -52,6 +52,22 @@ struct AddrInfo {
 namespace isc {
 namespace radius {
 
+string
+protocolToText(const int proto) {
+    ostringstream result;
+    switch (proto) {
+    case PW_PROTO_UDP:
+        return ("UDP");
+    case PW_PROTO_TCP:
+        return ("TCP");
+    case PW_PROTO_TLS:
+        return ("TLS");
+    default:
+        result << "unknown transport protocol " << proto;
+        return (result.str());
+    }
+}
+
 IOAddress
 Server::getAddress(const string& name) {
     AddrInfo res(name);
index cf90c00b4b94e94b382111861239ac4a6b228c07..82cc1c81e523e268c18923934523ab9f958d6911 100644 (file)
@@ -31,10 +31,23 @@ namespace isc {
 namespace radius {
 
 /// @brief Default RADIUS access/authentication port.
-static constexpr uint16_t PW_AUTH_UDP_PORT = 1812;
+static constexpr uint16_t PW_AUTH_PORT = 1812;
 
 /// @brief Default RADIUS accounting port.
-static constexpr uint16_t PW_ACCT_UDP_PORT = 1813;
+static constexpr uint16_t PW_ACCT_PORT = 1813;
+
+/// @brief Default RADIUS/TLS port.
+static constexpr uint16_t PW_TLS_PORT = 2083;
+
+/// @brief Transport protocols.
+enum RadiusProtocol {
+    PW_PROTO_UDP,
+    PW_PROTO_TCP,
+    PW_PROTO_TLS
+};
+
+/// @brief Transport protocol to text.
+std::string protocolToText(const int proto);
 
 /// @brief RADIUS server class.
 class Server : public data::CfgToElement {
index 86fb34a1481bec78b29e14c18401f81590c57d66..8f6423d21f14dd8a0756827eac0e844dabae9a87 100644 (file)
@@ -24,6 +24,7 @@ dhcp_radius_lib = shared_library(
     'radius_request.cc',
     'radius_service.cc',
     'radius_status.cc',
+    'radius_tls.cc',
     'radius_utils.cc',
     'version.cc',
     cpp_args: [f'-DDICTIONARY="@SYSCONFDIR_INSTALLED@/kea/radius/dictionary"'],
index 50100b0eac0e86c5caa2560bd3032903864df420..4516a1e9f1973aa8917b81e714576c6c0537d4b2 100644 (file)
@@ -17,6 +17,7 @@
 #include <radius_accounting.h>
 #include <radius_log.h>
 #include <radius_parsers.h>
+#include <radius_tls.h>
 
 #include <exception>
 
@@ -45,7 +46,8 @@ RadiusImpl::instancePtr() {
 }
 
 RadiusImpl::RadiusImpl()
-    : auth_(new RadiusAccess()), acct_(new RadiusAccounting()),
+    : proto_(PW_PROTO_UDP), common_(new RadiusTls()),
+      auth_(new RadiusAccess()), acct_(new RadiusAccounting()),
       bindaddr_("*"), canonical_mac_address_(false),
       clientid_pop0_(false), clientid_printable_(false),
       deadtime_(0), extract_duid_(true),
@@ -97,6 +99,7 @@ void RadiusImpl::cleanup() {
         backend_.reset();
     }
 
+    common_.reset(new RadiusTls());
     auth_.reset(new RadiusAccess());
     acct_.reset(new RadiusAccounting());
 
@@ -130,6 +133,7 @@ void RadiusImpl::reset() {
 }
 
 void RadiusImpl::init(ElementPtr&config) {
+    common_.reset(new RadiusTls());
     auth_.reset(new RadiusAccess());
     acct_.reset(new RadiusAccounting());
     RadiusConfigParser parser;
index 4f86c1090871615616610151e22731c911fd9ae4..0c76315fc316f75482fcd982bb674e68b2283741 100644 (file)
@@ -36,6 +36,9 @@ namespace radius {
 /// Moved from radius_request.h file for better visibility.
 static const uint32_t SUBNET_ID_DEFAULT = 0;
 
+/// @brief Forward declaration of RadiusTls.
+class RadiusTls;
+
 /// @brief Forward declaration of RadiusAccess.
 class RadiusAccess;
 
@@ -147,10 +150,16 @@ public:
     /// @brief Dictionary path.
     std::string dictionary_;
 
+    /// @brief Transport protocol.
+    RadiusProtocol proto_;
+
     /// @brief Subnet ID to NAS port map.
     std::map<uint32_t, uint32_t> remap_;
 
-    // @brief Pointer to access (never null).
+    /// @brief Pointer to common tls (never null).
+    boost::shared_ptr<RadiusTls> common_;
+
+    /// @brief Pointer to access (never null).
     boost::shared_ptr<RadiusAccess> auth_;
 
     /// @brief Pointer to accounting (never null).
index 081e77f3f74eb09ab44f0f285994139648476321..d07405f15d0e9304f46febc326c5d03226df26de 100644 (file)
@@ -335,7 +335,6 @@ public:
 
     /// @brief Idle timer callback.
     static void IdleTimerCallback();
-
 };
 
 } // end of namespace isc::radius
index 16aee7e701ff8882457b8ad1126ba00a112c3a09..7c806b5916076369eb594304926f7e1a0aa915f7 100644 (file)
@@ -470,9 +470,9 @@ RadiusServerParser::parse(const RadiusServicePtr& service,
     if (server->contains("port")) {
         port = getUint16(server, "port");
     } else if (service->name_ == "access") {
-        port = PW_AUTH_UDP_PORT;
+        port = PW_AUTH_PORT;
     } else {
-        port = PW_ACCT_UDP_PORT;
+        port = PW_ACCT_PORT;
     }
     msg << " port=" << port;
 
diff --git a/src/hooks/dhcp/radius/radius_tls.cc b/src/hooks/dhcp/radius/radius_tls.cc
new file mode 100644 (file)
index 0000000..d1993ed
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (C) 2020-2025 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <radius_status.h>
+#include <radius_tls.h>
+#include <util/multi_threading_mgr.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::asiolink;
+using namespace isc::util;
+
+namespace isc {
+namespace radius {
+
+RadiusTls::RadiusTls() : RadiusService("common-tls") {
+}
+
+void
+RadiusTls::setIdleTimer() {
+    MultiThreadingLock lock(idle_timer_mutex_);
+    cancelIdleTimer();
+    if (idle_timer_interval_ <= 0) {
+        return;
+    }
+    // Cope to one day.
+    long secs = idle_timer_interval_;
+    if (secs > 24*60*60) {
+        secs = 24*60*60;
+    }
+    idle_timer_.reset(new IntervalTimer(RadiusImpl::instance().getIOContext()));
+    idle_timer_->setup(RadiusTls::IdleTimerCallback,
+                       secs * 1000, IntervalTimer::REPEATING);
+}
+
+void
+RadiusTls::IdleTimerCallback() {
+    AttributesPtr send_attrs;
+    RadiusAuthStatusPtr handler(new RadiusAuthStatus(send_attrs, 0));
+    RadiusImpl::instance().registerExchange(handler->getExchange());
+    handler->start();
+}
+
+} // end of namespace isc::radius
+} // end of namespace isc
diff --git a/src/hooks/dhcp/radius/radius_tls.h b/src/hooks/dhcp/radius/radius_tls.h
new file mode 100644 (file)
index 0000000..0253ec3
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef RADIUS_TLS_H
+#define RADIUS_TLS_H
+
+#include <radius_service.h>
+
+namespace isc {
+namespace radius {
+
+/// @brief Radius common service for TLS transport.
+class RadiusTls : public RadiusService {
+public:
+
+    /// @brief Constructor.
+    RadiusTls();
+
+    /// @brief Destructor.
+    virtual ~RadiusTls() = default;
+
+    /// @brief Set idle timer.
+    ///
+    /// @note: The caller must hold the idle timer mutex.
+    void setIdleTimer();
+
+    /// @brief Idle timer callback.
+    static void IdleTimerCallback();
+};
+
+} // end of namespace isc::radius
+} // end of namespace isc
+
+#endif
index bc65d2da26f3f8782cb4f3cb7e4716d6e4dbbdd3..44815ab2a6d79641cd8143a949df89d2b2860453 100644 (file)
@@ -29,6 +29,14 @@ using namespace std::chrono;
 
 namespace {
 
+/// Verify protocolToText.
+TEST(ServerClassTest, protocolToText) {
+    EXPECT_EQ("UDP", protocolToText(PW_PROTO_UDP));
+    EXPECT_EQ("TCP", protocolToText(PW_PROTO_TCP));
+    EXPECT_EQ("TLS", protocolToText(PW_PROTO_TLS));
+    EXPECT_EQ("unknown transport protocol 6", protocolToText(6));
+}
+
 /// Verify Server::getAddress.
 TEST(ServerClassTest, getAddress) {
     boost::scoped_ptr<IOAddress> addr;