From 751b896c3d2d806eb551b4e59128fea9a738090f Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 28 Mar 2018 12:42:51 -0700 Subject: [PATCH] ircd::m: Improve various initial conf related keys and routines. --- ircd/m/m.cc | 105 +++++++++++++++++++++++++++++++++++++++++++----- ircd/net.cc | 52 +++++++++++++++--------- ircd/openssl.cc | 8 ++-- 3 files changed, 131 insertions(+), 34 deletions(-) diff --git a/ircd/m/m.cc b/ircd/m/m.cc index b0c661cc0..4f4022fc6 100644 --- a/ircd/m/m.cc +++ b/ircd/m/m.cc @@ -96,7 +96,7 @@ ircd::m::init::init() try :config { - ircd::conf::config //TODO: X + ircd::conf::config } ,_keys { @@ -195,7 +195,15 @@ ircd::m::init::listeners() config.at({"listen", unquote(name)}) }; - init_listener(config, name, opts); + if(!opts.has("tmp_dh_path")) + throw user_error + { + "Listener %s requires a 'tmp_dh_path' in the config. We do not" + " create this yet. Try `openssl dhparam -outform PEM -out dh512.pem 512`", + name + }; + + init_listener(config, unquote(name), opts); } catch(const json::not_found &e) { @@ -451,32 +459,90 @@ ircd::m::keys::init::certificate() const json::object config { - this->config.at({"origin", unquote(origin)}) + this->config.at({"origin", origin}) }; const std::string private_key_file { - unquote(config.at("ssl_private_key_file_pem")) + unquote(config.get("ssl_private_key_pem_path")) }; const std::string public_key_file { - unquote(config.get("ssl_public_key_file_pem", private_key_file + ".pub")) + unquote(config.get("ssl_public_key_pem_path", private_key_file + ".pub")) }; + if(!private_key_file) + throw user_error + { + "You must specify an SSL private key file at" + " origin.[%s].ssl_private_pem_path even if you do not have one;" + " it will be created there.", + origin + }; + if(!fs::exists(private_key_file)) { - log::warning("Failed to find certificate private key @ `%s'; creating...", private_key_file); + log::warning + { + "Failed to find certificate private key @ `%s'; creating...", + private_key_file + }; + openssl::genrsa(private_key_file, public_key_file); } const std::string cert_file { - unquote(config.at("ssl_certificate_file_pem")) + unquote(config.get("ssl_certificate_pem_path")) }; + if(!cert_file) + throw user_error + { + "You must specify an SSL certificate file path in the config at" + " origin.[%s].ssl_certificate_pem_path even if you do not have one;" + " it will be created there.", + origin + }; + if(!fs::exists(cert_file)) - throw fs::error("Failed to find SSL certificate @ `%s'", cert_file); + { + if(!this->config.has({"certificate", origin, "subject"})) + throw user_error + { + "Failed to find SSL certificate @ `%s'. Additionally, no" + " certificate.[%s].subject was found in the conf to generate one.", + cert_file, + origin + }; + + log::warning + { + "Failed to find SSL certificate @ `%s'; creating for '%s'...", + cert_file, + origin + }; + + const unique_buffer buf + { + 1_MiB + }; + + const json::strung opts{json::members + { + { "private_key_pem_path", private_key_file }, + { "public_key_pem_path", public_key_file }, + { "subject", this->config.get({"certificate", origin, "subject"}) } + }}; + + const auto cert + { + openssl::genX509_rsa(buf, opts) + }; + + fs::overwrite(cert_file, cert); + } const auto cert_pem { @@ -518,15 +584,34 @@ ircd::m::keys::init::certificate() void ircd::m::keys::init::signing() { + const string_view origin + { + unquote(this->config.at({"ircd", "origin"})) + }; + + const json::object config + { + this->config.at({"origin", unquote(origin)}) + }; + const std::string sk_file { - unquote(config.get("signing_key_path", "construct.sk")) + unquote(config.get("ed25519_private_key_path")) }; + if(!sk_file) + throw user_error + { + "Failed to find ed25519 secret key path at" + " origin.[%s].ed25519_private_key_path in config. If you do not" + " have a private key, specify a path for one to be created.", + origin + }; + if(fs::exists(sk_file)) log.info("Using ed25519 secret key @ `%s'", sk_file); else - log.notice("Creating new ed25519 secret key @ `%s'", sk_file); + log.notice("Creating ed25519 secret key @ `%s'", sk_file); self::secret_key = ed25519::sk { diff --git a/ircd/net.cc b/ircd/net.cc index 48f7497c1..799e4b2c3 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -1184,17 +1184,20 @@ ircd::net::listener::acceptor::configure(const json::object &opts) return "foobar"; }); - if(opts.has("ssl_certificate_chain_file")) + if(opts.has("certificate_chain_path")) { const std::string filename { - unquote(opts["ssl_certificate_chain_file"]) + unquote(opts["certificate_chain_path"]) }; if(!fs::exists(filename)) - throw error("%s: SSL certificate chain file @ `%s' not found", - std::string(*this), - filename); + throw error + { + "%s: SSL certificate chain file @ `%s' not found", + std::string(*this), + filename + }; ssl.use_certificate_chain_file(filename); log.info("%s using certificate chain file '%s'", @@ -1202,17 +1205,20 @@ ircd::net::listener::acceptor::configure(const json::object &opts) filename); } - if(opts.has("ssl_certificate_file_pem")) + if(opts.has("certificate_pem_path")) { const std::string filename { - unquote(opts["ssl_certificate_file_pem"]) + unquote(opts["certificate_pem_path"]) }; if(!fs::exists(filename)) - throw error("%s: SSL certificate pem file @ `%s' not found", - std::string(*this), - filename); + throw error + { + "%s: SSL certificate pem file @ `%s' not found", + std::string(*this), + filename + }; ssl.use_certificate_file(filename, asio::ssl::context::pem); log.info("%s using certificate file '%s'", @@ -1220,17 +1226,20 @@ ircd::net::listener::acceptor::configure(const json::object &opts) filename); } - if(opts.has("ssl_private_key_file_pem")) + if(opts.has("private_key_pem_path")) { const std::string filename { - unquote(opts["ssl_private_key_file_pem"]) + unquote(opts["private_key_pem_path"]) }; if(!fs::exists(filename)) - throw error("%s: SSL private key file @ `%s' not found", - std::string(*this), - filename); + throw error + { + "%s: SSL private key file @ `%s' not found", + std::string(*this), + filename + }; ssl.use_private_key_file(filename, asio::ssl::context::pem); log.info("%s using private key file '%s'", @@ -1238,17 +1247,20 @@ ircd::net::listener::acceptor::configure(const json::object &opts) filename); } - if(opts.has("ssl_tmp_dh_file")) + if(opts.has("tmp_dh_path")) { const std::string filename { - unquote(opts["ssl_tmp_dh_file"]) + unquote(opts["tmp_dh_path"]) }; if(!fs::exists(filename)) - throw error("%s: SSL tmp dh file @ `%s' not found", - std::string(*this), - filename); + throw error + { + "%s: SSL tmp dh file @ `%s' not found", + std::string(*this), + filename + }; ssl.use_tmp_dh_file(filename); log.info("%s using tmp dh file '%s'", diff --git a/ircd/openssl.cc b/ircd/openssl.cc index a1fabdd7c..02c7137aa 100644 --- a/ircd/openssl.cc +++ b/ircd/openssl.cc @@ -184,14 +184,14 @@ void ircd::openssl::genx509_readkeys(EVP_PKEY &pk, const json::object &opts) { - const auto private_key_path + const std::string private_key_path { - unquote(opts.at("tls_private_key_path")) + unquote(opts.at("private_key_pem_path")) }; - const auto public_key_path + const std::string public_key_path { - unquote(opts.at("tls_public_key_path")) + unquote(opts.get("public_key_pem_path", private_key_path + ".pub")) }; bio::read_file(private_key_path, [&pk](const string_view &pem)