]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Handle resummed sessions
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 5 Nov 2015 18:20:01 +0000 (20:20 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 5 Nov 2015 18:20:01 +0000 (20:20 +0200)
On resumed sessions the SSL server will send a "Change Cipher Spec Protocol"
message instead of Certificates message.
After the CCS protocol message received we waiting an Finished SSL handshake
message. However this message may received encrypted and we can not decrypt it
in order to parse it correctly.

This patch after the CCS message received finishes parsing.

However maybe still messages from server must received and appended to
ServerBio::rbuf in order to sent later on SSL client in the case of splice.

This patch get back the ServerBio::record_ mechanism which is enabled/disabled
by the caller Ssl::PeekingPeerConnector class. The ServerBio code writes to
ServerBio::rbuf buffer as long as the ServerBio::record_ flag is set to true
by the Ssl::PeekingPeerConnector.

src/ssl/PeerConnector.cc
src/ssl/bio.cc
src/ssl/bio.h

index 6e7e8457062afd4aa5a4f3fe29a35f902ec207c4..a2967510fb841e12c141e561a0886f8ad63bc2a6 100644 (file)
@@ -278,6 +278,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti
         clientConn->close();
     } else if (finalAction != Ssl::bumpSplice) {
         //Allow write, proceed with the connection
+        srvBio->recordInput(false);
         srvBio->holdWrite(false);
         debugs(83,5, "Retry the fwdNegotiateSSL on FD " << serverConn->fd);
         Ssl::PeerConnector::noteWantWrite();
@@ -685,7 +686,7 @@ Ssl::PeerConnector::checkForMissingCertificates ()
     Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
     const Ssl::X509_STACK_Pointer &certs = srvBio->serverCertificates();
 
-    if (sk_X509_num(certs.get())) {
+    if (certs.get() && sk_X509_num(certs.get())) {
         debugs(83, 5, "SSL server sent " << sk_X509_num(certs.get()) << " certificates");
         Ssl::missingChainCertificatesUrls(urlsOfMissingCerts, certs);
         if (urlsOfMissingCerts.size()) {
@@ -819,6 +820,7 @@ Ssl::PeekingPeerConnector::initializeSsl()
                     Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
                     // Inherite client features, like SSL version, SNI and other
                     srvBio->setClientFeatures(features);
+                    srvBio->recordInput(true);
                     srvBio->mode(csd->sslBumpMode);
                 }
             }
index 93474a24a43476d9355d0c635f2df389da3a9215..f46340262045410851921c6b6b784080081dcf66 100644 (file)
@@ -529,9 +529,9 @@ Ssl::ServerBio::readAndBufferServerHelloMsg(BIO *table, const char *description)
 int
 Ssl::ServerBio::read(char *buf, int size, BIO *table)
 {
-    if (parser_.state < Ssl::HandshakeParser::atHelloDoneReceived) {
+    if (!parser_.parseDone || record_) {
         int ret = readAndBufferServerHelloMsg(table, "TLS server Hello");
-        if (ret <= 0)
+        if (!rbuf.contentSize() && parser_.parseDone && ret <= 0)
             return ret;
     }
 
@@ -1470,9 +1470,11 @@ Ssl::HandshakeParser::parseChangeCipherCpecMessage()
 {
     Must(currentContentType == Rfc5246::ContentType::ctChangeCipherSpec);
     // we are currently ignoring Change Cipher Spec Protocol messages
-    // XXX: everything after this message is going to be encrypted, right?
-    // If so, then continuing parsing is pointless.
+    // Everything after this message may be is encrypted
+    // The continuing parsing is pointless, abort here and set parseDone
     skipMessage("ChangeCipherCpec msg");
+    ressumingSession = true;
+    parseDone = true;
 }
 
 void
index b3bf4781e8300b497451e1d07de379837c04524c..af4dafaf005031dae9b1b642844228e31e184ab2 100644 (file)
@@ -383,7 +383,7 @@ private:
 class ServerBio: public Bio
 {
 public:
-    explicit ServerBio(const int anFd): Bio(anFd), helloMsgSize(0), helloBuild(false), allowSplice(false), allowBump(false), holdWrite_(false), holdRead_(true), bumpMode_(bumpNone), rbufConsumePos(0) {}
+    explicit ServerBio(const int anFd): Bio(anFd), helloMsgSize(0), helloBuild(false), allowSplice(false), allowBump(false), holdWrite_(false), holdRead_(true), record_(false), bumpMode_(bumpNone), rbufConsumePos(0) {}
     /// 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
@@ -414,6 +414,8 @@ public:
     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
     bool canSplice() {return allowSplice;}
     /// Whether we can bump or not the SSL stream
@@ -439,6 +441,7 @@ private:
     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
     Ssl::BumpMode bumpMode_;
 
     ///< The size of data stored in rbuf which passed to the openSSL