From a3361b40aa8f92849c50db27e349e17b87bebb1e Mon Sep 17 00:00:00 2001
From: wbauer <wbauer@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>
Date: Tue, 9 Sep 2008 12:40:52 +0000
Subject: improved security handling and added shutdown handler

git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@27 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
---
 .../online/applet/InternalSSLSocketFactory.java    |  4 +-
 .../at/gv/egiz/bku/online/conf/Configurator.java   |  8 +--
 .../gv/egiz/bku/online/webapp/ResultServlet.java   |  3 +-
 .../gv/egiz/bku/online/webapp/ShutdownHandler.java | 31 ++++++++
 .../egiz/bku/online/conf/accessControlConfig.xml   |  3 +-
 .../src/main/webapp/WEB-INF/applicationContext.xml |  6 +-
 .../accesscontroller/AuthenticationClassifier.java | 82 +++++++++++++++-------
 .../egiz/bku/binding/BindingProcessorManager.java  |  4 +-
 .../bku/binding/BindingProcessorManagerImpl.java   | 11 ++-
 .../AuthenticationClassifierTest.java              | 28 ++++++++
 .../egiz/bku/accesscontroller/www.a-trust.at.crt   | 28 ++++++++
 11 files changed, 169 insertions(+), 39 deletions(-)
 create mode 100644 BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ShutdownHandler.java
 create mode 100644 bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifierTest.java
 create mode 100644 bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/www.a-trust.at.crt

diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java
index 79c369a2..fa3587e4 100644
--- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java
+++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java
@@ -40,13 +40,13 @@ import org.apache.commons.logging.LogFactory;
 
 public class InternalSSLSocketFactory extends SSLSocketFactory {
 
+	private final static String GOV_DOMAIN = ".gv.at";
+
 	private static InternalSSLSocketFactory instance = new InternalSSLSocketFactory();
 
 	private final static Log log = LogFactory
 			.getLog(InternalSSLSocketFactory.class);
 
-	private final static String GOV_DOMAIN = ".gv.at";
-
 	private SSLSocket sslSocket;
 
 	private SSLSocketFactory proxy;
diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java
index a0a268e4..de577139 100644
--- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java
+++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java
@@ -52,9 +52,9 @@ public class Configurator {
 
 	protected void configureProviders() {
 		log.debug("Registering security providers");
-                Security.insertProviderAt(new IAIK(), 1);
-                Security.insertProviderAt(new ECCProvider(false), 2);
-    		Security.addProvider(new STALProvider());
+		Security.insertProviderAt(new IAIK(), 1);
+		Security.insertProviderAt(new ECCProvider(false), 2);
+		Security.addProvider(new STALProvider());
 		XSecProvider.addAsProvider(false);
 		StringBuilder sb = new StringBuilder();
 		sb.append("Registered providers: ");
@@ -65,7 +65,7 @@ public class Configurator {
 		log.debug(sb.toString());
 	}
 
-        public void configure() {
+	public void configure() {
 		configureProviders();
 		configUrlConnections();
 	}
diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java
index 6c1a4c3a..bc3edf18 100644
--- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java
+++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java
@@ -115,6 +115,7 @@ public class ResultServlet extends SpringBKUServlet {
     resp.setContentType(bp.getResultContentType());
     resp.setCharacterEncoding(encoding);
     bp.writeResultTo(resp.getOutputStream(), encoding);
-    session.invalidate();
+    session.invalidate();
+    getBindingProcessorManager().removeBindingProcessor(bp.getId());
   }
 }
diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ShutdownHandler.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ShutdownHandler.java
new file mode 100644
index 00000000..86da6c06
--- /dev/null
+++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ShutdownHandler.java
@@ -0,0 +1,31 @@
+package at.gv.egiz.bku.online.webapp;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextClosedEvent;
+
+import at.gv.egiz.bku.binding.BindingProcessorManager;
+
+public class ShutdownHandler implements ApplicationListener {
+
+	private static Log log = LogFactory.getLog(ShutdownHandler.class);
+
+	private BindingProcessorManager bindingProcessorManager;
+
+	public void setBindingProcessorManager(
+			BindingProcessorManager bindingProcessorManager) {
+		this.bindingProcessorManager = bindingProcessorManager;
+	}
+
+	@Override
+	public void onApplicationEvent(ApplicationEvent event) {
+		if (event instanceof ContextClosedEvent) {
+			log.info("Shutting down BKU");
+			bindingProcessorManager.shutdownNow();
+		}
+
+	}
+
+}
diff --git a/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/accessControlConfig.xml b/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/accessControlConfig.xml
index 69b45d1b..f8d1411c 100644
--- a/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/accessControlConfig.xml
+++ b/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/accessControlConfig.xml
@@ -54,8 +54,7 @@
 			<Rules>
 				<Rule Id="cmd-rule-1">
 					<AuthClass>certified</AuthClass>
-					<AnyPeer />
-					<Command Name="Infobox*">
+					<Command Name="Infobox.*">
 						<Param Name="InfoboxIdentifier">IdentityLink</Param>
 						<Param Name="PersonIdentifier">derived</Param>
 					</Command>
diff --git a/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml b/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml
index 4bb5e8e2..f87d09f5 100644
--- a/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml
@@ -49,5 +49,9 @@
 		scope="singleton" init-method="configure">
 		<property name="resource" value="classpath:at/gv/egiz/bku/online/conf/defaultConf.properties"/>
 	</bean>
-
+	
+	<!-- Shutdown Event handler -->
+  <bean id="shutdown" class="at.gv.egiz.bku.online.webapp.ShutdownHandler">
+  <property name="bindingProcessorManager" ref="bindingProcessorManager"></property>
+  </bean>
 </beans>
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java
index ace8a75a..ed4b9bda 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java
@@ -1,30 +1,31 @@
 /*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package at.gv.egiz.bku.accesscontroller;
 
 import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.ANONYMOUS;
 import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.CERTIFIED;
-import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.PSEUDO_ANONYMOUS;
 import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.CERTIFIED_GOV_AGENCY;
+import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.PSEUDO_ANONYMOUS;
 
-import java.net.InetAddress;
 import java.net.URL;
-import java.net.UnknownHostException;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -37,6 +38,39 @@ public class AuthenticationClassifier {
 	private AuthenticationClassifier() {
 	}
 
+	public static boolean isGovAgency(X509Certificate cert) {
+		String[] rdns = (cert.getSubjectX500Principal().getName()).split(",");
+		for (String rdn : rdns) {
+			if (rdn.startsWith("CN=")) {
+				String dns = rdn.split("=")[1];
+				log.trace("Analyzing cn dn: " + dns);
+				if (dns.endsWith(GOV_DOMAIN)) {
+					return true;
+				}
+			}
+		}
+		try {
+			Collection<List<?>> sanList = cert.getSubjectAlternativeNames();
+			if (sanList != null) {
+				for (List<?> san : sanList) {
+					log.trace("Analyzing subj. alt name: " + san);
+					if ((Integer) san.get(0) == 2) {
+						String dns = (String) san.get(1);
+						if (dns.endsWith(GOV_DOMAIN)) {
+							return true;
+						}
+					}
+				}
+			}
+		} catch (CertificateParsingException e) {
+			log.error(e);
+		}
+		if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) {
+			return true;
+		}
+		return false;
+	}
+
 	/**
 	 * Client Certificates are currently not supported
 	 * 
@@ -45,13 +79,8 @@ public class AuthenticationClassifier {
 			URL url, X509Certificate cert) {
 		if (isDataUrl) {
 			if (url.getProtocol().equalsIgnoreCase("https")) {
-				try {
-					if (InetAddress.getByName(url.getHost()).getCanonicalHostName()
-							.endsWith(GOV_DOMAIN)) {
-						return CERTIFIED_GOV_AGENCY;
-					}
-				} catch (UnknownHostException e) {
-					log.error("Cannot determine host name", e);
+				if (isGovAgency(cert)) {
+					return CERTIFIED_GOV_AGENCY;
 				}
 				if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) {
 					return CERTIFIED_GOV_AGENCY;
@@ -68,7 +97,8 @@ public class AuthenticationClassifier {
 	/**
 	 * 
 	 * @param isDataUrl
-	 * @param url if the url's protocol is https a cert parameter must be provided.
+	 * @param url
+	 *          if the url's protocol is https a cert parameter must be provided.
 	 * @param cert
 	 * @return
 	 */
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
index ed37f08f..aaf81e51 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
@@ -99,5 +99,7 @@ public interface BindingProcessorManager {
    */
   public Set<Id> getManagedIds();
       
-  public void shutdown();
+  public void shutdown();
+  
+  public void shutdownNow();
 }
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
index 6f5ca2d2..0082de26 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
@@ -149,6 +149,11 @@ public class BindingProcessorManagerImpl implements BindingProcessorManager {
   public void shutdown() {
     log.info("Shutting down the BindingProcessorManager");
     executorService.shutdown();
+  }
+  
+  public void shutdownNow() {
+  	log.info("Shutting down the BindingProcessorManager NOW!");
+    executorService.shutdownNow();
   }
 
   /**
@@ -223,7 +228,8 @@ public class BindingProcessorManagerImpl implements BindingProcessorManager {
       throw new SLRuntimeException(
           "Clashing ids, cannot process bindingprocessor with id:"
               + aBindingProcessor.getId());
-    }
+    }
+    log.debug("processing bindingprocessor: "+aBindingProcessor.getId());
     Future<?> f = executorService.submit(aBindingProcessor);
     bindingProcessorMap.put(aBindingProcessor.getId(), new MapEntityWrapper(f,
         aBindingProcessor));
@@ -235,7 +241,8 @@ public class BindingProcessorManagerImpl implements BindingProcessorManager {
   }
 
   @Override
-  public void removeBindingProcessor(Id sessionId) {
+  public void removeBindingProcessor(Id sessionId) {
+  	log.debug("Removing binding processor: "+sessionId);
     MapEntityWrapper wrapper = bindingProcessorMap
         .get(sessionId);
     if (wrapper == null) {
diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifierTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifierTest.java
new file mode 100644
index 00000000..c339704e
--- /dev/null
+++ b/bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifierTest.java
@@ -0,0 +1,28 @@
+package at.gv.egiz.bku.accesscontroller;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AuthenticationClassifierTest {
+
+	private X509Certificate atrust;
+
+	@Before
+	public void setUp() throws Exception {
+		atrust = (X509Certificate) CertificateFactory.getInstance("X509")
+				.generateCertificate(
+						getClass().getClassLoader().getResourceAsStream(
+								"at/gv/egiz/bku/accesscontroller/www.a-trust.at.crt"));
+	}
+
+	@Test
+	public void testATrust() {
+		assertTrue(AuthenticationClassifier.isGovAgency(atrust));
+	}
+
+}
diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/www.a-trust.at.crt b/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/www.a-trust.at.crt
new file mode 100644
index 00000000..11cde026
--- /dev/null
+++ b/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/www.a-trust.at.crt
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEyjCCA7KgAwIBAgIDA4LFMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYDVQQGEwJB
+VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
+bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRYwFAYDVQQLDA1hLXNpZ24tU1NM
+LTAzMRYwFAYDVQQDDA1hLXNpZ24tU1NMLTAzMB4XDTA3MTIxMTExMTQ0NFoXDTEy
+MTIxMTExMTQ0NFowYTELMAkGA1UEBhMCQVQxEDAOBgNVBAoMB0EtVHJ1c3QxEDAO
+BgNVBAsMB0EtVHJ1c3QxFzAVBgNVBAMMDnd3dy5hLXRydXN0LmF0MRUwEwYDVQQF
+Eww2NDk2ODY0MDkzMzkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK2oRtJ4
+R9ipr/NUH5F4p86cjWtzT1g+ytpjg1lwh4HNY+lTjdUcx/VKBrtf0N8qnMK1UHhA
+LLvvZeKTFi3L15i5or1WjZRi4RfH/4vcL0o1w/91liwMOKH3D30omnVceuxmQp2j
+V9QrGPbz0/IsP51cnBWCBTWGqgfBebB8v1FLAgMBAAGjggHmMIIB4jATBgNVHSME
+DDAKgAhAPqHTYrQD3TByBggrBgEFBQcBAQRmMGQwJwYIKwYBBQUHMAGGG2h0dHA6
+Ly9vY3NwLmEtdHJ1c3QuYXQvb2NzcDA5BggrBgEFBQcwAoYtaHR0cDovL3d3dy5h
+LXRydXN0LmF0L2NlcnRzL2Etc2lnbi1zc2wtMDMuY3J0MEsGA1UdIAREMEIwQAYG
+KigAEQEUMDYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuYS10cnVzdC5hdC9kb2Nz
+L2NwL2Etc2lnbi1zc2wwgY8GA1UdHwSBhzCBhDCBgaB/oH2Ge2xkYXA6Ly9sZGFw
+LmEtdHJ1c3QuYXQvb3U9YS1zaWduLVNTTC0wMyxvPUEtVHJ1c3QsYz1BVD9jZXJ0
+aWZpY2F0ZXJldm9jYXRpb25saXN0P2Jhc2U/b2JqZWN0Y2xhc3M9ZWlkQ2VydGlm
+aWNhdGlvbkF1dGhvcml0eTARBgNVHQ4ECgQIRu1a/pOZZpMwDgYDVR0PAQH/BAQD
+AgWgMEoGA1UdEQRDMEGBEW9mZmljZUBhLXRydXN0LmF0gg53d3cuYS10cnVzdC5h
+dIIcemRhLnNvemlhbHZlcnNpY2hlcnVuZy5ndi5hdDAJBgNVHRMEAjAAMA0GCSqG
+SIb3DQEBBQUAA4IBAQCQGheDpci0lnSEoKw/N3tbJqn/KG49/OWZcsw6XZiAEHsx
+Rx9TlNJhL2d/SqFXBmmqfR496gdzTb4823WJsmXtyBY2t5ZnmD9tY5oJi5bHKchO
+50QCd1x24HzH1mxPReCJzRxzLEM/znojEMdYqQ5Y+BZuj7n9BY+l2nY0Qnhn09FE
+dxXAfNcuZnZavLJgk7vTBg8OFkAh6DJ21ACxf/y+rN53gKFK4Jh+PodRu0J2tK8B
+wAZg7HlnT8U7tcEsf1JnsBhlzAWCHgZc6whgBbDHFs6WSFWuobKN+maU91g/Tvgk
+Obos/EhVNti54Zhu1PO9RSKpKkwzTJT4kmGtaOJN
+-----END CERTIFICATE-----
-- 
cgit v1.2.3