]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1706] Checkpoint: syntax updated - need UTs?
authorFrancis Dupont <fdupont@isc.org>
Thu, 8 Apr 2021 22:20:36 +0000 (00:20 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 20 Apr 2021 21:24:57 +0000 (23:24 +0200)
src/bin/agent/ca_cfg_mgr.h
src/hooks/dhcp/high_availability/ha_config.cc
src/hooks/dhcp/high_availability/ha_config.h
src/hooks/dhcp/high_availability/ha_config_parser.cc
src/hooks/dhcp/high_availability/tests/ha_config_unittest.cc

index df4e0f6dc7a521fc5026e03ffdaf8083c390f0b0..78c722d827ee2aef09779c188470219a2bcad577 100644 (file)
@@ -119,8 +119,8 @@ public:
 
     /// @brief Sets trust-anchor parameter
     ///
-    /// @param ca Trust anchor aka Certificate Authority (can be a file or
-    /// with OpenSSL a directory).
+    /// @param ca Trust anchor aka Certificate Authority (can be a file name
+    /// or a directory path).
     void setTrustAnchor(const std::string& ca) {
         trust_anchor_ = ca;
     }
@@ -225,8 +225,8 @@ private:
     /// TCP port the CA should listen on.
     uint16_t http_port_;
 
-    /// Trust anchor aka Certificate Authority (can be a file or with
-    /// OpenSSL a directory).
+    /// Trust anchor aka Certificate Authority (can be a file name or
+    /// a directory path).
     std::string trust_anchor_;
 
     /// Server certificate file name.
index 67c2f8db0695c06d9196220fbbf1f941ff04cf68..7754f6f3039c6b0a974e8d8366eded47c35bbb7d 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <asiolink/io_address.h>
 #include <asiolink/io_error.h>
+#include <asiolink/crypto_tls.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/cfg_multi_threading.h>
 #include <exceptions/exceptions.h>
@@ -27,8 +28,8 @@ namespace isc {
 namespace ha {
 
 HAConfig::PeerConfig::PeerConfig()
-    : name_(), url_(""), role_(STANDBY), auto_failover_(false),
-      basic_auth_() {
+    : name_(), url_(""), trust_anchor_(), cert_file_(), key_file_(),
+      role_(STANDBY), auto_failover_(false), basic_auth_() {
 }
 
 void
@@ -165,6 +166,7 @@ HAConfig::HAConfig()
       max_ack_delay_(10000), max_unacked_clients_(10), wait_backup_ack_(false),
       enable_multi_threading_(false), http_dedicated_listener_(false),
       http_listener_threads_(0), http_client_threads_(0),
+      trust_anchor_(), cert_file_(), key_file_(),
       peers_(), state_machine_(new StateMachineConfig()) {
 }
 
@@ -296,12 +298,43 @@ HAConfig::validate() {
                       << " for server " << p->second->getName());
         }
 
-        // Refuse HTTPS scheme as TLS is not (yet) supported.
-        if (p->second->getUrl().getScheme() == Url::HTTPS) {
+        // Check TLS setup.
+        bool use_tls = false;
+        Optional<std::string> ca = p->second->getTrustAnchor();
+        Optional<std::string> cert = p->second->getCertFile();
+        Optional<std::string> key = p->second->getKeyFile();
+        // When not configured get the value from the global level.
+        if (ca.unspecified()) {
+            ca = trust_anchor_;
+        }
+        if (cert.unspecified()) {
+            cert = cert_file_;
+        }
+        if (key.unspecified()) {
+            key = key_file_;
+        }
+        if (!ca.unspecified() || !cert.unspecified() || !key.unspecified()) {
+            use_tls = true;
+            try {
+                TlsContextPtr tls_context;
+                TlsContext::configure(tls_context,
+                                      TlsRole::CLIENT,
+                                      ca.get(),
+                                      cert.get(),
+                                      key.get());
+            } catch (const isc::Exception& ex) {
+                isc_throw(HAConfigValidationError, "bad TLS config for server "
+                          << p->second->getName() << ": " << ex.what());
+            }
+        }
+
+        // Refuse HTTPS scheme when TLS is not enabled.
+        if (!use_tls && (p->second->getUrl().getScheme() == Url::HTTPS)) {
             isc_throw(HAConfigValidationError, "bad url '"
                       << p->second->getUrl().toText()
                       << "': https scheme is not supported"
-                      << " for server " << p->second->getName());
+                      << " for server " << p->second->getName()
+                      << " where TLS is disabled");
         }
 
         ++peers_cnt[p->second->getRole()];
index b730b80f292372d191892c2da08cdadc6220d503..359c7316e546fcc19c0e732fbc0f8b1c3ef7a18d 100644 (file)
@@ -11,6 +11,7 @@
 #include <http/basic_auth.h>
 #include <http/post_request_json.h>
 #include <http/url.h>
+#include <util/optional.h>
 #include <util/state_model.h>
 #include <boost/shared_ptr.hpp>
 #include <cstdint>
@@ -98,6 +99,42 @@ public:
             url_ = url;
         }
 
+        /// @brief Return server's trust-anchor.
+        util::Optional<std::string> getTrustAnchor() const {
+            return (trust_anchor_);
+        }
+
+        /// @brief Sets server's trust-anchor.
+        ///
+        /// @param ca Trust anchor aka Certificate Authority.
+        void setTrustAnchor(const util::Optional<std::string>& ca) {
+            trust_anchor_ = ca;
+        }
+
+        /// @brief Return server's cert-file.
+        util::Optional<std::string> getCertFile() const {
+            return (cert_file_);
+        }
+
+        /// @brief Sets server's cert-file.
+        ///
+        /// @param cert Certificate file name.
+        void setCertFile(const util::Optional<std::string>& cert) {
+            cert_file_ = cert;
+        }
+
+        /// @brief Return server's key-file.
+        util::Optional<std::string> getKeyFile() const {
+            return (key_file_);
+        }
+
+        /// @brief Sets server's key-file.
+        ///
+        /// @param key Private key file name.
+        void setKeyFile(const util::Optional<std::string>& key) {
+            key_file_ = key;
+        }
+
         /// @brief Returns a string identifying a server used in logging.
         ///
         /// The label is constructed from server name and server URL.
@@ -166,11 +203,14 @@ public:
 
     private:
 
-        std::string name_;                  ///< Server name.
-        http::Url url_;                     ///< Server URL.
-        Role role_;                         ///< Server role.
-        bool auto_failover_;                ///< Auto failover state.
-        http::BasicHttpAuthPtr basic_auth_; ///< Basic HTTP authentication.
+        std::string name_;                          ///< Server name.
+        http::Url url_;                             ///< Server URL.
+        util::Optional<std::string> trust_anchor_;  ///< Server trust anchor.
+        util::Optional<std::string> cert_file_;     ///< Server cert file.
+        util::Optional<std::string> key_file_;      ///< Server key file.
+        Role role_;                                 ///< Server role.
+        bool auto_failover_;                        ///< Auto failover state.
+        http::BasicHttpAuthPtr basic_auth_;         ///< Basic HTTP authentication.
     };
 
     /// @brief Pointer to the server's configuration.
@@ -578,6 +618,41 @@ public:
     /// @param http_client_threads number of threads the client should use.
     void setHttpClientThreads(uint32_t http_client_threads) {
         http_client_threads_ = http_client_threads;
+
+    /// @brief Return global trust-anchor.
+    util::Optional<std::string> getTrustAnchor() const {
+        return (trust_anchor_);
+    }
+
+    /// @brief Sets global trust-anchor.
+    ///
+    /// @param ca Trust anchor aka Certificate Authority.
+    void setTrustAnchor(const util::Optional<std::string>& ca) {
+        trust_anchor_ = ca;
+    }
+
+    /// @brief Return global cert-file.
+    util::Optional<std::string> getCertFile() const {
+        return (cert_file_);
+    }
+
+    /// @brief Sets global cert-file.
+    ///
+    /// @param cert Certificate file name.
+    void setCertFile(const util::Optional<std::string>& cert) {
+        cert_file_ = cert;
+    }
+
+    /// @brief Return global key-file.
+    util::Optional<std::string> getKeyFile() const {
+        return (key_file_);
+    }
+
+    /// @brief Sets global key-file.
+    ///
+    /// @param key Private key file name.
+    void setKeyFile(const util::Optional<std::string>& key) {
+        key_file_ = key;
     }
 
     /// @brief Returns configuration of the specified server.
@@ -641,26 +716,29 @@ public:
     /// @throw HAConfigValidationError if configuration is invalid.
     void validate();
 
-    std::string this_server_name_;        ///< This server name.
-    HAMode ha_mode_;                      ///< Mode of operation.
-    bool send_lease_updates_;             ///< Send lease updates to partner?
-    bool sync_leases_;                    ///< Synchronize databases on startup?
-    uint32_t sync_timeout_;               ///< Timeout for syncing lease database (ms)
-    uint32_t sync_page_limit_;            ///< Page size limit while synchronizing
-                                          ///< leases.
-    uint32_t delayed_updates_limit_;      ///< Maximum number of lease updates held
-                                          ///< for later send in communication-recovery.
-    uint32_t heartbeat_delay_;            ///< Heartbeat delay in milliseconds.
-    uint32_t max_response_delay_;         ///< Max delay in response to heartbeats.
-    uint32_t max_ack_delay_;              ///< Maximum DHCP message ack delay.
-    uint32_t max_unacked_clients_;        ///< Maximum number of unacked clients.
-    bool wait_backup_ack_;                ///< Wait for lease update ack from backup?
-    bool enable_multi_threading_;         ///< Enable multi-threading.
-    bool http_dedicated_listener_;        ///< Enable use of own HTTP listener.
-    uint32_t http_listener_threads_;      ///< Number of HTTP listener threads.
-    uint32_t http_client_threads_;        ///< Number of HTTP client threads.
-    PeerConfigMap peers_;                 ///< Map of peers' configurations.
-    StateMachineConfigPtr state_machine_; ///< State machine configuration.
+    std::string this_server_name_;            ///< This server name.
+    HAMode ha_mode_;                          ///< Mode of operation.
+    bool send_lease_updates_;                 ///< Send lease updates to partner?
+    bool sync_leases_;                        ///< Synchronize databases on startup?
+    uint32_t sync_timeout_;                   ///< Timeout for syncing lease database (ms)
+    uint32_t sync_page_limit_;                ///< Page size limit while
+                                              ///< synchronizing leases.
+    uint32_t delayed_updates_limit_;          ///< Maximum number of lease updates held
+                                              ///< for later send in communication-recovery.
+    uint32_t heartbeat_delay_;                ///< Heartbeat delay in milliseconds.
+    uint32_t max_response_delay_;             ///< Max delay in response to heartbeats.
+    uint32_t max_ack_delay_;                  ///< Maximum DHCP message ack delay.
+    uint32_t max_unacked_clients_;            ///< Maximum number of unacked clients.
+    bool wait_backup_ack_;                    ///< Wait for lease update ack from backup?
+    bool enable_multi_threading_;             ///< Enable multi-threading.
+    bool http_dedicated_listener_;            ///< Enable use of own HTTP listener.
+    uint32_t http_listener_threads_;          ///< Number of HTTP listener threads.
+    uint32_t http_client_threads_;            ///< Number of HTTP client threads.
+    util::Optional<std::string> trust_anchor_; ///< Trust anchor.
+    util::Optional<std::string> cert_file_;    ///< Certificate file.
+    util::Optional<std::string> key_file_;     ///< Private key file.
+    PeerConfigMap peers_;                      ///< Map of peers' configurations.
+    StateMachineConfigPtr state_machine_;      ///< State machine configuration.
 };
 
 /// @brief Pointer to the High Availability configuration structure.
index 5b336a4f64c89756001cfbea665883731aa04af9..2d1a41033eb70198709ac000e7bf55def38e9a90 100644 (file)
@@ -210,6 +210,24 @@ HAConfigParser::parseInternal(const HAConfigPtr& config_storage,
     threads = getAndValidateInteger<uint32_t>(mt_config, "http-client-threads");
     config_storage->setHttpClientThreads(threads);
 
+    // Get optional 'trust-anchor'.
+    ConstElementPtr ca = c->get("trust-anchor");
+    if (ca) {
+        config_storage->setTrustAnchor(getString(c, ("trust-anchor")));
+    }
+
+    // Get optional 'cert-file'.
+    ConstElementPtr cert = c->get("cert-file");
+    if (cert) {
+        config_storage->setCertFile(getString(c, ("cert-file")));
+    }
+
+    // Get optional 'key-file'.
+    ConstElementPtr key = c->get("key-file");
+    if (key) {
+        config_storage->setKeyFile(getString(c, ("key-file")));
+    }
+
     // Peers configuration parsing.
     const auto& peers_vec = peers->listValue();
 
@@ -229,6 +247,21 @@ HAConfigParser::parseInternal(const HAConfigPtr& config_storage,
         // URL.
         cfg->setUrl(Url(getString((*p), "url")));
 
+        // Optional trust anchor.
+        if ((*p)->contains("trust-anchor")) {
+            cfg->setTrustAnchor(getString(*p, ("trust-anchor")));
+        }
+
+        // Optional certificate file.
+        if ((*p)->contains("cert-file")) {
+            cfg->setCertFile(getString(*p, ("cert-file")));
+        }
+
+        // Optional private key file.
+        if ((*p)->contains("key-file")) {
+            cfg->setKeyFile(getString(*p, ("key-file")));
+        }
+
         // Role.
         cfg->setRole(getString(*p, "role"));
 
index 16e7ad74e6c8e086d2c5bc973fbc735563a480e0..68c13eb7899e897d93d0f43fafb8ca78640f811c 100644 (file)
@@ -676,7 +676,8 @@ TEST_F(HAConfigTest, badURLHttps) {
         "    }"
         "]",
         "bad url 'https://127.0.0.1:8080/': "
-        "https scheme is not supported for server server2");
+        "https scheme is not supported for server server2 "
+        "where TLS is disabled");
 }
 
 // Only certain roles are allowed.