X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=include%2Fmodules%2Fssl.h;h=edea45a1092e73e787d7b9bcc376de023a26f3c9;hb=79892a727e323dcc4bce7e9c0cf3c99c5fe61706;hp=25076215ac5b4e5e5913e2dfbb3ba52c6c372715;hpb=1031f333332cf1b09db4fd632f141143ee637c34;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/modules/ssl.h b/include/modules/ssl.h index 25076215a..edea45a10 100644 --- a/include/modules/ssl.h +++ b/include/modules/ssl.h @@ -112,9 +112,21 @@ class ssl_cert : public refcountbase return revoked; } + /** Get certificate usability + * @return True if the certificate is not expired nor revoked + */ + bool IsUsable() + { + return !invalid && !revoked && error.empty(); + } + + /** Get CA trust status + * @return True if the certificate is issued by a CA + * and valid. + */ bool IsCAVerified() { - return trusted && !invalid && !revoked && !unknownsigner && error.empty(); + return IsUsable() && trusted && !unknownsigner; } std::string GetMetaLine() @@ -133,32 +145,86 @@ class ssl_cert : public refcountbase class SSLIOHook : public IOHook { + protected: + /** Peer SSL certificate, set by the SSL module + */ + reference certificate; + + /** Reduce elements in a send queue by appending later elements to the first element until there are no more + * elements to append or a desired length is reached + * @param sendq SendQ to work on + * @param targetsize Target size of the front element + */ + static void FlattenSendQueue(StreamSocket::SendQueue& sendq, size_t targetsize) + { + if ((sendq.size() <= 1) || (sendq.front().length() >= targetsize)) + return; + + // Avoid multiple repeated SSL encryption invocations + // This adds a single copy of the queue, but avoids + // much more overhead in terms of system calls invoked + // by an IOHook. + std::string tmp; + tmp.reserve(std::min(targetsize, sendq.bytes())+1); + do + { + tmp.append(sendq.front()); + sendq.pop_front(); + } + while (!sendq.empty() && tmp.length() < targetsize); + sendq.push_front(tmp); + } + public: - SSLIOHook(Module* mod, const std::string& Name) - : IOHook(mod, Name, IOHook::IOH_SSL) + static SSLIOHook* IsSSL(StreamSocket* sock) + { + IOHook* const iohook = sock->GetIOHook(); + if ((iohook) && ((iohook->prov->type == IOHookProvider::IOH_SSL))) + return static_cast(iohook); + return NULL; + } + + SSLIOHook(IOHookProvider* hookprov) + : IOHook(hookprov) { } /** - * Get the client certificate from a socket - * @param sock The socket to get the certificate from, must be using this IOHook - * @return The SSL client certificate information + * Get the certificate sent by this peer + * @return The SSL certificate sent by the peer, NULL if no cert was sent */ - virtual ssl_cert* GetCertificate(StreamSocket* sock) = 0; + ssl_cert* GetCertificate() const + { + if (certificate && certificate->IsUsable()) + return certificate; + return NULL; + } /** - * Get the fingerprint of a client certificate from a socket - * @param sock The socket to get the certificate fingerprint from, must be using this IOHook + * Get the fingerprint of the peer's certificate * @return The fingerprint of the SSL client certificate sent by the peer, * empty if no cert was sent */ - std::string GetFingerprint(StreamSocket* sock) + std::string GetFingerprint() const { - ssl_cert* cert = GetCertificate(sock); + ssl_cert* cert = GetCertificate(); if (cert) return cert->GetFingerprint(); return ""; } + + /** + * Get the ciphersuite negotiated with the peer + * @param out String where the ciphersuite string will be appended to + */ + virtual void GetCiphersuite(std::string& out) const = 0; + + + /** Retrieves the name of the SSL connection which is sent via SNI. + * @param out String that the server name will be appended to. + * returns True if the server name was retrieved; otherwise, false. + */ + virtual bool GetServerName(std::string& out) const = 0; }; /** Helper functions for obtaining SSL client certificates and key fingerprints @@ -174,12 +240,11 @@ class SSLClientCert */ static ssl_cert* GetCertificate(StreamSocket* sock) { - IOHook* iohook = sock->GetIOHook(); - if ((!iohook) || (iohook->type != IOHook::IOH_SSL)) + SSLIOHook* ssliohook = SSLIOHook::IsSSL(sock); + if (!ssliohook) return NULL; - SSLIOHook* ssliohook = static_cast(iohook); - return ssliohook->GetCertificate(sock); + return ssliohook->GetCertificate(); } /** @@ -212,6 +277,12 @@ class UserCertificateAPIBase : public DataProvider */ virtual ssl_cert* GetCertificate(User* user) = 0; + /** Set the SSL certificate of a user. + * @param user The user whose certificate to set. + * @param cert The SSL certificate to set for the user. + */ + virtual void SetCertificate(User* user, ssl_cert* cert) = 0; + /** Get the key fingerprint from a user's certificate * @param user The user whose key fingerprint to get, user may be remote * @return The key fingerprint from the user's SSL certificate or an empty string