diff --git a/external/subpack/net/nginx-util/src/nginx-ssl-util.hpp b/external/subpack/net/nginx-util/src/nginx-ssl-util.hpp
new file mode 100644
index 0000000..5a64b00
--- /dev/null
+++ b/external/subpack/net/nginx-util/src/nginx-ssl-util.hpp
@@ -0,0 +1,1124 @@
+#ifndef __NGINX_SSL_UTIL_HPP
+#define __NGINX_SSL_UTIL_HPP
+
+#ifdef NO_PCRE
+#include <regex>
+namespace rgx = std;
+#else
+#include "regex-pcre.hpp"
+#endif
+
+#include "nginx-util.hpp"
+#include "px5g-openssl.hpp"
+
+#ifndef NO_UBUS
+static constexpr auto UBUS_TIMEOUT = 1000;
+#endif
+
+// once a year:
+static constexpr auto CRON_INTERVAL = std::string_view{"3 3 12 12 *"};
+
+static constexpr auto LAN_SSL_LISTEN = std::string_view{"/var/lib/nginx/lan_ssl.listen"};
+
+static constexpr auto LAN_SSL_LISTEN_DEFAULT =  // TODO(pst) deprecate
+    std::string_view{"/var/lib/nginx/lan_ssl.listen.default"};
+
+static constexpr auto ADD_SSL_FCT = std::string_view{"add_ssl"};
+
+static constexpr auto SSL_SESSION_CACHE_ARG = [](const std::string_view & /*name*/) -> std::string {
+    return "shared:SSL:32k";
+};
+
+static constexpr auto SSL_SESSION_TIMEOUT_ARG = std::string_view{"64m"};
+
+using _Line = std::array<std::string (*)(const std::string&, const std::string&), 2>;
+
+class Line {
+  private:
+    _Line _line;
+
+  public:
+    explicit Line(const _Line& line) noexcept : _line{line} {}
+
+    template <const _Line&... xn>
+    static auto build() noexcept -> Line
+    {
+        return Line{_Line{[](const std::string& p, const std::string& b) -> std::string {
+                              return (... + xn[0](p, b));
+                          },
+                          [](const std::string& p, const std::string& b) -> std::string {
+                              return (... + xn[1](p, b));
+                          }}};
+    }
+
+    [[nodiscard]] auto STR(const std::string& param, const std::string& begin) const -> std::string
+    {
+        return _line[0](param, begin);
+    }
+
+    [[nodiscard]] auto RGX() const -> rgx::regex
+    {
+        return rgx::regex{_line[1]("", "")};
+    }
+};
+
+auto get_if_missed(const std::string& conf,
+                   const Line& LINE,
+                   const std::string& val,
+                   const std::string& indent = "\n    ",
+                   bool compare = true) -> std::string;
+
+auto replace_if(const std::string& conf,
+                const rgx::regex& rgx,
+                const std::string& val,
+                const std::string& insert) -> std::string;
+
+auto replace_listen(const std::string& conf, const std::array<const char*, 2>& ngx_port)
+    -> std::string;
+
+auto check_ssl_certificate(const std::string& crtpath, const std::string& keypath) -> bool;
+
+auto contains(const std::string& sentence, const std::string& word) -> bool;
+
+auto get_uci_section_for_name(const std::string& name) -> uci::section;
+
+void add_ssl_if_needed(const std::string& name);
+
+void add_ssl_if_needed(const std::string& name,
+                       std::string_view manage,
+                       std::string_view crt,
+                       std::string_view key);
+
+void install_cron_job(const Line& CRON_LINE, const std::string& name = "");
+
+void remove_cron_job(const Line& CRON_LINE, const std::string& name = "");
+
+auto del_ssl_legacy(const std::string& name) -> bool;
+
+void del_ssl(const std::string& name);
+
+void del_ssl(const std::string& name, std::string_view manage);
+
+auto check_ssl(const uci::package& pkg, bool is_enabled) -> bool;
+
+inline void check_ssl(const uci::package& pkg)
+{
+    if (!check_ssl(pkg, is_enabled(pkg))) {
+#ifndef NO_UBUS
+        if (ubus::call("service", "list", UBUS_TIMEOUT).filter("nginx")) {
+            call("/etc/init.d/nginx", "reload");
+            std::cerr << "Reload Nginx.\n";
+        }
+#endif
+    }
+}
+
+constexpr auto _begin = _Line{
+    [](const std::string& /*param*/, const std::string& begin) -> std::string { return begin; },
+
+    [](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+        return R"([{;](?:\s*#[^\n]*(?=\n))*(\s*))";
+    }};
+
+constexpr auto _space = _Line{[](const std::string& /*param*/, const std::string &
+                                 /*begin*/) -> std::string { return std::string{" "}; },
+
+                              [](const std::string& /*param*/, const std::string &
+                                 /*begin*/) -> std::string { return R"(\s+)"; }};
+
+constexpr auto _newline = _Line{
+    [](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+        return std::string{"\n"};
+    },
+
+    [](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+        return std::string{"(\n)"};
+    }  // capture it as _end captures it, too.
+};
+
+constexpr auto _end =
+    _Line{[](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+              return std::string{";"};
+          },
+
+          [](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+              return std::string{R"(\s*(;(?:[\t ]*#[^\n]*)?))"};
+          }};
+
+template <char clim = '\0'>
+static constexpr auto _capture = _Line{
+    [](const std::string& param, const std::string & /*begin*/) -> std::string {
+        return '\'' + param + '\'';
+    },
+
+    [](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+        const auto lim = clim == '\0' ? std::string{"\\s"} : std::string{clim};
+        return std::string{R"(((?:(?:"[^"]*")|(?:[^'")"} + lim + "][^" + lim + "]*)|(?:'[^']*'))+)";
+    }};
+
+template <const std::string_view& strptr, char clim = '\0'>
+static constexpr auto _escape = _Line{
+    [](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+        return clim == '\0' ? std::string{strptr.data()} : clim + std::string{strptr.data()} + clim;
+    },
+
+    [](const std::string& /*param*/, const std::string & /*begin*/) -> std::string {
+        std::string ret{};
+        for (char c : strptr) {
+            switch (c) {
+                case '^':
+                    ret += '\\';
+                    ret += c;
+                    break;
+                case '_':
+                case '-':
+                    ret += c;
+                    break;
+                default:
+                    if ((isalpha(c) != 0) || (isdigit(c) != 0)) {
+                        ret += c;
+                    }
+                    else {
+                        ret += std::string{"["} + c + "]";
+                    }
+            }
+        }
+        return "(?:" + ret + "|'" + ret + "'" + "|\"" + ret + "\"" + ")";
+    }};
+
+constexpr std::string_view _check_ssl = "check_ssl";
+
+constexpr std::string_view _server_name = "server_name";
+
+constexpr std::string_view _listen = "listen";
+
+constexpr std::string_view _include = "include";
+
+constexpr std::string_view _ssl_certificate = "ssl_certificate";
+
+constexpr std::string_view _ssl_certificate_key = "ssl_certificate_key";
+
+constexpr std::string_view _ssl_session_cache = "ssl_session_cache";
+
+constexpr std::string_view _ssl_session_timeout = "ssl_session_timeout";
+
+// For a compile time regex lib, this must be fixed, use one of these options:
+// * Hand craft or macro concat them (loosing more or less flexibility).
+// * Use Macro concatenation of __VA_ARGS__ with the help of:
+//   https://p99.gforge.inria.fr/p99-html/group__preprocessor__for.html
+// * Use constexpr---not available for strings or char * for now---look at lib.
+
+static const auto CRON_CHECK =
+    Line::build<_space, _escape<NGINX_UTIL>, _space, _escape<_check_ssl, '\''>, _newline>();
+
+static const auto CRON_CMD = Line::build<_space,
+                                         _escape<NGINX_UTIL>,
+                                         _space,
+                                         _escape<ADD_SSL_FCT, '\''>,
+                                         _space,
+                                         _capture<>,
+                                         _newline>();
+
+static const auto NGX_SERVER_NAME =
+    Line::build<_begin, _escape<_server_name>, _space, _capture<';'>, _end>();
+
+static const auto NGX_INCLUDE_LAN_LISTEN =
+    Line::build<_begin, _escape<_include>, _space, _escape<LAN_LISTEN, '\''>, _end>();
+
+static const auto NGX_INCLUDE_LAN_LISTEN_DEFAULT =
+    Line::build<_begin, _escape<_include>, _space, _escape<LAN_LISTEN_DEFAULT, '\''>, _end>();
+
+static const auto NGX_INCLUDE_LAN_SSL_LISTEN =
+    Line::build<_begin, _escape<_include>, _space, _escape<LAN_SSL_LISTEN, '\''>, _end>();
+
+static const auto NGX_INCLUDE_LAN_SSL_LISTEN_DEFAULT =
+    Line::build<_begin, _escape<_include>, _space, _escape<LAN_SSL_LISTEN_DEFAULT, '\''>, _end>();
+
+static const auto NGX_SSL_CRT =
+    Line::build<_begin, _escape<_ssl_certificate>, _space, _capture<';'>, _end>();
+
+static const auto NGX_SSL_KEY =
+    Line::build<_begin, _escape<_ssl_certificate_key>, _space, _capture<';'>, _end>();
+
+static const auto NGX_SSL_SESSION_CACHE =
+    Line::build<_begin, _escape<_ssl_session_cache>, _space, _capture<';'>, _end>();
+
+static const auto NGX_SSL_SESSION_TIMEOUT =
+    Line::build<_begin, _escape<_ssl_session_timeout>, _space, _capture<';'>, _end>();
+
+static const auto NGX_LISTEN = Line::build<_begin, _escape<_listen>, _space, _capture<';'>, _end>();
+
+static const auto NGX_PORT_80 = std::array<const char*, 2>{
+    R"(^\s*([^:]*:|\[[^\]]*\]:)?80(\s|$|;))",
+    "$01443 ssl$2",
+};
+
+static const auto NGX_PORT_443 = std::array<const char*, 2>{
+    R"(^\s*([^:]*:|\[[^\]]*\]:)?443(\s.*)?\sssl(\s|$|;))",
+    "$0180$2$3",
+};
+
+// ------------------------- implementation: ----------------------------------
+
+auto get_if_missed(const std::string& conf,
+                   const Line& LINE,
+                   const std::string& val,
+                   const std::string& indent,
+                   bool compare) -> std::string
+{
+    if (!compare || val.empty()) {
+        return rgx::regex_search(conf, LINE.RGX()) ? "" : LINE.STR(val, indent);
+    }
+
+    rgx::smatch match;  // assuming last capture has the value!
+
+    for (auto pos = conf.begin(); rgx::regex_search(pos, conf.end(), match, LINE.RGX());
+         pos += match.position(0) + match.length(0))
+    {
+        const std::string value = match.str(match.size() - 2);
+
+        if (value == val || value == "'" + val + "'" || value == '"' + val + '"') {
+            return "";
+        }
+    }
+
+    return LINE.STR(val, indent);
+}
+
+auto replace_if(const std::string& conf,
+                const rgx::regex& rgx,
+                const std::string& val,
+                const std::string& insert) -> std::string
+{
+    std::string ret{};
+    auto pos = conf.begin();
+
+    auto skip = 0;
+    for (rgx::smatch match; rgx::regex_search(pos, conf.end(), match, rgx);
+         pos += match.position(match.size() - 1))
+    {
+        auto i = match.size() - 2;
+        const std::string value = match.str(i);
+
+        bool compare = !val.empty();
+        if (compare && value != val && value != "'" + val + "'" && value != '"' + val + '"') {
+            ret.append(pos + skip, pos + match.position(i) + match.length(i));
+            skip = 0;
+        }
+        else {
+            ret.append(pos + skip, pos + match.position(match.size() > 2 ? 1 : 0));
+            ret += insert;
+            skip = 1;
+        }
+    }
+
+    ret.append(pos + skip, conf.end());
+    return ret;
+}
+
+auto replace_listen(const std::string& conf, const std::array<const char*, 2>& ngx_port)
+    -> std::string
+{
+    std::string ret{};
+    auto pos = conf.begin();
+
+    for (rgx::smatch match; rgx::regex_search(pos, conf.end(), match, NGX_LISTEN.RGX());
+         pos += match.position(match.size() - 1))
+    {
+        auto i = match.size() - 2;
+        ret.append(pos, pos + match.position(i));
+        ret += rgx::regex_replace(match.str(i), rgx::regex{ngx_port[0]}, ngx_port[1]);
+    }
+
+    ret.append(pos, conf.end());
+    return ret;
+}
+
+inline void add_ssl_directives_to(const std::string& name)
+{
+    const std::string prefix = std::string{CONF_DIR} + name;
+
+    const std::string const_conf = read_file(prefix + ".conf");
+
+    rgx::smatch match;  // captures str(1)=indentation spaces, str(2)=server name
+    for (auto pos = const_conf.begin();
+         rgx::regex_search(pos, const_conf.end(), match, NGX_SERVER_NAME.RGX());
+         pos += match.position(0) + match.length(0))
+    {
+        if (!contains(match.str(2), name)) {
+            continue;
+        }  // else:
+
+        const std::string indent = match.str(1);
+
+        auto adds = std::string{};
+
+        adds += get_if_missed(const_conf, NGX_SSL_CRT, prefix + ".crt", indent);
+
+        adds += get_if_missed(const_conf, NGX_SSL_KEY, prefix + ".key", indent);
+
+        adds += get_if_missed(const_conf, NGX_SSL_SESSION_CACHE, SSL_SESSION_CACHE_ARG(name),
+                              indent, false);
+
+        adds += get_if_missed(const_conf, NGX_SSL_SESSION_TIMEOUT,
+                              std::string{SSL_SESSION_TIMEOUT_ARG}, indent, false);
+
+        pos += match.position(0) + match.length(0);
+        std::string conf =
+            std::string(const_conf.begin(), pos) + adds + std::string(pos, const_conf.end());
+
+        conf = replace_if(conf, NGX_INCLUDE_LAN_LISTEN_DEFAULT.RGX(), "",
+                          NGX_INCLUDE_LAN_SSL_LISTEN_DEFAULT.STR("", indent));
+
+        conf = replace_if(conf, NGX_INCLUDE_LAN_LISTEN.RGX(), "",
+                          NGX_INCLUDE_LAN_SSL_LISTEN.STR("", indent));
+
+        conf = replace_listen(conf, NGX_PORT_80);
+
+        if (conf != const_conf) {
+            write_file(prefix + ".conf", conf);
+            std::cerr << "Added SSL directives to " << prefix << ".conf\n";
+        }
+
+        return;
+    }
+
+    auto errmsg = std::string{"add_ssl_directives_to error: "};
+    errmsg += "cannot add SSL directives to " + name + ".conf, missing: ";
+    errmsg += NGX_SERVER_NAME.STR(name, "\n    ") + "\n";
+    throw std::runtime_error(errmsg);
+}
+
+template <typename T>
+inline auto num2hex(T bytes) -> std::array<char, 2 * sizeof(bytes) + 1>
+{
+    constexpr auto n = 2 * sizeof(bytes);
+    std::array<char, n + 1> str{};
+
+    for (size_t i = 0; i < n; ++i) {
+        static const std::array<char, 17> hex{"0123456789ABCDEF"};
+        static constexpr auto get = 0x0fU;
+        str.at(i) = hex.at(bytes & get);
+
+        static constexpr auto move = 4U;
+        bytes >>= move;
+    }
+
+    str[n] = '\0';
+    return str;
+}
+
+template <typename T>
+inline auto get_nonce(const T salt = 0) -> T
+{
+    T nonce = 0;
+
+    std::ifstream urandom{"/dev/urandom"};
+
+    static constexpr auto move = 6U;
+
+    constexpr size_t steps = (sizeof(nonce) * 8 - 1) / move + 1;
+
+    for (size_t i = 0; i < steps; ++i) {
+        if (!urandom.good()) {
+            throw std::runtime_error("get_nonce error");
+        }
+        nonce = (nonce << move) + static_cast<unsigned>(urandom.get());
+    }
+
+    nonce ^= salt;
+
+    return nonce;
+}
+
+inline void create_ssl_certificate(const std::string& crtpath,
+                                   const std::string& keypath,
+                                   const int days = 792)
+{
+    size_t nonce = 0;
+
+    try {
+        nonce = get_nonce(nonce);
+    }
+
+    catch (...) {  // the address of a variable should be random enough:
+        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) sic:
+        nonce += reinterpret_cast<size_t>(&crtpath);
+    }
+
+    auto noncestr = num2hex(nonce);
+
+    const auto tmpcrtpath = crtpath + ".new-" + noncestr.data();
+    const auto tmpkeypath = keypath + ".new-" + noncestr.data();
+
+    try {
+        auto pkey = gen_eckey(NID_secp384r1);
+
+        write_key(pkey, tmpkeypath);
+
+        std::string subject{"/C=ZZ/ST=Somewhere/L=None/CN=OpenWrt/O=OpenWrt"};
+        subject += noncestr.data();
+
+        selfsigned(pkey, days, subject, tmpcrtpath);
+
+        static constexpr auto to_seconds = 24 * 60 * 60;
+        static constexpr auto leeway = 42;
+        if (!checkend(tmpcrtpath, days * to_seconds - leeway)) {
+            throw std::runtime_error("bug: created certificate is not valid!!");
+        }
+    }
+    catch (...) {
+        std::cerr << "create_ssl_certificate error: ";
+        std::cerr << "cannot create selfsigned certificate, ";
+        std::cerr << "removing temporary files ..." << std::endl;
+
+        if (remove(tmpcrtpath.c_str()) != 0) {
+            auto errmsg = "\t cannot remove " + tmpcrtpath;
+            perror(errmsg.c_str());
+        }
+
+        if (remove(tmpkeypath.c_str()) != 0) {
+            auto errmsg = "\t cannot remove " + tmpkeypath;
+            perror(errmsg.c_str());
+        }
+
+        throw;
+    }
+
+    if (rename(tmpcrtpath.c_str(), crtpath.c_str()) != 0 ||
+        rename(tmpkeypath.c_str(), keypath.c_str()) != 0)
+    {
+        auto errmsg = std::string{"create_ssl_certificate warning: "};
+        errmsg += "cannot move " + tmpcrtpath + " to " + crtpath;
+        errmsg += " or " + tmpkeypath + " to " + keypath + ", continuing ... ";
+        perror(errmsg.c_str());
+    }
+
+    std::cerr << "Created self-signed SSL certificate '" << crtpath;
+    std::cerr << "' with key '" << keypath << "'.\n";
+}
+
+auto check_ssl_certificate(const std::string& crtpath, const std::string& keypath) -> bool
+{
+    {  // paths are relative to dir:
+        auto dir = std::string_view{"/etc/nginx"};
+        auto crt_rel = crtpath[0] != '/';
+        auto key_rel = keypath[0] != '/';
+        if ((crt_rel || key_rel) && (chdir(dir.data()) != 0)) {
+            auto errmsg = std::string{"check_ssl_certificate error: entering "};
+            errmsg += dir;
+            perror(errmsg.c_str());
+            errmsg += " (need to change directory since the given ";
+            errmsg += crt_rel ? "ssl_certificate '" + crtpath : std::string{};
+            errmsg += crt_rel && key_rel ? "' and " : "";
+            errmsg += key_rel ? "ssl_certificate_key '" + keypath : std::string{};
+            errmsg += crt_rel && key_rel ? "' are" : "' is a";
+            errmsg += " relative path";
+            errmsg += crt_rel && key_rel ? "s)" : ")";
+            throw std::runtime_error(errmsg);
+        }
+    }
+
+    constexpr auto remaining_seconds = (365 + 32) * 24 * 60 * 60;
+    constexpr auto validity_days = 3 * (365 + 31);
+
+    bool is_valid = true;
+
+    if (access(keypath.c_str(), R_OK) != 0 || access(crtpath.c_str(), R_OK) != 0) {
+        is_valid = false;
+    }
+
+    else {
+        try {
+            if (!checkend(crtpath, remaining_seconds)) {
+                is_valid = false;
+            }
+        }
+        catch (...) {  // something went wrong, maybe it is in DER format:
+            try {
+                if (!checkend(crtpath, remaining_seconds, false)) {
+                    is_valid = false;
+                }
+            }
+            catch (...) {  // it has neither DER nor PEM format, rebuild.
+                is_valid = false;
+            }
+        }
+    }
+
+    if (!is_valid) {
+        create_ssl_certificate(crtpath, keypath, validity_days);
+    }
+
+    return is_valid;
+}
+
+auto contains(const std::string& sentence, const std::string& word) -> bool
+{
+    auto pos = sentence.find(word);
+    if (pos == std::string::npos) {
+        return false;
+    }
+    if (pos != 0 && (isgraph(sentence[pos - 1]) != 0)) {
+        return false;
+    }
+    if (isgraph(sentence[pos + word.size()]) != 0) {
+        return false;
+    }
+    // else:
+    return true;
+}
+
+auto get_uci_section_for_name(const std::string& name) -> uci::section
+{
+    auto pkg = uci::package{"nginx"};  // let it throw.
+
+    auto uci_enabled = is_enabled(pkg);
+
+    if (uci_enabled) {
+        for (auto sec : pkg) {
+            if (sec.name() == name) {
+                return sec;
+            }
+        }
+        // try interpreting 'name' as FQDN:
+        for (auto sec : pkg) {
+            for (auto opt : sec) {
+                if (opt.name() == "server_name") {
+                    for (auto itm : opt) {
+                        if (contains(itm.name(), name)) {
+                            return sec;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    auto errmsg = std::string{"lookup error: neither there is a file named '"};
+    errmsg += std::string{CONF_DIR} + name + ".conf' nor the UCI config has ";
+    if (uci_enabled) {
+        errmsg += "a nginx server with section name or 'server_name': " + name;
+    }
+    else {
+        errmsg += "been enabled by:\n\tuci set nginx.global.uci_enable=true";
+    }
+    throw std::runtime_error(errmsg);
+}
+
+inline auto add_ssl_to_config(const std::string& name,
+                              const std::string_view manage = "self-signed",
+                              const std::string_view crt = "",
+                              const std::string_view key = "")
+{
+    auto sec = get_uci_section_for_name(name);  // let it throw.
+    auto secname = sec.name();
+
+    struct {
+        std::string crt;
+        std::string key;
+    } ret;
+
+    std::cerr << "Adding SSL directives to UCI server: nginx." << secname << "\n";
+
+    std::cerr << "\t" << MANAGE_SSL << "='" << manage << "'\n";
+    sec.set(MANAGE_SSL.data(), manage.data());
+
+    if (!crt.empty() && !key.empty()) {
+        sec.set("ssl_certificate", crt.data());
+        std::cerr << "\tssl_certificate='" << crt << "'\n";
+        sec.set("ssl_certificate_key", key.data());
+        std::cerr << "\tssl_certificate_key='" << key << "'\n";
+    }
+
+    auto cache = false;
+    auto timeout = false;
+    for (auto opt : sec) {
+        if (opt.name() == "ssl_session_cache") {
+            cache = true;
+            continue;
+        }  // else:
+
+        if (opt.name() == "ssl_session_timeout") {
+            timeout = true;
+            continue;
+        }
+
+        // else:
+        for (auto itm : opt) {
+            if (opt.name() == "ssl_certificate_key") {
+                ret.key = itm.name();
+            }
+
+            else if (opt.name() == "ssl_certificate") {
+                ret.crt = itm.name();
+            }
+
+            else if (opt.name() == "listen") {
+                auto val = regex_replace(itm.name(), rgx::regex{NGX_PORT_80[0]}, NGX_PORT_80[1]);
+                if (val != itm.name()) {
+                    std::cerr << "\t" << opt.name() << "='" << val << "' (replacing)\n";
+                    itm.rename(val.c_str());
+                }
+            }
+        }
+    }
+
+    if (ret.crt.empty()) {
+        ret.crt = std::string{CONF_DIR} + name + ".crt";
+        std::cerr << "\tssl_certificate='" << ret.crt << "'\n";
+        sec.set("ssl_certificate", ret.crt.c_str());
+    }
+
+    if (ret.key.empty()) {
+        ret.key = std::string{CONF_DIR} + name + ".key";
+        std::cerr << "\tssl_certificate_key='" << ret.key << "'\n";
+        sec.set("ssl_certificate_key", ret.key.c_str());
+    }
+
+    if (!cache) {
+        std::cerr << "\tssl_session_cache='" << SSL_SESSION_CACHE_ARG(name) << "'\n";
+        sec.set("ssl_session_cache", SSL_SESSION_CACHE_ARG(name).data());
+    }
+
+    if (!timeout) {
+        std::cerr << "\tssl_session_timeout='" << SSL_SESSION_TIMEOUT_ARG << "'\n";
+        sec.set("ssl_session_timeout", SSL_SESSION_TIMEOUT_ARG.data());
+    }
+
+    sec.commit();
+
+    return ret;
+}
+
+void install_cron_job(const Line& CRON_LINE, const std::string& name)
+{
+    static const char* filename = "/etc/crontabs/root";
+
+    std::string conf{};
+    try {
+        conf = read_file(filename);
+    }
+    catch (const std::ifstream::failure&) { /* is ok if not found, create. */
+    }
+
+    const std::string add = get_if_missed(conf, CRON_LINE, name);
+
+    if (add.length() > 0) {
+#ifndef NO_UBUS
+        if (!ubus::call("service", "list", UBUS_TIMEOUT).filter("cron")) {
+            std::string errmsg{"install_cron_job error: "};
+            errmsg += "Cron unavailable to re-create the ssl certificate";
+            errmsg += (name.empty() ? std::string{"s\n"} : " for '" + name + "'\n");
+            throw std::runtime_error(errmsg);
+        }  // else active with or without instances:
+#endif
+
+        const auto* pre = (conf.length() == 0 || conf.back() == '\n' ? "" : "\n");
+        write_file(filename, pre + std::string{CRON_INTERVAL} + add, std::ios::app);
+
+#ifndef NO_UBUS
+        call("/etc/init.d/cron", "reload");
+#endif
+
+        std::cerr << "Rebuild the self-signed SSL certificate";
+        std::cerr << (name.empty() ? std::string{"s"} : " for '" + name + "'");
+        std::cerr << " annually with cron." << std::endl;
+    }
+}
+
+void add_ssl_if_needed(const std::string& name)
+{
+    const auto legacypath = std::string{CONF_DIR} + name + ".conf";
+    if (access(legacypath.c_str(), R_OK) == 0) {
+        add_ssl_directives_to(name);  // let it throw.
+
+        const auto crtpath = std::string{CONF_DIR} + name + ".crt";
+        const auto keypath = std::string{CONF_DIR} + name + ".key";
+        check_ssl_certificate(crtpath, keypath);  // let it throw.
+
+        try {
+            install_cron_job(CRON_CMD, name);
+        }
+        catch (...) {
+            std::cerr << "add_ssl_if_needed warning: cannot use cron to rebuild ";
+            std::cerr << "the self-signed SSL certificate for " << name << "\n";
+        }
+        return;
+    }  // else:
+
+    auto paths = add_ssl_to_config(name);  // let it throw.
+
+    check_ssl_certificate(paths.crt, paths.key);  // let it throw.
+
+    try {
+        install_cron_job(CRON_CHECK);
+    }
+    catch (...) {
+        std::cerr << "add_ssl_if_needed warning: cannot use cron to rebuild ";
+        std::cerr << "the self-signed SSL certificates.\n";
+    }
+}
+
+void add_ssl_if_needed(const std::string& name,
+                       const std::string_view manage,
+                       const std::string_view crt,
+                       const std::string_view key)
+{
+    if (crt[0] != '/') {
+        auto errmsg = std::string{"add_ssl_if_needed error: ssl_certificate "};
+        errmsg += "path cannot be relative '" + std::string{crt} + "'";
+        throw std::runtime_error(errmsg);
+    }
+
+    if (key[0] != '/') {
+        auto errmsg = std::string{"add_ssl_if_needed error: path to ssl_key "};
+        errmsg += "cannot be relative '" + std::string{key} + "'";
+        throw std::runtime_error(errmsg);
+    }
+
+    const auto legacypath = std::string{CONF_DIR} + name + ".conf";
+
+    if (access(legacypath.c_str(), R_OK) != 0) {
+        add_ssl_to_config(name, manage, crt, key);  // let it throw.
+        return;
+    }  // else:
+
+    // symlink crt+key to the paths that add_ssl_directives_to uses (if needed):
+
+    auto crtpath = std::string{CONF_DIR} + name + ".crt";
+    if (crtpath != crt && /* then */ symlink(crt.data(), crtpath.c_str()) != 0) {
+        auto errmsg = std::string{"add_ssl_if_needed error: cannot link "};
+        errmsg += "ssl_certificate " + crtpath + " -> " + crt.data() + " (";
+        errmsg += std::to_string(errno) + "): " + std::strerror(errno);
+        throw std::runtime_error(errmsg);
+    }
+
+    auto keypath = std::string{CONF_DIR} + name + ".key";
+    if (keypath != key && /* then */ symlink(key.data(), keypath.c_str()) != 0) {
+        auto errmsg = std::string{"add_ssl_if_needed error: cannot link "};
+        errmsg += "ssl_certificate_key " + keypath + " -> " + key.data() + " (";
+        errmsg += std::to_string(errno) + "): " + std::strerror(errno);
+        throw std::runtime_error(errmsg);
+    }
+
+    add_ssl_directives_to(name);  // let it throw.
+}
+
+void remove_cron_job(const Line& CRON_LINE, const std::string& name)
+{
+    static const char* filename = "/etc/crontabs/root";
+
+    const auto const_conf = read_file(filename);
+
+    bool changed = false;
+    auto conf = std::string{};
+
+    size_t prev = 0;
+    size_t curr = 0;
+    while ((curr = const_conf.find('\n', prev)) != std::string::npos) {
+        auto line = const_conf.substr(prev, curr - prev + 1);
+
+        if (line == replace_if(line, CRON_LINE.RGX(), name, "")) {
+            conf += line;
+        }
+        else {
+            changed = true;
+        }
+
+        prev = curr + 1;
+    }
+
+    if (changed) {
+        write_file(filename, conf);
+
+        std::cerr << "Do not rebuild the self-signed SSL certificate";
+        std::cerr << (name.empty() ? std::string{"s"} : " for '" + name + "'");
+        std::cerr << " annually with cron anymore." << std::endl;
+
+#ifndef NO_UBUS
+        if (ubus::call("service", "list", UBUS_TIMEOUT).filter("cron")) {
+            call("/etc/init.d/cron", "reload");
+        }
+#endif
+    }
+}
+
+inline void del_ssl_directives_from(const std::string& name)
+{
+    const std::string prefix = std::string{CONF_DIR} + name;
+
+    const std::string const_conf = read_file(prefix + ".conf");
+
+    rgx::smatch match;  // captures str(1)=indentation spaces, str(2)=server name
+    for (auto pos = const_conf.begin();
+         rgx::regex_search(pos, const_conf.end(), match, NGX_SERVER_NAME.RGX());
+         pos += match.position(0) + match.length(0))
+    {
+        if (!contains(match.str(2), name)) {
+            continue;
+        }  // else:
+
+        const std::string indent = match.str(1);
+
+        std::string conf = const_conf;
+
+        conf = replace_listen(conf, NGX_PORT_443);
+
+        conf = replace_if(conf, NGX_INCLUDE_LAN_SSL_LISTEN_DEFAULT.RGX(), "",
+                          NGX_INCLUDE_LAN_LISTEN_DEFAULT.STR("", indent));
+
+        conf = replace_if(conf, NGX_INCLUDE_LAN_SSL_LISTEN.RGX(), "",
+                          NGX_INCLUDE_LAN_LISTEN.STR("", indent));
+
+        // NOLINTNEXTLINE(performance-inefficient-string-concatenation) prefix:
+        conf = replace_if(conf, NGX_SSL_CRT.RGX(), prefix + ".crt", "");
+
+        // NOLINTNEXTLINE(performance-inefficient-string-concatenation) prefix:
+        conf = replace_if(conf, NGX_SSL_KEY.RGX(), prefix + ".key", "");
+
+        conf = replace_if(conf, NGX_SSL_SESSION_CACHE.RGX(), "", "");
+
+        conf = replace_if(conf, NGX_SSL_SESSION_TIMEOUT.RGX(), "", "");
+
+        if (conf != const_conf) {
+            write_file(prefix + ".conf", conf);
+            std::cerr << "Deleted SSL directives from " << prefix << ".conf\n";
+        }
+
+        return;
+    }
+
+    auto errmsg = std::string{"del_ssl_directives_from error: "};
+    errmsg += "cannot delete SSL directives from " + name + ".conf, missing: ";
+    errmsg += NGX_SERVER_NAME.STR(name, "\n    ") + "\n";
+    throw std::runtime_error(errmsg);
+}
+
+inline auto del_ssl_from_config(const std::string& name,
+                                const std::string_view manage = "self-signed")
+{
+    auto sec = get_uci_section_for_name(name);  // let it throw.
+    auto secname = sec.name();
+
+    struct {
+        std::string crt;
+        std::string key;
+    } ret;
+
+    std::cerr << "Deleting SSL directives from UCI server: nginx." << secname << "\n";
+
+    auto manage_match = false;
+    for (auto opt : sec) {
+        for (auto itm : opt) {
+            if (opt.name() == "ssl_certificate_key") {
+                ret.key = itm.name();
+            }
+
+            else if (opt.name() == "ssl_certificate") {
+                ret.crt = itm.name();
+            }
+
+            else if (opt.name() == "ssl_session_cache" || opt.name() == "ssl_session_timeout") {
+            }
+
+            else if (opt.name() == MANAGE_SSL && itm.name() == manage) {
+                manage_match = true;
+            }
+
+            else if (opt.name() == "listen") {
+                auto val = regex_replace(itm.name(), rgx::regex{NGX_PORT_443[0]}, NGX_PORT_443[1]);
+                if (val != itm.name()) {
+                    std::cerr << "\t" << opt.name() << " (set back to '" << val << "')\n";
+                    itm.rename(val.c_str());
+                }
+                continue; /* not deleting opt, look at other itm : opt */
+            }
+
+            else {
+                continue; /* not deleting opt, look at other itm : opt */
+            }
+
+            // Delete matching opt (not skipped by continue):
+            std::cerr << "\t" << opt.name() << " (was '" << itm.name() << "')\n";
+            opt.del();
+            break;
+        }
+    }
+    if (manage_match) {
+        sec.commit();
+        return ret;
+    }  // else:
+
+    auto errmsg = std::string{"del_ssl error: not changing config wihtout: "};
+    errmsg += "uci set nginx." + secname + "." + MANAGE_SSL.data() + "='" + manage.data();
+    errmsg += "'";
+    throw std::runtime_error(errmsg);
+}
+
+auto del_ssl_legacy(const std::string& name) -> bool
+{
+    const auto legacypath = std::string{CONF_DIR} + name + ".conf";
+
+    if (access(legacypath.c_str(), R_OK) != 0) {
+        return false;
+    }
+
+    try {
+        remove_cron_job(CRON_CMD, name);
+    }
+    catch (...) {
+        std::cerr << "del_ssl warning: cannot remove cron job rebuilding ";
+        std::cerr << "the self-signed SSL certificate for " << name << "\n";
+    }
+
+    try {
+        del_ssl_directives_from(name);
+    }
+    catch (...) {
+        std::cerr << "del_ssl error: ";
+        std::cerr << "cannot delete SSL directives from " << name << ".conf\n";
+        throw;
+    }
+
+    return true;
+}
+
+void del_ssl(const std::string& name)
+{
+    auto crtpath = std::string{};
+    auto keypath = std::string{};
+
+    if (del_ssl_legacy(name)) {  // let it throw.
+        crtpath = std::string{CONF_DIR} + name + ".crt";
+        keypath = std::string{CONF_DIR} + name + ".key";
+    }
+
+    else {
+        auto paths = del_ssl_from_config(name);  // let it throw.
+        crtpath = paths.crt;
+        keypath = paths.key;
+    }
+
+    if (remove(crtpath.c_str()) != 0) {
+        auto errmsg = "del_ssl warning: cannot remove " + crtpath;
+        perror(errmsg.c_str());
+    }
+
+    if (remove(keypath.c_str()) != 0) {
+        auto errmsg = "del_ssl warning: cannot remove " + keypath;
+        perror(errmsg.c_str());
+    }
+}
+
+void del_ssl(const std::string& name, const std::string_view manage)
+{
+    const auto legacypath = std::string{CONF_DIR} + name + ".conf";
+
+    if (access(legacypath.c_str(), R_OK) != 0) {
+        del_ssl_from_config(name, manage);  // let it throw.
+        return;
+    }  // else:
+
+    del_ssl_directives_from(name);  // let it throw.
+
+    for (const auto* ext : {".crt", ".key"}) {
+        struct stat sb {};
+
+        auto path = std::string{CONF_DIR} + name + ext;
+
+        // managed version of add_ssl_if_needed created symlinks (if needed):
+        // NOLINTNEXTLINE(hicpp-signed-bitwise) S_ISLNK macro:
+        if (lstat(path.c_str(), &sb) == 0 && S_ISLNK(sb.st_mode)) {
+            if (remove(path.c_str()) != 0) {
+                auto errmsg = "del_ssl warning: cannot remove " + path;
+                perror(errmsg.c_str());
+            }
+        }
+    }
+}
+
+auto check_ssl(const uci::package& pkg, bool is_enabled) -> bool
+{
+    auto are_valid = true;
+    auto is_enabled_and_at_least_one_has_manage_ssl = false;
+
+    if (is_enabled) {
+        for (auto sec : pkg) {
+            if (sec.anonymous() || sec.type() != "server") {
+                continue;
+            }  // else:
+
+            const auto legacypath = std::string{CONF_DIR} + sec.name() + ".conf";
+            if (access(legacypath.c_str(), R_OK) == 0) {
+                continue;
+            }  // else:
+
+            auto keypath = std::string{};
+            auto crtpath = std::string{};
+            auto self_signed = false;
+
+            for (auto opt : sec) {
+                for (auto itm : opt) {
+                    if (opt.name() == "ssl_certificate_key") {
+                        keypath = itm.name();
+                    }
+
+                    else if (opt.name() == "ssl_certificate") {
+                        crtpath = itm.name();
+                    }
+
+                    else if (opt.name() == MANAGE_SSL) {
+                        if (itm.name() == "self-signed") {
+                            self_signed = true;
+                        }
+
+                        // else if (itm.name()=="???") { /* manage other */ }
+
+                        else {
+                            continue;
+                        }  // no supported manage_ssl string.
+
+                        is_enabled_and_at_least_one_has_manage_ssl = true;
+                    }
+                }
+            }
+
+            if (self_signed && !crtpath.empty() && !keypath.empty()) {
+                try {
+                    if (!check_ssl_certificate(crtpath, keypath)) {
+                        are_valid = false;
+                    }
+                }
+                catch (...) {
+                    std::cerr << "check_ssl warning: cannot build certificate '";
+                    std::cerr << crtpath << "' or key '" << keypath << "'.\n";
+                }
+            }
+        }
+    }
+
+    auto suffix = std::string_view{" the cron job checking the managed SSL certificates.\n"};
+
+    if (is_enabled_and_at_least_one_has_manage_ssl) {
+        try {
+            install_cron_job(CRON_CHECK);
+        }
+        catch (...) {
+            std::cerr << "check_ssl warning: cannot install" << suffix;
+        }
+    }
+
+    else if (access("/etc/crontabs/root", R_OK) == 0) {
+        try {
+            remove_cron_job(CRON_CHECK);
+        }
+        catch (...) {
+            std::cerr << "check_ssl warning: cannot remove" << suffix;
+        }
+    }  // else: do nothing
+
+    return are_valid;
+}
+
+#endif
