/*
- * 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.
#ifndef SQUID_SSL_BIO_H
#define SQUID_SSL_BIO_H
+#if USE_OPENSSL
+
+#include "compat/openssl.h"
+#include "FadingCounter.h"
#include "fd.h"
+#include "MemBuf.h"
#include "security/Handshake.h"
+#include "ssl/support.h"
#include <iosfwd>
#include <list>
class Bio
{
public:
- enum Type {
- BIO_TO_CLIENT = 6000,
- BIO_TO_SERVER
- };
-
explicit Bio(const int anFd);
virtual ~Bio();
/// 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);
class ClientBio: public Bio
{
public:
- explicit ClientBio(const int anFd): Bio(anFd), holdRead_(false), holdWrite_(false), helloSize(0) {}
+ explicit ClientBio(const int anFd);
/// The ClientBio version of the Ssl::Bio::stateChanged method
/// When the client hello message retrieved, fill the
/// 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
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
void mode(Ssl::BumpMode m) {bumpMode_ = m;}
Ssl::BumpMode bumpMode() {return bumpMode_;} ///< return the bumping mode
+ /// \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); }
+
+ /// \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;}
/// 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
void
applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode);
+#endif /* USE_OPENSSL */
#endif /* SQUID_SSL_BIO_H */