>From cc10c05d122df43bb5b09cfc09c42099c1fd08bd Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Thu, 26 May 2016 05:10:17 +0200
Subject: [PATCH] Fixed error handling in ProxyRealm.

The ProxyRealms for Tomcat 7 and 8 have been modified to return an
error if the subsystem is not available instead of falling back to
username/password authentication.

https://fedorahosted.org/pki/ticket/2326
---
 base/server/tomcat7/src/CMakeLists.txt             |  3 +-
 .../src/com/netscape/cms/tomcat/ProxyRealm.java    | 46 ++++++++++++++++++++++
 base/server/tomcat8/src/CMakeLists.txt             |  3 +-
 .../src/com/netscape/cms/tomcat/ProxyRealm.java    | 44 +++++++++++++++++++++
 4 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/base/server/tomcat7/src/CMakeLists.txt b/base/server/tomcat7/src/CMakeLists.txt
index bb42bfe0a4a840f0b271a83600f79686f76cc353..f84369ccc33d47c11f32bc3e956431f501c121e4 100644
--- a/base/server/tomcat7/src/CMakeLists.txt
+++ b/base/server/tomcat7/src/CMakeLists.txt
@@ -124,7 +124,8 @@ javac(pki-tomcat7-classes
         com/netscape/cms/tomcat/*.java
     CLASSPATH
         ${SERVLET_JAR} ${TOMCAT_CATALINA_JAR} ${TOMCAT_UTIL_SCAN_JAR}
-            ${CMAKE_BINARY_DIR}/../../tomcat
+        ${JAXRS_API_JAR}
+        ${CMAKE_BINARY_DIR}/../../tomcat
     OUTPUT_DIR
         ${CMAKE_BINARY_DIR}/../../tomcat
     DEPENDS
diff --git a/base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java b/base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java
index 094c0561f49f4e79d910b1d9a30c13b10d04a297..13b61e47a5531785760a338db1658c6bd1619555 100644
--- a/base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java
+++ b/base/server/tomcat7/src/com/netscape/cms/tomcat/ProxyRealm.java
@@ -7,6 +7,8 @@ import java.security.cert.X509Certificate;
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.ws.rs.ServiceUnavailableException;
+
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
 import org.apache.catalina.Realm;
@@ -60,12 +62,26 @@ public class ProxyRealm implements Realm {
     }
 
     @Override
+    public Principal authenticate(String username) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
+        return realm.authenticate(username);
+    }
+
+    @Override
     public Principal authenticate(String username, String password) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(username, password);
     }
 
     @Override
     public Principal authenticate(X509Certificate certs[]) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(certs);
     }
 
@@ -80,11 +96,17 @@ public class ProxyRealm implements Realm {
             String realmName,
             String md5a2
     ) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(username, digest, nonce, nc, cnonce, qop, realmName, md5a2);
     }
 
     @Override
     public Principal authenticate(GSSContext gssContext, boolean storeCreds) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(gssContext, storeCreds);
     }
 
@@ -95,26 +117,41 @@ public class ProxyRealm implements Realm {
             SecurityConstraint[] constraints,
             Context context
     ) throws IOException {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.hasResourcePermission(request, response, constraints, context);
     }
 
     @Override
     public String getInfo() {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.getInfo();
     }
 
     @Override
     public void backgroundProcess() {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         realm.backgroundProcess();
     }
 
     @Override
     public SecurityConstraint[] findSecurityConstraints(Request request, Context context) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.findSecurityConstraints(request, context);
     }
 
     @Override
     public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.hasRole(wrapper, principal, role);
     }
 
@@ -124,16 +161,25 @@ public class ProxyRealm implements Realm {
             Response response,
             SecurityConstraint[] constraint
     ) throws IOException {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.hasUserDataPermission(request,  response, constraint);
     }
 
     @Override
     public void addPropertyChangeListener(PropertyChangeListener listener) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         realm.addPropertyChangeListener(listener);
     }
 
     @Override
     public void removePropertyChangeListener(PropertyChangeListener listener) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         realm.removePropertyChangeListener(listener);
     }
 }
diff --git a/base/server/tomcat8/src/CMakeLists.txt b/base/server/tomcat8/src/CMakeLists.txt
index 8aed1fc18e8173b3db841ed2cd3d730b9f45753f..0f49ff9bc6366e65c289ab76e1ee32e6fac928fd 100644
--- a/base/server/tomcat8/src/CMakeLists.txt
+++ b/base/server/tomcat8/src/CMakeLists.txt
@@ -131,7 +131,8 @@ javac(pki-tomcat8-classes
         com/netscape/cms/tomcat/*.java
     CLASSPATH
         ${SERVLET_JAR} ${TOMCAT_CATALINA_JAR} ${TOMCAT_UTIL_SCAN_JAR} ${TOMCAT_API_JAR}
-            ${CMAKE_BINARY_DIR}/../../tomcat
+        ${JAXRS_API_JAR}
+        ${CMAKE_BINARY_DIR}/../../tomcat
     OUTPUT_DIR
         ${CMAKE_BINARY_DIR}/../../tomcat
     DEPENDS
diff --git a/base/server/tomcat8/src/com/netscape/cms/tomcat/ProxyRealm.java b/base/server/tomcat8/src/com/netscape/cms/tomcat/ProxyRealm.java
index bcedd52dc152f44106d860f6b2a7e3b5f04b65c3..f5986e85730a3a3533a3035c8a11b6e9479acff3 100644
--- a/base/server/tomcat8/src/com/netscape/cms/tomcat/ProxyRealm.java
+++ b/base/server/tomcat8/src/com/netscape/cms/tomcat/ProxyRealm.java
@@ -7,6 +7,8 @@ import java.security.cert.X509Certificate;
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.ws.rs.ServiceUnavailableException;
+
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
 import org.apache.catalina.CredentialHandler;
@@ -62,16 +64,25 @@ public class ProxyRealm implements Realm {
 
     @Override
     public Principal authenticate(String username) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(username);
     }
 
     @Override
     public Principal authenticate(String username, String password) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(username, password);
     }
 
     @Override
     public Principal authenticate(X509Certificate certs[]) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(certs);
     }
 
@@ -86,11 +97,17 @@ public class ProxyRealm implements Realm {
             String realmName,
             String md5a2
     ) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(username, digest, nonce, nc, cnonce, qop, realmName, md5a2);
     }
 
     @Override
     public Principal authenticate(GSSContext gssContext, boolean storeCreds) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.authenticate(gssContext, storeCreds);
     }
 
@@ -101,21 +118,33 @@ public class ProxyRealm implements Realm {
             SecurityConstraint[] constraints,
             Context context
     ) throws IOException {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.hasResourcePermission(request, response, constraints, context);
     }
 
     @Override
     public void backgroundProcess() {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         realm.backgroundProcess();
     }
 
     @Override
     public SecurityConstraint[] findSecurityConstraints(Request request, Context context) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.findSecurityConstraints(request, context);
     }
 
     @Override
     public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.hasRole(wrapper, principal, role);
     }
 
@@ -125,26 +154,41 @@ public class ProxyRealm implements Realm {
             Response response,
             SecurityConstraint[] constraint
     ) throws IOException {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.hasUserDataPermission(request,  response, constraint);
     }
 
     @Override
     public void addPropertyChangeListener(PropertyChangeListener listener) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         realm.addPropertyChangeListener(listener);
     }
 
     @Override
     public void removePropertyChangeListener(PropertyChangeListener listener) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         realm.removePropertyChangeListener(listener);
     }
 
     @Override
     public CredentialHandler getCredentialHandler() {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         return realm.getCredentialHandler();
     }
 
     @Override
     public void setCredentialHandler(CredentialHandler handler) {
+        if (realm == null) {
+            throw new ServiceUnavailableException("Subsystem unavailable");
+        }
         realm.setCredentialHandler(handler);
     }
 }
-- 
2.4.11

