#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>
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
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()) {
}
<< " 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()];
#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>
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.
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.
/// @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.
/// @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.
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();
// 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"));