From 1ffb12f9b964ca5757b65af2cba1fff5c1a1a2e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20K=C3=A1cha?= <ph@cesnet.cz>
Date: Mon, 10 Jul 2017 15:36:47 +0200
Subject: [PATCH] Cert checking now works correctly in both "SSLVerifyClient
 required" and "SSLVerifyClient optional" (authenticators do safety check
 themselves)

---
 warden3/warden_server/apache22.conf.dist |  2 +-
 warden3/warden_server/apache24.conf.dist |  2 +-
 warden3/warden_server/warden_server.py   | 22 ++++++++++++++++++++--
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/warden3/warden_server/apache22.conf.dist b/warden3/warden_server/apache22.conf.dist
index 380cd44..353e4d3 100644
--- a/warden3/warden_server/apache22.conf.dist
+++ b/warden3/warden_server/apache22.conf.dist
@@ -1,6 +1,6 @@
 SSLEngine on
 
-SSLVerifyClient require
+SSLVerifyClient optional
 SSLVerifyDepth 4
 SSLOptions +StdEnvVars +ExportCertData
 
diff --git a/warden3/warden_server/apache24.conf.dist b/warden3/warden_server/apache24.conf.dist
index a65ada3..6a1e367 100644
--- a/warden3/warden_server/apache24.conf.dist
+++ b/warden3/warden_server/apache24.conf.dist
@@ -1,6 +1,6 @@
 SSLEngine on
 
-SSLVerifyClient require
+SSLVerifyClient optional
 SSLVerifyDepth 4
 SSLOptions +StdEnvVars +ExportCertData
 
diff --git a/warden3/warden_server/warden_server.py b/warden3/warden_server/warden_server.py
index b1d7442..90d1bd1 100755
--- a/warden3/warden_server/warden_server.py
+++ b/warden3/warden_server/warden_server.py
@@ -357,7 +357,19 @@ class X509Authenticator(PlainAuthenticator):
         return [firstcommon] + list(set(altnames+commons) - set([firstcommon]))
 
 
+    def is_verified_by_apache(self, env, args):
+        # Allows correct work while SSLVerifyClient both "optional" and "required"
+        verify = env.get("SSL_CLIENT_VERIFY")
+        if verify != "SUCCESS":
+            exception = self.req.error(message="authenticate: certificate verification failed", error=403, args = args, ssl_client_verify=verify, cert=env.get("SSL_CLIENT_CERT"))
+            exception.log(self.log)
+            return None
+
+
     def authenticate(self, env, args):
+        if not self.is_verified_by_apache(env, args):
+            return None
+
         try:
             cert_names = self.get_cert_dns_names(env["SSL_CLIENT_CERT"])
         except:
@@ -368,9 +380,12 @@ class X509Authenticator(PlainAuthenticator):
         return PlainAuthenticator.authenticate(self, env, args, hostnames = cert_names)
         
 
-class X509NameAuthenticator(PlainAuthenticator):
+class X509NameAuthenticator(X509Authenticator):
 
     def authenticate(self, env, args):
+        if not self.is_verified_by_apache(env, args):
+            return None
+
         try:
             cert_name = env["SSL_CLIENT_S_DN_CN"]
         except:
@@ -386,7 +401,7 @@ class X509NameAuthenticator(PlainAuthenticator):
         return PlainAuthenticator.authenticate(self, env, args, check_secret = False)
 
 
-class X509MixMatchAuthenticator(PlainAuthenticator):
+class X509MixMatchAuthenticator(X509Authenticator):
 
     def __init__(self, req, log, db):
         PlainAuthenticator.__init__(self, req, log, db)
@@ -395,6 +410,9 @@ class X509MixMatchAuthenticator(PlainAuthenticator):
 
 
     def authenticate(self, env, args):
+        if not self.is_verified_by_apache(env, args):
+            return None
+
         try:
             cert_name = env["SSL_CLIENT_S_DN_CN"]
         except:
-- 
GitLab