Commit 6139e49d authored by jan.koester's avatar jan.koester
Browse files

test

parent af2802e7
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -2265,6 +2265,34 @@ libhttppp::HttpD::HttpD(const std::string& httpaddr, int port,int maxconnections
    }
}

libhttppp::HttpD::HttpD(const std::string &httpaddr, int port, int maxconnections,
                         const std::map<std::string, netplus::ssl::CertificateBundle> &certsByHostname) {
    try {
        _fileServer = false;
        if (certsByHostname.empty()) {
            _httpexception[HTTPException::Critical] << "HttpD SNI ctor requires at least one hostname->cert entry";
            throw _httpexception;
        }
        _certBundle = certsByHostname;
        for (auto &[hostname, bundle] : _certBundle) {
            if (!bundle.cert.checkValidity()) {
                time_t now = time(nullptr);
                _httpexception[HTTPException::Critical] << "invalid certfile for hostname " << hostname
                    << " (CN=" << bundle.cert.getSubjectCN() << ", system_time=" << now << ")";
                throw _httpexception;
            }
        }
        auto tss = std::make_unique<netplus::ssl>(_certBundle, httpaddr, port, maxconnections, -1);
        auto qss = std::make_unique<netplus::quic>(_certBundle, httpaddr, port, maxconnections, -1);
        _ServerSockets.push_back(std::move(tss));
        _ServerSockets.push_back(std::move(qss));
    } catch (netplus::NetException &e) {
        HTTPException ee;
        ee[HTTPException::Critical] << e.what();
        throw ee;
    }
}

std::vector<netplus::socket*> libhttppp::HttpD::getServerSockets(){
    std::vector<netplus::socket*> sockets;
    for (auto &sock : _ServerSockets) {
@@ -2298,5 +2326,29 @@ bool libhttppp::HttpD::reloadCertificates(const std::string &certpath, const std
    return true;
}

bool libhttppp::HttpD::reloadCertificate(const std::string &hostname, const std::string &certpath,
                                          const std::string &keypath, const std::string &password) {
    netplus::ssl::CertificateBundle bundle;
    if (!bundle.loadFromFile(certpath, keypath, password)) {
        return false;
    }
    if (!bundle.cert.checkValidity()) {
        return false;
    }

    // Unlike reloadCertificates() above, only this one hostname's entry is replaced -- every
    // other hostname bound to this listener keeps its own, unrelated certificate.
    _certBundle[hostname] = bundle;

    for (auto &sock : _ServerSockets) {
        if (auto *s = dynamic_cast<netplus::ssl*>(sock.get())) {
            s->setCertificates(_certBundle);
        } else if (auto *q = dynamic_cast<netplus::quic*>(sock.get())) {
            q->setCertificates(_certBundle);
        }
    }
    return true;
}

libhttppp::HttpD::~HttpD(){
}
+11 −0
Original line number Diff line number Diff line
@@ -186,11 +186,22 @@ namespace libhttppp {
    public:
        HttpD(int argc, char** argv);
        HttpD(const std::string &httpaddr, int port, int maxconnections, const std::string &sslcertpath, const  std::string &sslkeypath, const std::string &sslpassword = "");
        // SNI virtual hosting: certsByHostname is keyed by the SNI hostname each bundle should
        // be presented for (unlike the single-cert ctor above, whose _certBundle ends up keyed
        // by httpaddr) -- netplus::ssl/quic pick a bundle per-connection from this map by
        // matching the ClientHello's requested hostname, see netplus::tls::cert_map.
        HttpD(const std::string &httpaddr, int port, int maxconnections,
              const std::map<std::string, netplus::ssl::CertificateBundle> &certsByHostname);
        ~HttpD();
        std::vector<netplus::socket*> getServerSockets();

        // Reload SSL certificates from file(s). Updates all ssl/quic server sockets.
        bool reloadCertificates(const std::string &certpath, const std::string &keypath, const std::string &password = "");

        // Reload just one SNI hostname's bundle (for a multi-hostname HttpD from the ctor
        // above) without disturbing any other hostname's certificate.
        bool reloadCertificate(const std::string &hostname, const std::string &certpath,
                                const std::string &keypath, const std::string &password = "");
    protected:
        void                        FileServer();
    private: