]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Restrict the number of downloaded certificates and the nested certificates
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 6 Nov 2015 12:50:21 +0000 (14:50 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 6 Nov 2015 12:50:21 +0000 (14:50 +0200)
downloads per SSL connection

- Do not allow more than Ssl::PeerConnector::MaxCertsDownloads downloaded
  certificates for each SSL connection. This variable set to 10 for now.
- Restrict the number of nested certificates downloads. For example
  when the certificate located in an SSL site which requires to download a
  a missing certificate (... from an SSL site which requires to download a
  missing certificate )*

src/Downloader.cc
src/Downloader.h
src/ssl/PeerConnector.cc
src/ssl/PeerConnector.h

index 2571683788e9bd7757d4011f3a078c6762b1dae4..8d5312bd1f6604eeaa35ba5a0c55099433c8d8bc 100644 (file)
@@ -7,12 +7,13 @@
 
 CBDATA_CLASS_INIT(Downloader);
 
-Downloader::Downloader(SBuf &url, const MasterXaction::Pointer &xact, AsyncCall::Pointer &aCallback):
+Downloader::Downloader(SBuf &url, const MasterXaction::Pointer &xact, AsyncCall::Pointer &aCallback, unsigned int level):
     AsyncJob("Downloader"),
     ConnStateData(xact),
     url_(url),
     callback(aCallback),
-    status(Http::scNone)
+    status(Http::scNone),
+    level_(level)
 {
     maxObjectSize = 512*1024;
 }
index a698b60411587e01c83ddc2a1d1aabaec809bb6c..aad8e174cee31f722698e801e932d1ea36d11f9b 100644 (file)
@@ -19,9 +19,12 @@ public:
         Http::StatusCode status;
     };
 
-    explicit Downloader(SBuf &url, const MasterXaction::Pointer &xact, AsyncCall::Pointer &aCallback);
+    explicit Downloader(SBuf &url, const MasterXaction::Pointer &xact, AsyncCall::Pointer &aCallback, unsigned int level = 0);
     virtual ~Downloader();
     void downloadFinished();
+
+    /// The nested level of Downloader object (downloads inside downloads)
+    unsigned int nestedLevel() const {return level_;}
     
     /* ConnStateData API */
     virtual bool isOpen() const;
@@ -52,6 +55,7 @@ private:
     Http::StatusCode status;
     SBuf object; //object data
     size_t maxObjectSize;
+    unsigned int level_; ///< Holds the nested downloads level
 };
 
 #endif
index a2967510fb841e12c141e561a0886f8ad63bc2a6..71c5a620a43d89345e9b21593f38baaee5638c3e 100644 (file)
@@ -42,7 +42,8 @@ Ssl::PeerConnector::PeerConnector(const Comm::ConnectionPointer &aServerConn, As
     callback(aCallback),
     negotiationTimeout(timeout),
     startTime(squid_curtime),
-    useCertValidator_(false)
+    useCertValidator_(false),
+    certsDownloads(0)
 {
     // if this throws, the caller's cb dialer is not our CbDialer
     Must(dynamic_cast<CbDialer*>(callback->getDialer()));
@@ -638,14 +639,16 @@ Ssl::PeerConnector::startCertDownloading(SBuf &url)
                                             "Ssl::PeerConnector::certDownloadingDone",
                                             PeerConnectorCertDownloaderDialer(&Ssl::PeerConnector::certDownloadingDone, this));
 
+    const Downloader *csd = dynamic_cast<const Downloader*>(request->clientConnectionManager.valid());
     MasterXaction *xaction = new MasterXaction;
-    Downloader *dl = new Downloader(url, xaction, certCallback);
+    Downloader *dl = new Downloader(url, xaction, certCallback, csd ? csd->nestedLevel() + 1 : 1);
     AsyncJob::Start(dl);
 }
 
 void
 Ssl::PeerConnector::certDownloadingDone(SBuf &obj, int downloadStatus)
 {
+    certsDownloads++;
     debugs(81, 5, "OK! certificate downloaded, status: " << downloadStatus << " data size: " << obj.length());
 
     // Get ServerBio from SSL object
@@ -667,7 +670,7 @@ Ssl::PeerConnector::certDownloadingDone(SBuf &obj, int downloadStatus)
     }
 
     // Check if has uri to donwload and add it to urlsOfMissingCerts
-    if (urlsOfMissingCerts.size()) {
+    if (urlsOfMissingCerts.size() && certsDownloads <= MaxCertsDownloads) {
         startCertDownloading(urlsOfMissingCerts.front());
         urlsOfMissingCerts.pop();
         return;
@@ -680,6 +683,13 @@ Ssl::PeerConnector::certDownloadingDone(SBuf &obj, int downloadStatus)
 bool
 Ssl::PeerConnector::checkForMissingCertificates ()
 {
+    // Check for nested SSL certificates downloads. For example when the
+    // certificate located in an SSL site which requires to download a
+    // a missing certificate (... from an SSL site which requires to ...)
+    const Downloader *csd = dynamic_cast<const Downloader*>(request->clientConnectionManager.valid());
+    if (csd && csd->nestedLevel() >= MaxNestedDownloads)
+        return false;
+
     const int fd = serverConnection()->fd;
     SSL *ssl = fd_table[fd].ssl;
     BIO *b = SSL_get_rbio(ssl);
index 8bec0943d0a594a808b2ec43d88e4eb3b93cc94a..ba5af4d5a76f73f7f0cabf30f3059c91d7aea526 100644 (file)
@@ -177,13 +177,20 @@ private:
 
     /// A wrapper function for negotiateSsl for use with Comm::SetSelect
     static void NegotiateSsl(int fd, void *data);
+
+    /// The maximum allowed missing certificates downloads
+    static const unsigned int MaxCertsDownloads = 10;
+    /// The maximum allowed nested certificates downloads
+    static const unsigned int MaxNestedDownloads = 3;
+
     AsyncCall::Pointer callback; ///< we call this with the results
     AsyncCall::Pointer closeHandler; ///< we call this when the connection closed
     time_t negotiationTimeout; ///< the SSL connection timeout to use
     time_t startTime; ///< when the peer connector negotiation started
     bool useCertValidator_; ///< whether the certificate validator should bypassed
-
+    /// The list of URLs where missing certificates should be downloaded
     std::queue<SBuf> urlsOfMissingCerts;
+    unsigned int certsDownloads; ///< The number of downloaded missing certificates
 };
 
 /// A simple PeerConnector for SSL/TLS cache_peers. No SslBump capabilities.