]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1662] Checkpoint before regen
authorFrancis Dupont <fdupont@isc.org>
Tue, 9 Feb 2021 21:04:35 +0000 (22:04 +0100)
committerFrancis Dupont <fdupont@isc.org>
Wed, 17 Feb 2021 11:53:10 +0000 (12:53 +0100)
doc/examples/agent/simple.json
src/bin/agent/ca_cfg_mgr.cc
src/bin/agent/ca_cfg_mgr.h
src/bin/agent/simple_parser.cc
src/bin/agent/simple_parser.h
src/bin/agent/tests/get_config_unittest.cc
src/bin/agent/tests/testdata/get_config.json

index 7aa741d33d8d50d253329b449544bf23d3938915..2a7486c55a20c48fde35a7fb02df1a3eab19d675 100644 (file)
         // Another mandatory parameter is the HTTP port.
         "http-port": 8000,
 
+        // TLS trust anchor aka Certificate Authority. A file name or
+        // with OpenSSL a directory path.
+        "trust-anchor": "my-ca",
+
+        // TLS server certificate file name.
+        "cert-file": "my-cert",
+
+        // TLS server private key file name.
+        "key-file": "my-key",
+
+        // TLS require client certificates flag. Default is true and means
+        // require client certificates. False means they are optional.
+        "file-required": true,
+
         // Optional authentication.
         "authentication":
         {
index 0a9a7bfcb99d3eb9e9b8a01881ed49a1f25cea47..2a715c7a9f030d1e023adcfef0f319f737f3de2f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2021 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
@@ -22,7 +22,8 @@ namespace isc {
 namespace agent {
 
 CtrlAgentCfgContext::CtrlAgentCfgContext()
-    : http_host_(""), http_port_(0) {
+    : http_host_(""), http_port_(0),
+      trust_anchor_(""), cert_file_(""), key_file_(""), cert_required_(true) {
 }
 
 CtrlAgentCfgContext::CtrlAgentCfgContext(const CtrlAgentCfgContext& orig)
@@ -46,7 +47,20 @@ CtrlAgentCfgMgr::getConfigSummary(const uint32_t /*selection*/) {
     // First print the http stuff.
     std::ostringstream s;
     s << "listening on " << ctx->getHttpHost() << ", port "
-      << ctx->getHttpPort() << ", control sockets: ";
+      << ctx->getHttpPort();
+
+    // When TLS is setup print its config.
+    if (!ctx->getTrustAnchor().empty()) {
+        s << ", trust anchor " << ctx->getTrustAnchor()
+          << ", cert file " << ctx->getCertFile()
+          << ", key file " << ctx->getKeyFile();
+        if (ctx->getCertRequired()) {
+            s << ", client certs are required";
+        } else {
+            s << ", client certs are optional";
+        }
+    }
+    s << ", control sockets: ";
 
     // Then print the control-sockets
     s << ctx->getControlSocketInfoSummary();
@@ -91,6 +105,7 @@ CtrlAgentCfgMgr::parse(ConstElementPtr config_set, bool check_only) {
     try {
         // Do the actual parsing
         AgentSimpleParser parser;
+        parser.checkTlsSetup(cfg);
         parser.parse(ctx, cfg, check_only);
     } catch (const isc::Exception& ex) {
         excuse = ex.what();
@@ -218,6 +233,13 @@ CtrlAgentCfgContext::toElement() const {
     ca->set("http-host", Element::create(http_host_));
     // Set http-port
     ca->set("http-port", Element::create(static_cast<int64_t>(http_port_)));
+    // Set TLS setup when enabled
+    if (!trust_anchor_.empty()) {
+        ca->set("trust-anchor", Element::create(trust_anchor_));
+        ca->set("cert-file", Element::create(cert_file_));
+        ca->set("key-file", Element::create(key_file_));
+        ca->set("cert-required", Element::create(cert_required_));
+    }
     // Set authentication
     if (auth_config_) {
         ca->set("authentication", auth_config_->toElement());
index f43778b7835994db058e19e87bd1fc982aaed404..4e8a38615f85d92aa93f58eed41f6eef6370cd8b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2021 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
@@ -117,6 +117,65 @@ public:
         return (auth_config_);
     }
 
+    /// @brief Sets trust-anchor parameter
+    ///
+    /// @param ca Trust anchor aka Certificate Authority (can be a file or
+    /// with OpenSSL a directory).
+    void setTrustAnchor(const std::string& ca) {
+        trust_anchor_ = ca;
+    }
+
+    /// @brief Returns trust-anchor parameter
+    ///
+    /// @return Trust anchor aka Certificate Authority
+    std::string getTrustAnchor() const {
+        return (trust_anchor_);
+    }
+
+    /// @brief Sets cert-file parameter
+    ///
+    /// @param cert Server certificate file name
+    void setCertFile(const std::string& cert) {
+        cert_file_ = cert;
+    }
+
+    /// @brief Returns cert-file parameter
+    ///
+    /// @return Server certificate file name
+    std::string getCertFile() const {
+        return (cert_file_);
+    }
+
+    /// @brief Sets key-file parameter
+    ///
+    /// @param key Server private key file name
+    void setKeyFile(const std::string& key) {
+        key_file_ = key;
+    }
+
+    /// @brief Returns key-file parameter
+    ///
+    /// @return Server private key file name
+    std::string getKeyFile() const {
+        return (key_file_);
+    }
+
+    /// @brief Sets cert-required parameter
+    ///
+    /// @param required Client certificates are required when true
+    /// (the default) or optional when false
+    void setCertRequired(bool required) {
+        cert_required_ = required;
+    }
+
+    /// @brief Returns cert-required parameter
+    ///
+    /// @return True when client certificates are required, false when they
+    /// are optional, the default is to required them (true).
+    bool getCertRequired() const {
+        return (cert_required_);
+    }
+
     /// @brief Returns non-const reference to configured hooks libraries.
     ///
     /// @return non-const reference to configured hooks libraries.
@@ -166,6 +225,20 @@ 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).
+    std::string trust_anchor_;
+
+    /// Server certificate file name.
+    std::string cert_file_;
+
+    /// Server private key file name.
+    std::string key_file_;
+
+    /// Client certificates requirement flag (default is true i.e. to
+    /// require them).
+    bool cert_required_;
+
     /// @brief Configured hooks libraries.
     isc::hooks::HooksConfig hooks_config_;
 
index eb65352f853fedf69df4fef56c555eff3affa326..43a6461c0f714202e47cb26f91eb4c6007131f53 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2021 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
@@ -37,8 +37,12 @@ namespace agent {
 ///
 /// These are global Control Agent parameters.
 const SimpleDefaults AgentSimpleParser::AGENT_DEFAULTS = {
-    { "http-host",    Element::string,  "127.0.0.1" },
-    { "http-port",    Element::integer, "8000" }
+    { "http-host",      Element::string,   "127.0.0.1" },
+    { "http-port",      Element::integer,  "8000" },
+    { "trust-anchor",   Element::string,   "" },
+    { "cert-file",      Element::string,   "" },
+    { "key-file",       Element::string,   "" },
+    { "cert-required",  Element::boolean,  "true" }
 };
 
 /// @brief This table defines default values for authentication.
@@ -96,6 +100,32 @@ size_t AgentSimpleParser::setAllDefaults(const isc::data::ElementPtr& global) {
     return (cnt);
 }
 
+void
+AgentSimpleParser::checkTlsSetup(const isc::data::ConstElementPtr& config) {
+    ConstElementPtr ca = config->get("trust-anchor");
+    ConstElementPtr cert = config->get("cert-file");
+    ConstElementPtr key = config->get("key-file");
+    if (ca && !ca->stringValue().empty()) {
+        if (!cert || cert->stringValue().empty()) {
+            isc_throw(ConfigError, "trust-anchor is set but not cert-file:"
+                      " all or none of TLS parameters must be set");
+        }
+        if (!key || key->stringValue().empty()) {
+            isc_throw(ConfigError, "cert-file is set but not key-file:"
+                      " all or none of TLS parameters must be set");
+        }
+    } else {
+        if (cert && !cert->stringValue().empty()) {
+            isc_throw(ConfigError, "cert-file is set but not trust-anchor:"
+                      " all or none of TLS parameters must be set");
+        }
+        if (key && !key->stringValue().empty()) {
+            isc_throw(ConfigError, "key-file is set but not cert-file:"
+                      " all or none of TLS parameters must be set");
+        }
+    }
+}
+
 void
 AgentSimpleParser::parse(const CtrlAgentCfgContextPtr& ctx,
                          const isc::data::ConstElementPtr& config,
@@ -105,7 +135,13 @@ AgentSimpleParser::parse(const CtrlAgentCfgContextPtr& ctx,
     ctx->setHttpHost(SimpleParser::getString(config, "http-host"));
     ctx->setHttpPort(SimpleParser::getIntType<uint16_t>(config, "http-port"));
 
-    // Control sockets are second.
+    // TLS parameter are second.
+    ctx->setTrustAnchor(SimpleParser::getString(config, "trust-anchor"));
+    ctx->setCertFile(SimpleParser::getString(config, "cert-file"));
+    ctx->setKeyFile(SimpleParser::getString(config, "key-file"));
+    ctx->setCertRequired(SimpleParser::getBoolean(config, "cert-required"));
+
+    // Control sockets are third.
     ConstElementPtr ctrl_sockets = config->get("control-sockets");
     if (ctrl_sockets) {
         auto sockets_map = ctrl_sockets->mapValue();
@@ -114,7 +150,7 @@ AgentSimpleParser::parse(const CtrlAgentCfgContextPtr& ctx,
         }
     }
 
-    // Basic HTTP authentications are third.
+    // Basic HTTP authentications are forth.
     ConstElementPtr auth_config = config->get("authentication");
     if (auth_config) {
         using namespace isc::http;
index 6d29fbf20587cc877ce808f7ea4df1bfb420a79f..20f61d8f3ed0d861cf0643d2b0bfeb90dcf911bb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2021 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
@@ -30,6 +30,12 @@ public:
     /// @return number of default values added
     static size_t setAllDefaults(const isc::data::ElementPtr& global);
 
+    /// @brief Check TLS setup consistency i.e. all or none.
+    ///
+    /// @param config - Element tree structure that holds configuration.
+    /// @throw ConfigError when the configuration is not consistent.
+    void checkTlsSetup(const isc::data::ConstElementPtr& config);
+
     /// @brief Parses the control agent configuration
     ///
     /// @param ctx - parsed information will be stored here
index 45396ecaf13bf6505209a1322442666e9f0dc7cc..2d557294edc44429e4fb80b3dac5758099751f18 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2021 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
index f60c521a53824cea46ba87c770bd78ebc19d5fc2..38a6d47fb5f32b0be34294e4f1fe795225581dbb 100644 (file)
@@ -13,6 +13,8 @@
             "realm": "kea-control-agent",
             "type": "basic"
         },
+        "cert-file": "my-cert",
+        "cert-required": true,
         "control-sockets": {
             "d2": {
                 "socket-name": "/tmp/kea-ddns-ctrl-socket",
@@ -42,6 +44,8 @@
             }
         ],
         "http-host": "127.0.0.1",
-        "http-port": 8000
+        "http-port": 8000,
+        "key-file": "my-key",
+        "trust-anchor": "my-ca"
     }
 }