]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ssl/bio.h
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / ssl / bio.h
index 4b05235bb511efc4445c91e78cef3f485415c27f..22335b8a3bbe4159f624b3374f9512082866c6cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -9,9 +9,14 @@
 #ifndef SQUID_SSL_BIO_H
 #define SQUID_SSL_BIO_H
 
+#if USE_OPENSSL
+
+#include "compat/openssl.h"
+#include "FadingCounter.h"
 #include "fd.h"
-#include "sbuf/SBuf.h"
+#include "MemBuf.h"
 #include "security/Handshake.h"
+#include "ssl/support.h"
 
 #include <iosfwd>
 #include <list>
@@ -28,11 +33,6 @@ namespace Ssl
 class Bio
 {
 public:
-    enum Type {
-        BIO_TO_CLIENT = 6000,
-        BIO_TO_SERVER
-    };
-
     explicit Bio(const int anFd);
     virtual ~Bio();
 
@@ -54,11 +54,11 @@ public:
 
     /// Creates a low-level BIO table, creates a high-level Ssl::Bio object
     /// for a given socket, and then links the two together via BIO_C_SET_FD.
-    static BIO *Create(const int fd, Type type);
+    static BIO *Create(const int fd, Security::Io::Type type);
     /// Tells ssl connection to use BIO and monitor state via stateChanged()
     static void Link(SSL *ssl, BIO *bio);
 
-    const SBuf &rBufData() {return rbuf;}
+    const SBuf &rBufData() {return rbuf;} ///< The buffered input data
 protected:
     const int fd_; ///< the SSL socket we are reading and writing
     SBuf rbuf;  ///< Used to buffer input data.
@@ -70,7 +70,7 @@ protected:
 class ClientBio: public Bio
 {
 public:
-    explicit ClientBio(const int anFd): Bio(anFd), holdRead_(false), holdWrite_(false), helloSize(0)/*, wrongProtocol(false)*/ {}
+    explicit ClientBio(const int anFd);
 
     /// The ClientBio version of the Ssl::Bio::stateChanged method
     /// When the client hello message retrieved, fill the
@@ -84,13 +84,25 @@ public:
     virtual int read(char *buf, int size, BIO *table);
     /// Prevents or allow writting on socket.
     void hold(bool h) {holdRead_ = holdWrite_ = h;}
+
+    /// Sets the buffered input data (Bio::rbuf).
+    /// Used to pass payload data (normally client HELLO data) retrieved
+    /// by the caller.
     void setReadBufData(SBuf &data) {rbuf = data;}
 private:
-    /// True if the SSL state corresponds to a hello message
-    bool isClientHello(int state);
+    /// approximate size of a time window for computing client-initiated renegotiation rate (in seconds)
+    static const time_t RenegotiationsWindow = 10;
+
+    /// the maximum tolerated number of client-initiated renegotiations in RenegotiationsWindow
+    static const int RenegotiationsLimit = 5;
+
     bool holdRead_; ///< The read hold state of the bio.
     bool holdWrite_;  ///< The write hold state of the bio.
     int helloSize; ///< The SSL hello message sent by client size
+    FadingCounter renegotiations; ///< client requested renegotiations limit control
+
+    /// why we should terminate the connection during next TLS operation (or nil)
+    const char *abortReason;
 };
 
 /// BIO node to handle socket IO for squid server side
@@ -111,7 +123,8 @@ private:
 class ServerBio: public Bio
 {
 public:
-    explicit ServerBio(const int anFd): Bio(anFd), helloMsgSize(0), helloBuild(false), allowSplice(false), allowBump(false), holdWrite_(false), record_(false), bumpMode_(bumpNone), rbufConsumePos(0) {}
+    explicit ServerBio(const int anFd);
+
     /// The ServerBio version of the Ssl::Bio::stateChanged method
     virtual void stateChanged(const SSL *ssl, int where, int ret);
     /// The ServerBio version of the Ssl::Bio::write method
@@ -134,6 +147,10 @@ public:
     bool holdWrite() const {return holdWrite_;}
     /// Enables or disables the write hold state
     void holdWrite(bool h) {holdWrite_ = h;}
+    /// The read hold state
+    bool holdRead() const {return holdRead_;}
+    /// Enables or disables the read hold state
+    void holdRead(bool h) {holdRead_ = h;}
     /// Enables or disables the input data recording, for internal analysis.
     void recordInput(bool r) {record_ = r;}
     /// Whether we can splice or not the SSL stream
@@ -144,10 +161,17 @@ public:
     void mode(Ssl::BumpMode m) {bumpMode_ = m;}
     Ssl::BumpMode bumpMode() {return bumpMode_;} ///< return the bumping mode
 
-    /// Return the TLS Details advertised by TLS server.
-    const Security::TlsDetails::Pointer &receivedHelloDetails() const {return parser_.details;}
+    /// \retval true if the Server hello message received
+    bool gotHello() const { return (parsedHandshake && !parseError); }
+
+    /// Return true if the Server Hello parsing failed
+    bool gotHelloFailed() const { return (parsedHandshake && parseError); }
 
-    const Ssl::X509_STACK_Pointer &serverCertificatesIfAny() { return parser_.serverCertificates; } /* XXX: may be nil */
+    /// \return the server certificates list if received and parsed correctly
+    const Security::CertList &serverCertificatesIfAny() { return parser_.serverCertificates; }
+
+    /// \return the TLS Details advertised by TLS server.
+    const Security::TlsDetails::Pointer &receivedHelloDetails() const {return parser_.details;}
 
 private:
     int readAndGive(char *buf, const int size, BIO *table);
@@ -158,19 +182,22 @@ private:
     /// SSL client features extracted from ClientHello message or SSL object
     Security::TlsDetails::Pointer clientTlsDetails;
     /// TLS client hello message, used to adapt our tls Hello message to the server
-    SBuf clientHelloMessage;
+    SBuf clientSentHello;
     SBuf helloMsg; ///< Used to buffer output data.
     mb_size_t  helloMsgSize;
     bool helloBuild; ///< True if the client hello message sent to the server
     bool allowSplice; ///< True if the SSL stream can be spliced
     bool allowBump;  ///< True if the SSL stream can be bumped
     bool holdWrite_;  ///< The write hold state of the bio.
+    bool holdRead_;  ///< The read hold state of the bio.
     bool record_; ///< If true the input data recorded to rbuf for internal use
+    bool parsedHandshake; ///< whether we are done parsing TLS Hello
+    bool parseError; ///< error while parsing server hello message
     Ssl::BumpMode bumpMode_;
 
-    ///< The size of data stored in rbuf which passed to the openSSL
+    /// The size of data stored in rbuf which passed to the openSSL
     size_t rbufConsumePos;
-    Security::HandshakeParser parser_; ///< The SSL messages parser.
+    Security::HandshakeParser parser_; ///< The TLS/SSL messages parser.
 };
 
 } // namespace Ssl
@@ -178,5 +205,6 @@ private:
 void
 applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode);
 
+#endif /* USE_OPENSSL */
 #endif /* SQUID_SSL_BIO_H */