]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
- Implement the FwdState::sslCrtvdCheckForErrors method. This method
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Tue, 18 Sep 2012 17:08:48 +0000 (20:08 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Tue, 18 Sep 2012 17:08:48 +0000 (20:08 +0300)
  checks if the errors returned from cert validator class can be
  ignored or an error to the user must returned.

- Now if the Config.ssl_client.cert_error is not used, then the first
  error in the list returned from cert validator, is the error which
  considered as the error which causes the failure

src/forward.cc
src/forward.h

index ee48acaba23e1851200add204fad86e4427e3004..81afd06ed33c6252c1c361bfcdda1d557da80a01 100644 (file)
@@ -842,43 +842,10 @@ FwdState::sslCrtvdHandleReply(const char *reply)
                 validatorFailed = true;
             } else {
                 debugs(83, 5, HERE << "Certificate for " << request->GetHost() << " was successfully validated from ssl_crtvd");
-                ACLFilledChecklist *check = NULL;
-                if (acl_access *acl = Config.ssl_client.cert_error) {
-                    check = new ACLFilledChecklist(acl, request, dash_str);
-                    for(std::vector<Ssl::ValidateCertificateResponse::ErrorItem>::const_iterator i = resp.errors.begin(); i != resp.errors.end(); ++i) {
-                        debugs(83, 7, "Error item: " << i->error_no << " " << i->error_reason);
-
-                        if (i->error_no == SSL_ERROR_NONE)
-                            continue; //ignore????
-
-                        if (errDetails == NULL && check) {
-                            check->sslErrors = new Ssl::Errors(i->error_no);
-                            if (check->fastCheck() == ACCESS_ALLOWED) {
-                                debugs(83, 3, "bypassing SSL error " << i->error_no << " in " << "buffer");
-                            } else {
-                                debugs(83, 5, "confirming SSL error " << i->error_no);
-                                X509 *brokenCert = (i->cert ? i->cert : NULL);
-                                X509 *peerCert = SSL_get_peer_certificate(ssl);
-                                const char *aReason = i->error_reason.empty() ? NULL : i->error_reason.c_str();
-                                errDetails = new Ssl::ErrorDetail(i->error_no, peerCert, brokenCert, aReason);
-                                X509_free(peerCert);
-                                // set error detail reason
-                            }
-                            delete check->sslErrors;
-                            check->sslErrors = NULL;
-                        }
-
-                        if (errs == NULL)
-                            errs = new Ssl::Errors(i->error_no);
-                        else 
-                            errs->push_back_unique(i->error_no);
-                    }
-
-                    if (!errDetails) {
-                        dispatch();
-                        return;
-                    }
-
+                errs = sslCrtvdCheckForErrors(resp, errDetails);
+                if (!errDetails) {
+                    dispatch();
+                    return;
                 }
             }
         }
@@ -896,7 +863,7 @@ FwdState::sslCrtvdHandleReply(const char *reply)
                 // remember validation errors, if any
                 if (errs) {
                     if (serverBump->sslErrors)
-                        cbdataReference(serverBump->sslErrors);
+                        cbdataReferenceDone(serverBump->sslErrors);
                     serverBump->sslErrors = cbdataReference(errs);
                 }
             }
@@ -915,6 +882,57 @@ FwdState::sslCrtvdHandleReply(const char *reply)
     self = NULL;
     return;
 }
+
+Ssl::Errors *
+FwdState::sslCrtvdCheckForErrors(Ssl::ValidateCertificateResponse &resp, Ssl::ErrorDetail *& errDetails)
+{
+    Ssl::Errors *errs = NULL;
+    ACLFilledChecklist *check = NULL;
+    SSL *ssl = fd_table[serverConnection()->fd].ssl;
+
+    if (acl_access *acl = Config.ssl_client.cert_error)
+        check = new ACLFilledChecklist(acl, request, dash_str);
+
+    for(Ssl::ValidateCertificateResponse::Errors::const_iterator i = resp.errors.begin(); i != resp.errors.end(); ++i) {
+        debugs(83, 7, "Error item: " << i->error_no << " " << i->error_reason);
+
+        if (i->error_no == SSL_ERROR_NONE)
+            continue; //ignore????
+
+        if (errDetails == NULL) {
+            bool allowed = false;
+            if (check) {
+                check->sslErrors = new Ssl::Errors(i->error_no);
+                if (check->fastCheck() == ACCESS_ALLOWED)
+                    allowed = true;
+            }
+            // else the Config.ssl_client.cert_error access list is not defined
+            // and the first error will cause the error page
+
+            if (allowed) {
+                debugs(83, 3, "bypassing SSL error " << i->error_no << " in " << "buffer");
+            } else {
+                debugs(83, 5, "confirming SSL error " << i->error_no);
+                X509 *brokenCert = (i->cert ? i->cert : NULL);
+                X509 *peerCert = SSL_get_peer_certificate(ssl);
+                const char *aReason = i->error_reason.empty() ? NULL : i->error_reason.c_str();
+                errDetails = new Ssl::ErrorDetail(i->error_no, peerCert, brokenCert, aReason);
+                X509_free(peerCert);
+                // set error detail reason
+            }
+            delete check->sslErrors;
+            check->sslErrors = NULL;
+        }
+
+        if (errs == NULL)
+            errs = new Ssl::Errors(i->error_no);
+        else 
+            errs->push_back_unique(i->error_no);
+    }
+
+    return errs;
+}
+
 #endif // USE_SSL_CERT_VALIDATOR
 
 void
index f84feb7b9d795309f8f18e874befca6ca2beef93..2a4b311352af4de05848da8fe9c1a49a4d7d4f3e 100644 (file)
@@ -7,6 +7,9 @@
 #include "fde.h"
 #include "ip/Address.h"
 #include "RefCount.h"
+#if USE_SSL
+#include "ssl/support.h"
+#endif
 
 /* forward decls */
 
@@ -15,6 +18,12 @@ typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
 class ErrorState;
 class HttpRequest;
 
+namespace Ssl
+{
+    class ErrorDetail;
+    class ValidateCertificateResponse;
+};
+
 /**
  * Returns the TOS value that we should be setting on the connection
  * to the server, based on the ACL.
@@ -72,6 +81,7 @@ public:
 #if 1 // USE_SSL_CERT_VALIDATOR
     static void sslCrtvdHandleReplyWrapper(void *data, char *reply);
     void sslCrtvdHandleReply(const char *reply);
+    Ssl::Errors *sslCrtvdCheckForErrors(Ssl::ValidateCertificateResponse &, Ssl::ErrorDetail *&);
 #endif
 private:
     // hidden for safer management of self; use static fwdStart