From 816bd3d051a7c8fc7aba535361550d62fb5af2cc Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 23 Sep 2013 14:13:58 +0200 Subject: ReImplement MOAMetadataProvider to add and remove HTTPMetadataProvider dynamically from configuration database. --- .../moa/id/config/auth/AuthConfigLoader.java | 14 +- .../pvp2x/metadata/MOAMetadataProvider.java | 245 ++++++++++++++++++--- .../verification/MetadataSignatureFilter.java | 41 +++- 3 files changed, 254 insertions(+), 46 deletions(-) (limited to 'id/server/idserverlib/src/main/java/at/gv') diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigLoader.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigLoader.java index 92323f02b..e351cfa7d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigLoader.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigLoader.java @@ -26,7 +26,6 @@ public class AuthConfigLoader implements Runnable { MOAIDConfiguration moaidconfig = ConfigurationDBRead.getMOAIDConfiguration(); Date dbdate = moaidconfig.getTimestampItem(); Date pvprefresh = moaidconfig.getPvp2RefreshItem(); - ConfigurationDBUtils.closeSession(); Date date = AuthConfigurationProvider.getTimeStamp(); @@ -36,17 +35,18 @@ public class AuthConfigLoader implements Runnable { } Date pvpdate = MOAMetadataProvider.getTimeStamp(); - if (pvprefresh != null && pvprefresh.after(pvpdate)) { - MOAMetadataProvider metainst = MOAMetadataProvider.getInstance(); - metainst.reInitialize(); + if (pvprefresh != null && pvpdate != null && pvprefresh.after(pvpdate)) { + MOAMetadataProvider.reInitialize(); } - } catch (Throwable e) { Logger.warn("MOA-ID Configuration is actually not loadable. Reuse old configuration.", e); + + } finally { + ConfigurationDBUtils.closeSession(); + } - } - + } } public static void start() { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java index a61633e12..107ee22ee 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java @@ -1,11 +1,13 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.metadata; -import iaik.util.logging.Log; - import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Date; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Timer; import javax.xml.namespace.QName; @@ -34,8 +36,7 @@ public class MOAMetadataProvider implements MetadataProvider { private static MOAMetadataProvider instance = null; private static Object mutex = new Object(); - private static Date timestamp; - + private static Date timestamp = null; public static MOAMetadataProvider getInstance() { if (instance == null) { @@ -52,18 +53,162 @@ public class MOAMetadataProvider implements MetadataProvider { return timestamp; } - public void reInitialize() { + public static void reInitialize() { synchronized (mutex) { - Log.info("ReInitalize MOAMetaDataProvider."); - instance = new MOAMetadataProvider(); + + /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/ + if (instance != null) + instance.addAndRemoveMetadataProvider(); + + else + Logger.info("MOAMetadataProvider is not loaded."); + } + } + + public static void destroy() { + if (instance != null) { + instance.internalDestroy(); + + } else { + Logger.info("MOAMetadataProvider is not loaded. Accordingly it can not be destroyed"); } } MetadataProvider internalProvider; + + private void addAndRemoveMetadataProvider() { + if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { + Logger.info("Relaod MOAMetaDataProvider."); + + /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) + *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ + Map providersinuse = new HashMap(); + + Map loadedproviders = new HashMap(); + ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + //make a Map of all actually loaded HTTPMetadataProvider + List providers = chainProvider.getProviders(); + for (MetadataProvider provider : providers) { + if (provider instanceof HTTPMetadataProvider) { + HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; + loadedproviders.put(httpprovider.getMetadataURI(), httpprovider); + } + } + + //load all PVP2 OAs form ConfigurationDatabase and + //compare actually loaded Providers with configured PVP2 OAs + List oaList = ConfigurationDBRead + .getAllActiveOnlineApplications(); + + //set Timestamp + timestamp = new Date(); + + Iterator oaIt = oaList.iterator(); + while (oaIt.hasNext()) { + try { + OnlineApplication oa = oaIt.next(); + OAPVP2 pvp2Config = oa.getAuthComponentOA().getOAPVP2(); + if (pvp2Config != null && MiscUtil.isNotEmpty(pvp2Config.getMetadataURL())) { + + String metadataurl = pvp2Config.getMetadataURL(); + + if (loadedproviders.containsKey(metadataurl)) { + //PVP2 OA is actually loaded, to nothing + providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); + loadedproviders.remove(metadataurl); + + + } else if ( MiscUtil.isNotEmpty(metadataurl) && + !providersinuse.containsKey(metadataurl) ) { + //PVP2 OA is new, add it to MOAMetadataProvider + Logger.info("Loading metadata for: " + oa.getFriendlyName()); + HTTPMetadataProvider httpProvider = createNewHTTPMetaDataProvider( + pvp2Config.getMetadataURL(), + pvp2Config.getCertificate(), + oa.getFriendlyName()); + + if (httpProvider != null) + providersinuse.put(metadataurl, httpProvider); + + } + } + } catch (Throwable e) { + Logger.error( + "Failed to add Metadata (unhandled reason: " + + e.getMessage(), e); + } + } + + //remove all actually loaded MetadataProviders with are not in ConfigurationDB any more + Collection notusedproviders = loadedproviders.values(); + for (HTTPMetadataProvider provider : notusedproviders) { + String metadataurl = provider.getMetadataURI(); + + try { + + provider.destroy(); + + /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) + *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ + //chainProvider.removeMetadataProvider(provider); + + Logger.info("Remove not used MetadataProvider with MetadataURL " + metadataurl); + + } catch (Throwable e) { + Logger.error("HTTPMetadataProvider with URL " + metadataurl + + " can not be removed from the list of actually loaded Providers.", e); + + } + + } + + try { + chainProvider.setProviders(new ArrayList(providersinuse.values())); + + } catch (MetadataProviderException e) { + Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy", e); + + } + + + + } else { + Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); + } + + } + + + public void internalDestroy() { + if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { + Logger.info("Destrorying MOAMetaDataProvider."); + ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + List providers = chainProvider.getProviders(); + for (MetadataProvider provider : providers) { + if (provider instanceof HTTPMetadataProvider) { + HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; + Logger.debug("Destroy HTTPMetadataProvider +" + httpprovider.getMetadataURI()); + httpprovider.destroy(); + + } else { + Logger.warn("MetadataProvider can not be destroyed."); + } + } + instance = null; + } else { + Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); + } + } + private MOAMetadataProvider() { ChainingMetadataProvider chainProvider = new ChainingMetadataProvider(); Logger.info("Loading metadata"); + + Map providersinuse = new HashMap(); + List oaList = ConfigurationDBRead .getAllActiveOnlineApplications(); Iterator oaIt = oaList.iterator(); @@ -73,35 +218,22 @@ public class MOAMetadataProvider implements MetadataProvider { Logger.info("Loading metadata for: " + oa.getFriendlyName()); OAPVP2 pvp2Config = oa.getAuthComponentOA().getOAPVP2(); if (pvp2Config != null && MiscUtil.isNotEmpty(pvp2Config.getMetadataURL())) { -// if (pvp2Config != null) { String metadataURL = pvp2Config.getMetadataURL(); - try { - // TODO: use proper SSL checking - HTTPMetadataProvider httpProvider = - new HTTPMetadataProvider(new Timer(), new HttpClient(), - metadataURL); - httpProvider.setParserPool(new BasicParserPool()); - httpProvider.setRequireValidMetadata(true); - httpProvider.setMinRefreshDelay(1000*60*5); //5min - httpProvider.setMaxRefreshDelay(1000*60*30); //30min - //httpProvider.setRefreshDelayFactor(0.1F); - MetadataFilter filter = new MetadataSignatureFilter( - metadataURL, pvp2Config.getCertificate()); - httpProvider.setMetadataFilter(filter); - chainProvider.addMetadataProvider(httpProvider); - httpProvider.initialize(); - - } catch (MetadataProviderException e) { - Logger.error( - "Failed to add Metadata file for " - + oa.getFriendlyName() + "[ " - + e.getMessage() + " ]", e); - } catch (CertificateException e) { - Logger.error( - "Failed to add Metadata file for " - + oa.getFriendlyName() + "[ " - + e.getMessage() + " ]", e); + + if (!providersinuse.containsKey(metadataURL)) { + + HTTPMetadataProvider httpProvider = createNewHTTPMetaDataProvider( + metadataURL, + pvp2Config.getCertificate(), + oa.getFriendlyName()); + + if (httpProvider != null) + providersinuse.put(metadataURL, httpProvider); + + } else { + Logger.info(metadataURL + " are already added."); } + } else { Logger.info(oa.getFriendlyName() + " is not a PVP2 Application skipping"); @@ -113,10 +245,55 @@ public class MOAMetadataProvider implements MetadataProvider { } } + + try { + chainProvider.setProviders(new ArrayList(providersinuse.values())); + + } catch (MetadataProviderException e) { + Logger.error( + "Failed to add Metadata (unhandled reason: " + + e.getMessage(), e); + } + internalProvider = chainProvider; timestamp = new Date(); } + private HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL, byte[] certificate, String oaName) { + try { + HTTPMetadataProvider httpProvider = new HTTPMetadataProvider(new Timer(), new HttpClient(), + metadataURL); + httpProvider.setParserPool(new BasicParserPool()); + httpProvider.setRequireValidMetadata(true); + httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes + httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours + //httpProvider.setRefreshDelayFactor(0.1F); + + // TODO: use proper SSL checking + + MetadataFilter filter = new MetadataSignatureFilter( + metadataURL, certificate); + httpProvider.setMetadataFilter(filter); + httpProvider.initialize(); + + return httpProvider; + + + } catch (MetadataProviderException e) { + Logger.error( + "Failed to add Metadata file for " + + oaName + "[ " + + e.getMessage() + " ]", e); + } catch (CertificateException e) { + Logger.error( + "Failed to add Metadata file for " + + oaName + "[ " + + e.getMessage() + " ]", e); + } + + return null; + } + public boolean requireValidMetadata() { return internalProvider.requireValidMetadata(); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/MetadataSignatureFilter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/MetadataSignatureFilter.java index fb1f08132..ffc3f9b29 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/MetadataSignatureFilter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/MetadataSignatureFilter.java @@ -14,6 +14,8 @@ import org.opensaml.xml.security.credential.Credential; import org.opensaml.xml.security.x509.BasicX509Credential; import at.gv.egovernment.moa.id.MOAIDException; +import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils; +import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoCredentialsException; import at.gv.egovernment.moa.logging.Logger; public class MetadataSignatureFilter implements MetadataFilter { @@ -48,11 +50,37 @@ public class MetadataSignatureFilter implements MetadataFilter { } Iterator entIT = desc.getEntityDescriptors().iterator(); - - - //TODO: check this!!!! - while(entID.hasNext()) { - processEntityDescriptorr(entIT.next()); + + //check every Entity + while(entIT.hasNext()) { + + EntityDescriptor entity = entIT.next(); + String entityID = entity.getEntityID(); + + //CHECK if Entity also match MetaData signature. + /*This check is necessary to prepend declaration of counterfeit OA metadata!!*/ + byte[] entityCert = EntityVerifier.fetchSavedCredential(entityID); + + if (entityCert != null) { + + X509Certificate cert; + try { + cert = new X509Certificate(entityCert); + BasicX509Credential entityCrendential = new BasicX509Credential(); + entityCrendential.setEntityCertificate(cert); + + EntityVerifier.verify(desc, entityCrendential); + + } catch (Exception e) { + throw new MOAIDException("The App", null, e); + } + + } else { + throw new NoCredentialsException("NO Certificate found for OA " + entityID); + } + + //TODO: insert to support signed Entity-Elements + //processEntityDescriptorr(entIT.next()); } } @@ -70,6 +98,9 @@ public class MetadataSignatureFilter implements MetadataFilter { } */else { throw new MOAIDException("Invalid Metadata file Root element is no EntitiesDescriptor", null); } + + ConfigurationDBUtils.closeSession(); + Logger.info("Metadata Filter done OK"); } catch (MOAIDException e) { e.printStackTrace(); -- cgit v1.2.3