From b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 5 May 2010 15:29:01 +0000 Subject: Merged feature branch mocca-1.2.13-id@r724 back to trunk. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@725 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../accesscontroller/AccessControllerFactory.java | 305 ++++--- .../accesscontroller/AuthenticationClassifier.java | 220 ++--- .../gv/egiz/bku/accesscontroller/ChainChecker.java | 183 ++--- .../bku/accesscontroller/InfoboxParamChecker.java | 149 ++-- .../gv/egiz/bku/accesscontroller/RuleChecker.java | 406 +++++----- .../accesscontroller/SecurityManagerFacade.java | 237 +++--- .../egiz/bku/binding/AbstractBindingProcessor.java | 111 ++- .../binding/AbstractBindingProcessorFactory.java | 81 ++ .../at/gv/egiz/bku/binding/BindingProcessor.java | 153 +++- .../egiz/bku/binding/BindingProcessorFactory.java | 42 + .../egiz/bku/binding/BindingProcessorFuture.java | 73 ++ .../egiz/bku/binding/BindingProcessorManager.java | 138 ++-- .../bku/binding/BindingProcessorManagerImpl.java | 414 +++++----- .../egiz/bku/binding/DataURLConnectionFactory.java | 26 + .../main/java/at/gv/egiz/bku/binding/DataUrl.java | 91 +-- .../at/gv/egiz/bku/binding/DataUrlConnection.java | 134 +-- .../gv/egiz/bku/binding/DataUrlConnectionImpl.java | 340 +++----- .../gv/egiz/bku/binding/DataUrlConnectionSPI.java | 64 -- .../java/at/gv/egiz/bku/binding/ExpiryRemover.java | 67 -- .../egiz/bku/binding/FormDataURLDereferencer.java | 71 ++ .../gv/egiz/bku/binding/FormDataURLSupplier.java | 27 + .../gv/egiz/bku/binding/HTTPBindingProcessor.java | 859 +------------------- .../bku/binding/HTTPBindingProcessorFactory.java | 80 ++ .../egiz/bku/binding/HTTPBindingProcessorImpl.java | 896 +++++++++++++++++++++ .../gv/egiz/bku/binding/HttpDataURLConnection.java | 68 ++ .../main/java/at/gv/egiz/bku/binding/HttpUtil.java | 3 +- .../egiz/bku/binding/HttpsDataURLConnection.java | 72 ++ .../java/at/gv/egiz/bku/binding/IdFactory.java | 180 ++--- .../main/java/at/gv/egiz/bku/binding/IdImpl.java | 11 +- .../gv/egiz/bku/binding/InputDecoderFactory.java | 148 ++-- .../bku/binding/MultiPartFormDataInputDecoder.java | 235 +++--- .../at/gv/egiz/bku/binding/ProcessingContext.java | 59 -- .../at/gv/egiz/bku/binding/RemovalStrategy.java | 26 - .../gv/egiz/bku/binding/SLCommandInvokerImpl.java | 33 +- .../egiz/bku/binding/XWWWFormUrlInputIterator.java | 1 + .../java/at/gv/egiz/bku/conf/CertValidator.java | 13 - .../at/gv/egiz/bku/conf/CertValidatorImpl.java | 110 --- .../java/at/gv/egiz/bku/conf/Configuration.java | 100 --- .../java/at/gv/egiz/bku/conf/Configurator.java | 467 ----------- .../java/at/gv/egiz/bku/conf/IAIKCommonsLog.java | 144 ---- .../at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java | 59 -- .../java/at/gv/egiz/bku/conf/IAIKLogAdapter.java | 146 ++++ .../at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java | 62 ++ .../gv/egiz/bku/conf/MoccaConfigurationFacade.java | 22 + .../java/at/gv/egiz/bku/jmx/ComponentMXBean.java | 27 + .../java/at/gv/egiz/bku/jmx/ComponentState.java | 38 + .../at/gv/egiz/bku/jmx/ComponentStateCheck.java | 24 + .../bku/slcommands/AbstractSLCommandFactory.java | 46 ++ .../bku/slcommands/CreateXMLSignatureCommand.java | 2 +- .../bku/slcommands/CreateXMLSignatureResult.java | 7 +- .../at/gv/egiz/bku/slcommands/ErrorResult.java | 8 +- .../gv/egiz/bku/slcommands/InfoboxReadResult.java | 5 +- .../java/at/gv/egiz/bku/slcommands/SLCommand.java | 10 +- .../gv/egiz/bku/slcommands/SLCommandContext.java | 31 +- .../gv/egiz/bku/slcommands/SLCommandFactory.java | 519 ++++-------- .../gv/egiz/bku/slcommands/SLCommandInvoker.java | 2 +- .../egiz/bku/slcommands/SLMarshallerFactory.java | 11 +- .../at/gv/egiz/bku/slcommands/SLSourceContext.java | 3 - .../slcommands/impl/AbstractAssocArrayInfobox.java | 16 +- .../slcommands/impl/AbstractBinaryFileInfobox.java | 8 +- .../impl/AbstractInfoboxCommandFactory.java | 40 + .../impl/AbstractInfoboxCommandImpl.java | 26 +- .../slcommands/impl/AbstractInfoboxFactory.java | 24 + .../slcommands/impl/CardChannelInfoboxFactory.java | 27 + .../slcommands/impl/CardChannelInfoboxImpl.java | 12 +- .../impl/CertificatesInfoboxFactory.java | 27 + .../slcommands/impl/CertificatesInfoboxImpl.java | 6 +- .../impl/CreateXMLSignatureCommandFactory.java | 65 ++ .../impl/CreateXMLSignatureCommandImpl.java | 77 +- .../impl/CreateXMLSignatureResultImpl.java | 27 +- .../impl/DomCreateXMLSignatureResultImpl.java | 47 ++ .../bku/slcommands/impl/DomErrorResultImpl.java | 70 ++ .../slcommands/impl/DomInfoboxReadResultImpl.java | 105 +++ .../gv/egiz/bku/slcommands/impl/DomSLResult.java | 41 + .../egiz/bku/slcommands/impl/ErrorResultImpl.java | 18 + .../slcommands/impl/GetStatusCommandFactory.java | 37 + .../bku/slcommands/impl/GetStatusCommandImpl.java | 24 +- .../impl/IdentityLinkInfoboxFactory.java | 48 ++ .../slcommands/impl/IdentityLinkInfoboxImpl.java | 28 +- .../egiz/bku/slcommands/impl/InfoboxFactory.java | 103 +-- .../slcommands/impl/InfoboxReadCommandFactory.java | 37 + .../slcommands/impl/InfoboxReadCommandImpl.java | 84 +- .../slcommands/impl/InfoboxReadResultFileImpl.java | 40 +- .../bku/slcommands/impl/InfoboxReadResultImpl.java | 18 + .../impl/InfoboxUpdateCommandFactory.java | 37 + .../slcommands/impl/InfoboxUpdateCommandImpl.java | 16 +- .../impl/NullOperationCommandFactory.java | 37 + .../slcommands/impl/NullOperationCommandImpl.java | 3 +- .../gv/egiz/bku/slcommands/impl/SLCommandImpl.java | 33 +- .../gv/egiz/bku/slcommands/impl/SLResultImpl.java | 18 +- .../at/gv/egiz/bku/slcommands/impl/STALHelper.java | 17 +- .../impl/SVPersonendatenInfoboxFactory.java | 27 + .../impl/SVPersonendatenInfoboxImpl.java | 10 +- .../impl/xsect/AlgorithmMethodFactoryImpl.java | 3 +- .../egiz/bku/slcommands/impl/xsect/DataObject.java | 191 +++-- .../slcommands/impl/xsect/LocRefDereferencer.java | 189 +++-- .../bku/slcommands/impl/xsect/STALPrivateKey.java | 3 +- .../bku/slcommands/impl/xsect/STALProvider.java | 71 -- .../bku/slcommands/impl/xsect/STALSignature.java | 184 ----- .../impl/xsect/STALSignatureException.java | 2 +- .../slcommands/impl/xsect/STALSignatureMethod.java | 127 +++ .../egiz/bku/slcommands/impl/xsect/Signature.java | 43 +- .../slcommands/impl/xsect/SignatureContext.java | 50 +- .../slcommands/impl/xsect/SignatureLocation.java | 418 +++++----- .../impl/xsect/URIDereferncerAdapter.java | 14 +- .../egiz/bku/slexceptions/SLBindingException.java | 2 + .../egiz/bku/slexceptions/SLCanceledException.java | 2 + .../at/gv/egiz/bku/slexceptions/SLException.java | 9 +- .../egiz/bku/slexceptions/SLRequestException.java | 2 + .../egiz/bku/slexceptions/SLRuntimeException.java | 2 + .../egiz/bku/slexceptions/SLViewerException.java | 2 + .../bku/spring/ConfigurableHostnameVerifier.java | 77 ++ .../egiz/bku/spring/ConfigurationFactoryBean.java | 172 ++++ .../gv/egiz/bku/spring/PKIProfileFactoryBean.java | 235 ++++++ .../at/gv/egiz/bku/spring/PKITrustManager.java | 173 ++++ .../gv/egiz/bku/spring/SSLSocketFactoryBean.java | 109 +++ .../bku/spring/SecurityManagerFactoryBean.java | 102 +++ .../at/gv/egiz/bku/viewer/ResourceFontLoader.java | 6 +- .../at/gv/egiz/bku/viewer/ValidatorFactory.java | 22 +- 119 files changed, 6244 insertions(+), 5078 deletions(-) create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java (limited to 'bkucommon/src/main/java') diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java index 19fec084..eb708739 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java @@ -1,153 +1,152 @@ -/* -* 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 java.io.InputStream; -import java.util.Hashtable; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.accesscontrol.config.AccessControl; -import at.gv.egiz.bku.accesscontrol.config.Chain; -import at.gv.egiz.bku.accesscontrol.config.Command; -import at.gv.egiz.bku.accesscontrol.config.ObjectFactory; -import at.gv.egiz.bku.accesscontrol.config.Param; -import at.gv.egiz.bku.accesscontrol.config.Rule; -import at.gv.egiz.bku.accesscontroller.RuleChecker.PEER_TYPE; -import at.gv.egiz.bku.slexceptions.SLRuntimeException; - -public class AccessControllerFactory { - - private static AccessControllerFactory instance = new AccessControllerFactory(); - private static Log log = LogFactory.getLog(AccessControllerFactory.class); - private static JAXBContext jaxbContext; - public static String INPUT_CHAIN = "InputChain"; - public static String OUTPUT_CHAIN = "OutputChain"; - - static { - try { - jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage() - .getName()); - } catch (JAXBException e) { - log.fatal("Cannot init jaxbContext", e); - } - } - - private Hashtable chainTable = new Hashtable(); - - private AccessControllerFactory() { - } - - public static AccessControllerFactory getInstance() { - return instance; - } - - /** - * - * @param id - * @return null if there is no chain with this id. - */ - public ChainChecker getChainChecker(String id) { - return chainTable.get(id); - } - - public ChainChecker createChainChecker(String id, boolean register) { - ChainChecker cc = new ChainChecker(id); - if (register) { - chainTable.put(id, cc); - } - return cc; - } - - public void registerChainChecker(ChainChecker cc) { - chainTable.put(cc.getId(), cc); - } - - public CommandParamChecker createParamChecker(String cmd) { - if ((cmd != null) && (cmd.startsWith("Infobox"))) { - return new InfoboxParamChecker(); - } else { - return null; - } - } - - public RuleChecker createRuleChecker(Rule rule) { - RuleChecker rc; - rc = new RuleChecker(rule.getId()); - Command cmd = rule.getCommand(); - if (cmd != null) { - rc.setCommandName(cmd.getName()); - for (Param p : cmd.getParam()) { - rc.addParameter(p.getName(), p.getValue()); - } - } - rc.setAuthenticationClass(rule.getAuthClass()); - if (rule.getIPv4Address() != null) { - rc.setPeerId(rule.getIPv4Address(), PEER_TYPE.IP); - } else if (rule.getDomainName() != null) { - rc.setPeerId(rule.getDomainName(), PEER_TYPE.HOST); - } else if (rule.getURL() != null) { - rc.setPeerId(rule.getURL(), PEER_TYPE.URL); - } - rc.setAction(rule.getAction().getRuleAction()); - rc.setChainId(rule.getAction().getChainRef()); - rc.setUserAction(rule.getUserInteraction()); - return rc; - } - - public void init(InputStream is) throws JAXBException { - chainTable.clear(); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - AccessControl ac = (AccessControl) unmarshaller.unmarshal(is); - List chainList = ac.getChains().getChain(); - log.debug("Found " + chainList.size() + " chains in config"); - for (Chain chain : chainList) { - log.trace("Creating chain: " + chain.getId()); - ChainChecker cc = createChainChecker(chain.getId(), false); - List ruleList = chain.getRules().getRule(); - log - .debug("Found " + ruleList.size() + " rules in chain " - + chain.getId()); - for (Rule rule : ruleList) { - log.trace("Creating rule: " + rule.getId()); - cc.addRule(createRuleChecker(rule)); - } - registerChainChecker(cc); - } - validate(); - } - - private void validate() { - for (ChainChecker chain : chainTable.values()) { - for (RuleChecker rule : chain.getRules()) { - if (rule.getChainId() != null) { - log.trace("Checking reference to chain: "+rule.getChainId()); - if (getChainChecker(rule.getChainId()) == null) { - throw new SLRuntimeException("Invalid reference to unknown chain: "+rule.getChainId()); - } - } - } - } - } - -} +/* +* 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 java.io.InputStream; +import java.util.Hashtable; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.accesscontrol.config.AccessControl; +import at.gv.egiz.bku.accesscontrol.config.Chain; +import at.gv.egiz.bku.accesscontrol.config.Command; +import at.gv.egiz.bku.accesscontrol.config.ObjectFactory; +import at.gv.egiz.bku.accesscontrol.config.Param; +import at.gv.egiz.bku.accesscontrol.config.Rule; +import at.gv.egiz.bku.accesscontroller.RuleChecker.PEER_TYPE; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; + +public class AccessControllerFactory { + + private static AccessControllerFactory instance = new AccessControllerFactory(); + private static JAXBContext jaxbContext; + private final Logger log = LoggerFactory.getLogger(AccessControllerFactory.class); + public static String INPUT_CHAIN = "InputChain"; + public static String OUTPUT_CHAIN = "OutputChain"; + + static { + try { + jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage() + .getName()); + } catch (JAXBException e) { + Logger log = LoggerFactory.getLogger(AccessControllerFactory.class); + log.error("Cannot init jaxbContext.", e); + } + } + + private Hashtable chainTable = new Hashtable(); + + private AccessControllerFactory() { + } + + public static AccessControllerFactory getInstance() { + return instance; + } + + /** + * + * @param id + * @return null if there is no chain with this id. + */ + public ChainChecker getChainChecker(String id) { + return chainTable.get(id); + } + + public ChainChecker createChainChecker(String id, boolean register) { + ChainChecker cc = new ChainChecker(id); + if (register) { + chainTable.put(id, cc); + } + return cc; + } + + public void registerChainChecker(ChainChecker cc) { + chainTable.put(cc.getId(), cc); + } + + public CommandParamChecker createParamChecker(String cmd) { + if ((cmd != null) && (cmd.startsWith("Infobox"))) { + return new InfoboxParamChecker(); + } else { + return null; + } + } + + public RuleChecker createRuleChecker(Rule rule) { + RuleChecker rc; + rc = new RuleChecker(rule.getId()); + Command cmd = rule.getCommand(); + if (cmd != null) { + rc.setCommandName(cmd.getName()); + for (Param p : cmd.getParam()) { + rc.addParameter(p.getName(), p.getValue()); + } + } + rc.setAuthenticationClass(rule.getAuthClass()); + if (rule.getIPv4Address() != null) { + rc.setPeerId(rule.getIPv4Address(), PEER_TYPE.IP); + } else if (rule.getDomainName() != null) { + rc.setPeerId(rule.getDomainName(), PEER_TYPE.HOST); + } else if (rule.getURL() != null) { + rc.setPeerId(rule.getURL(), PEER_TYPE.URL); + } + rc.setAction(rule.getAction().getRuleAction()); + rc.setChainId(rule.getAction().getChainRef()); + rc.setUserAction(rule.getUserInteraction()); + return rc; + } + + public void init(InputStream is) throws JAXBException { + chainTable.clear(); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + AccessControl ac = (AccessControl) unmarshaller.unmarshal(is); + List chainList = ac.getChains().getChain(); + log.debug("Found {} chains in config.", chainList.size()); + for (Chain chain : chainList) { + log.trace("Creating chain: {}.", chain.getId()); + ChainChecker cc = createChainChecker(chain.getId(), false); + List ruleList = chain.getRules().getRule(); + log.debug("Found {} rules in chain {}.", ruleList.size(), chain.getId()); + for (Rule rule : ruleList) { + log.trace("Creating rule: {}.", rule.getId()); + cc.addRule(createRuleChecker(rule)); + } + registerChainChecker(cc); + } + validate(); + } + + private void validate() { + for (ChainChecker chain : chainTable.values()) { + for (RuleChecker rule : chain.getRules()) { + if (rule.getChainId() != null) { + log.trace("Checking reference to chain: {}.", rule.getChainId()); + if (getChainChecker(rule.getChainId()) == null) { + throw new SLRuntimeException("Invalid reference to unknown chain: "+rule.getChainId()); + } + } + } + } + } + +} 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 61d3d7a5..204513e0 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,110 +1,110 @@ -/* - * 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.CERTIFIED_GOV_AGENCY; -import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.PSEUDO_ANONYMOUS; - -import java.net.URL; -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; - -public class AuthenticationClassifier { - private static AuthenticationClassifier instance = new AuthenticationClassifier(); - private static Log log = LogFactory.getLog(AuthenticationClassifier.class); - private final static String GOV_DOMAIN = ".gv.at"; - - 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> 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) - || (cert.getExtensionValue("1.2.40.0.10.1.1.2") != null)) { - return true; - } - return false; - } - - /** - * Client Certificates are currently not supported - * - */ - protected AuthenticationClass getMyAuthenticationClass(boolean isDataUrl, - URL url, X509Certificate cert) { - if (isDataUrl) { - if (url.getProtocol().equalsIgnoreCase("https")) { - if (isGovAgency(cert)) { - return CERTIFIED_GOV_AGENCY; - } - if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) { - return CERTIFIED_GOV_AGENCY; - } - return CERTIFIED; - } else { - return PSEUDO_ANONYMOUS; - } - } else { - return ANONYMOUS; - } - } - - /** - * - * @param isDataUrl - * @param url - * if the url's protocol is https a cert parameter must be provided. - * @param cert - * @return - */ - public static AuthenticationClass getAuthenticationClass(boolean isDataUrl, - URL url, X509Certificate cert) { - return instance.getMyAuthenticationClass(isDataUrl, url, cert); - } -} +/* + * 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.CERTIFIED_GOV_AGENCY; +import static at.gv.egiz.bku.accesscontroller.AuthenticationClass.PSEUDO_ANONYMOUS; + +import java.net.URL; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.Collection; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AuthenticationClassifier { + private static AuthenticationClassifier instance = new AuthenticationClassifier(); + private final static String GOV_DOMAIN = ".gv.at"; + + private AuthenticationClassifier() { + } + + public static boolean isGovAgency(X509Certificate cert) { + Logger log = LoggerFactory.getLogger(AuthenticationClassifier.class); + 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> 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("Failed to parse certificate.", e); + } + if ((cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) + || (cert.getExtensionValue("1.2.40.0.10.1.1.2") != null)) { + return true; + } + return false; + } + + /** + * Client Certificates are currently not supported + * + */ + protected AuthenticationClass getMyAuthenticationClass(boolean isDataUrl, + URL url, X509Certificate cert) { + if (isDataUrl) { + if (url.getProtocol().equalsIgnoreCase("https")) { + if (isGovAgency(cert)) { + return CERTIFIED_GOV_AGENCY; + } + if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) { + return CERTIFIED_GOV_AGENCY; + } + return CERTIFIED; + } else { + return PSEUDO_ANONYMOUS; + } + } else { + return ANONYMOUS; + } + } + + /** + * + * @param isDataUrl + * @param url + * if the url's protocol is https a cert parameter must be provided. + * @param cert + * @return + */ + public static AuthenticationClass getAuthenticationClass(boolean isDataUrl, + URL url, X509Certificate cert) { + return instance.getMyAuthenticationClass(isDataUrl, url, cert); + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java index 716f81e4..6b24dcac 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java @@ -1,91 +1,92 @@ -/* -* 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 java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slexceptions.SLException; - -public class ChainChecker implements AccessChecker { - private static Log log = LogFactory.getLog(ChainChecker.class); - - private String id; - private List rules = new LinkedList(); - - /** - * - * @param id must not be null - */ - public ChainChecker(String id) { - if (id == null) { - throw new NullPointerException("Id argument must not be null"); - } - this.id = id; - } - - - public String getId() { - return id; - } - - public void addRule(RuleChecker rule) { - if (rule != null) { - rules.add(rule); - } - } - - public List getRules() { - return Collections.unmodifiableList(rules); - } - - @Override - public ChainResult check(AccessCheckerContext checkCtx) throws SLException { - log.debug("Processing chain: "+id); - for (RuleChecker rule : rules) { - log.trace("Checking rule: "+rule.getId()); - RuleResult result = rule.check(checkCtx); - if (result.matchFound()) { - if (result.getDelegateChainId() != null) { - // process chain - ChainChecker cc = AccessControllerFactory.getInstance().getChainChecker(result.getDelegateChainId()); - if (cc == null) { - log.error("Cannot delegate to chain. Unknown chain id: "+result.getDelegateChainId()); - throw new SLException(4000); - } - ChainResult cr = cc.check(checkCtx); - if (cr.matchFound()) { - return cr; - } - // if chain does not contain matching rule - // cont. here. - } else { - return result; - } - } - } - log.debug("Did not find a matching rule here"); - return new ChainResult(null, null, false); - } - - - -} +/* +* 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 java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.slexceptions.SLException; + +public class ChainChecker implements AccessChecker { + + private final Logger log = LoggerFactory.getLogger(ChainChecker.class); + + private String id; + private List rules = new LinkedList(); + + /** + * + * @param id must not be null + */ + public ChainChecker(String id) { + if (id == null) { + throw new NullPointerException("Id argument must not be null"); + } + this.id = id; + } + + + public String getId() { + return id; + } + + public void addRule(RuleChecker rule) { + if (rule != null) { + rules.add(rule); + } + } + + public List getRules() { + return Collections.unmodifiableList(rules); + } + + @Override + public ChainResult check(AccessCheckerContext checkCtx) throws SLException { + log.debug("Processing chain: {}.", id); + for (RuleChecker rule : rules) { + log.trace("Checking rule: {}.", rule.getId()); + RuleResult result = rule.check(checkCtx); + if (result.matchFound()) { + if (result.getDelegateChainId() != null) { + // process chain + ChainChecker cc = AccessControllerFactory.getInstance().getChainChecker(result.getDelegateChainId()); + if (cc == null) { + log.error("Cannot delegate to chain. Unknown chain id: {}.", result.getDelegateChainId()); + throw new SLException(4000); + } + ChainResult cr = cc.check(checkCtx); + if (cr.matchFound()) { + return cr; + } + // if chain does not contain matching rule + // cont. here. + } else { + return result; + } + } + } + log.debug("Did not find a matching rule here."); + return new ChainResult(null, null, false); + } + + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java index 8fa328de..e7535e81 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java @@ -1,74 +1,75 @@ -/* -* 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 java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slcommands.InfoboxReadCommand; -import at.gv.egiz.bku.slcommands.SLCommand; -import at.gv.egiz.bku.slexceptions.SLRuntimeException; - -public class InfoboxParamChecker extends CommandParamChecker { - private static Log log = LogFactory.getLog(InfoboxParamChecker.class); - - public final static String INFOBOX_ID = "InfoboxIdentifier"; - public final static String PERSON_ID = "PersonIdentifier"; - public final static String DERIVED = "derived"; - - @Override - public boolean checkParameter(SLCommand cmd) { - if (paramList.size() == 0) { - return true; - } - - if (cmd instanceof InfoboxReadCommand) { - InfoboxReadCommand irc = (InfoboxReadCommand) cmd; - for (Tupel param : paramList) { - if (param.getKey().equals(INFOBOX_ID)) { - if (!param.getVal().equals(irc.getInfoboxIdentifier())) { - return false; - } - } else if (param.getKey().equals(PERSON_ID)) { - if (param.getVal().equals(DERIVED)) { - if (irc.getIdentityLinkDomainId() == null) { - return false; - } - } else { - Pattern p = Pattern.compile(param.getVal()); - Matcher m = p.matcher(irc.getIdentityLinkDomainId()); - if (!m.matches()) { - return false; - } - } - - } else { - throw new SLRuntimeException("Cannot handle parameter " - + param.getKey()); - } - } - return true; - } else { - log.error("Cannot handle parameter for command: " + cmd.getName()); - throw new SLRuntimeException("Cannot handle parameters for command: " - + cmd.getName()); - } - } -} +/* +* 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 java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.slcommands.InfoboxReadCommand; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; + +public class InfoboxParamChecker extends CommandParamChecker { + + private final Logger log = LoggerFactory.getLogger(InfoboxParamChecker.class); + + public final static String INFOBOX_ID = "InfoboxIdentifier"; + public final static String PERSON_ID = "PersonIdentifier"; + public final static String DERIVED = "derived"; + + @Override + public boolean checkParameter(SLCommand cmd) { + if (paramList.size() == 0) { + return true; + } + + if (cmd instanceof InfoboxReadCommand) { + InfoboxReadCommand irc = (InfoboxReadCommand) cmd; + for (Tupel param : paramList) { + if (param.getKey().equals(INFOBOX_ID)) { + if (!param.getVal().equals(irc.getInfoboxIdentifier())) { + return false; + } + } else if (param.getKey().equals(PERSON_ID)) { + if (param.getVal().equals(DERIVED)) { + if (irc.getIdentityLinkDomainId() == null) { + return false; + } + } else { + Pattern p = Pattern.compile(param.getVal()); + Matcher m = p.matcher(irc.getIdentityLinkDomainId()); + if (!m.matches()) { + return false; + } + } + + } else { + throw new SLRuntimeException("Cannot handle parameter " + + param.getKey()); + } + } + return true; + } else { + log.error("Cannot handle parameter for command: {}.", cmd.getName()); + throw new SLRuntimeException("Cannot handle parameters for command: " + + cmd.getName()); + } + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java index 1cba89ef..33283eda 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java @@ -1,203 +1,203 @@ -/* -* 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 java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.UnknownHostException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slcommands.SLCommand; -import at.gv.egiz.bku.slexceptions.SLRuntimeException; - -public class RuleChecker implements AccessChecker { - - private static Log log = LogFactory.getLog(RuleChecker.class); - - public static enum PEER_TYPE { - HOST, IP, URL - }; - - protected String id; - protected AuthenticationClass authenticationClass; - protected String commandName; - protected Pattern commandNamePattern; - protected String peerId; - protected Pattern peerIdPattern; - protected PEER_TYPE peerType; - protected Action action; - protected UserAction userAction; - protected String chainId; - protected CommandParamChecker paramChecker; - - public RuleChecker(String id) { - if (id == null) { - throw new NullPointerException("Id argument must not be null"); - } - this.id = id; - } - - public void setAuthenticationClass(String ac) { - if (ac != null) { - AuthenticationClass tmp = AuthenticationClass.fromString(ac); - if (tmp == null) { - throw new SLRuntimeException("Unknown authentication class " + ac); - } - authenticationClass = tmp; - } - } - - public void setAction(String ac) { - if (ac != null) { - Action tmp = Action.fromString(ac); - if (tmp == null) { - throw new SLRuntimeException("Unknown action " + ac); - } - action = tmp; - } - } - - public void setUserAction(String uac) { - if (uac != null) { - UserAction tmp = UserAction.fromString(uac); - if (tmp == null) { - throw new SLRuntimeException("Unknown user action " + uac); - } - userAction = tmp; - } - } - - public void setChainId(String chainId) { - this.chainId = chainId; - } - - public void setPeerId(String peerId, PEER_TYPE type) { - this.peerType = type; - this.peerId = peerId; - peerIdPattern = Pattern.compile(peerId); - } - - public void setCommandName(String commandName) { - this.commandName = commandName; - commandNamePattern = Pattern.compile(commandName); - paramChecker = AccessControllerFactory.getInstance().createParamChecker( - commandName); - } - - /** - * Make sure to set the commandName first - * - * @param key - * @param value - */ - public void addParameter(String key, String value) { - if (paramChecker == null) { - throw new IllegalArgumentException("Cannot set parameters for command " - + commandName); - } - paramChecker.addParameter(key, value); - } - - public String getId() { - return id; - } - - protected boolean matchAuthenticationClass(AuthenticationClass cls) { - if ((this.authenticationClass == null) || (cls == null)) { - return true; - } - return this.authenticationClass.compareTo(cls) <= 0; - } - - protected boolean matchCommandName(SLCommand cmd) { - if ((commandName == null) || (cmd == null)) { - return true; - } - Matcher matcher = commandNamePattern.matcher(cmd.getName()); - if (matcher.matches()) { - if (paramChecker != null) { - return paramChecker.checkParameter(cmd); - } else { - return true; - } - } else { - return false; - } - } - - protected boolean matchPeerId(String peerUrl) { - if ((peerId == null) || (peerUrl == null)) { - return true; - } - if (peerType == PEER_TYPE.URL) { - Matcher matcher = peerIdPattern.matcher(peerUrl); - return matcher.matches(); - } else { - try { - URL url = new URL(peerUrl); - if (peerType == PEER_TYPE.HOST) { - try { - String host = url.getHost(); - String hostName = InetAddress.getByName(host) - .getCanonicalHostName(); - Matcher matcher = peerIdPattern.matcher(hostName); - return matcher.matches(); - } catch (UnknownHostException e) { - log.error("Cannot resolve hostname", e); - return false; - } - } else { - try { - String hostAddr = InetAddress.getByName(url.getHost()) - .getHostAddress(); - Matcher matcher = peerIdPattern.matcher(hostAddr); - return matcher.matches(); - } catch (UnknownHostException e) { - log.error("Cannot resolve host address", e); - return false; - } - } - } catch (MalformedURLException e) { - log.error("Cannot parse url", e); - return false; - } - } - } - - @Override - public RuleResult check(AccessCheckerContext checkCtx) { - log.debug("Processing rule: " + id); - if (matchAuthenticationClass(checkCtx.getAuthenticationClass()) - && matchCommandName(checkCtx.getCommand()) - && matchPeerId(checkCtx.getPeerUrl())) { - log.debug("Match found for rule: " + id); - return new RuleResult(action, userAction, true, chainId); - } - log.debug("No match found for rule: " + id); - return new RuleResult(action, userAction, false, chainId); - } - - public String getChainId() { - return chainId; - } - -} +/* +* 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 java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; + +public class RuleChecker implements AccessChecker { + + private final Logger log = LoggerFactory.getLogger(RuleChecker.class); + + public static enum PEER_TYPE { + HOST, IP, URL + }; + + protected String id; + protected AuthenticationClass authenticationClass; + protected String commandName; + protected Pattern commandNamePattern; + protected String peerId; + protected Pattern peerIdPattern; + protected PEER_TYPE peerType; + protected Action action; + protected UserAction userAction; + protected String chainId; + protected CommandParamChecker paramChecker; + + public RuleChecker(String id) { + if (id == null) { + throw new NullPointerException("Id argument must not be null"); + } + this.id = id; + } + + public void setAuthenticationClass(String ac) { + if (ac != null) { + AuthenticationClass tmp = AuthenticationClass.fromString(ac); + if (tmp == null) { + throw new SLRuntimeException("Unknown authentication class " + ac); + } + authenticationClass = tmp; + } + } + + public void setAction(String ac) { + if (ac != null) { + Action tmp = Action.fromString(ac); + if (tmp == null) { + throw new SLRuntimeException("Unknown action " + ac); + } + action = tmp; + } + } + + public void setUserAction(String uac) { + if (uac != null) { + UserAction tmp = UserAction.fromString(uac); + if (tmp == null) { + throw new SLRuntimeException("Unknown user action " + uac); + } + userAction = tmp; + } + } + + public void setChainId(String chainId) { + this.chainId = chainId; + } + + public void setPeerId(String peerId, PEER_TYPE type) { + this.peerType = type; + this.peerId = peerId; + peerIdPattern = Pattern.compile(peerId); + } + + public void setCommandName(String commandName) { + this.commandName = commandName; + commandNamePattern = Pattern.compile(commandName); + paramChecker = AccessControllerFactory.getInstance().createParamChecker( + commandName); + } + + /** + * Make sure to set the commandName first + * + * @param key + * @param value + */ + public void addParameter(String key, String value) { + if (paramChecker == null) { + throw new IllegalArgumentException("Cannot set parameters for command " + + commandName); + } + paramChecker.addParameter(key, value); + } + + public String getId() { + return id; + } + + protected boolean matchAuthenticationClass(AuthenticationClass cls) { + if ((this.authenticationClass == null) || (cls == null)) { + return true; + } + return this.authenticationClass.compareTo(cls) <= 0; + } + + protected boolean matchCommandName(SLCommand cmd) { + if ((commandName == null) || (cmd == null)) { + return true; + } + Matcher matcher = commandNamePattern.matcher(cmd.getName()); + if (matcher.matches()) { + if (paramChecker != null) { + return paramChecker.checkParameter(cmd); + } else { + return true; + } + } else { + return false; + } + } + + protected boolean matchPeerId(String peerUrl) { + if ((peerId == null) || (peerUrl == null)) { + return true; + } + if (peerType == PEER_TYPE.URL) { + Matcher matcher = peerIdPattern.matcher(peerUrl); + return matcher.matches(); + } else { + try { + URL url = new URL(peerUrl); + if (peerType == PEER_TYPE.HOST) { + try { + String host = url.getHost(); + String hostName = InetAddress.getByName(host) + .getCanonicalHostName(); + Matcher matcher = peerIdPattern.matcher(hostName); + return matcher.matches(); + } catch (UnknownHostException e) { + log.error("Cannot resolve hostname.", e); + return false; + } + } else { + try { + String hostAddr = InetAddress.getByName(url.getHost()) + .getHostAddress(); + Matcher matcher = peerIdPattern.matcher(hostAddr); + return matcher.matches(); + } catch (UnknownHostException e) { + log.error("Cannot resolve host address.", e); + return false; + } + } + } catch (MalformedURLException e) { + log.error("Cannot parse url.", e); + return false; + } + } + } + + @Override + public RuleResult check(AccessCheckerContext checkCtx) { + log.debug("Processing rule: {}.", id); + if (matchAuthenticationClass(checkCtx.getAuthenticationClass()) + && matchCommandName(checkCtx.getCommand()) + && matchPeerId(checkCtx.getPeerUrl())) { + log.debug("Match found for rule: {}.", id); + return new RuleResult(action, userAction, true, chainId); + } + log.debug("No match found for rule: {}", id); + return new RuleResult(action, userAction, false, chainId); + } + + public String getChainId() { + return chainId; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java index 482d3ecb..0596f0d0 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java @@ -1,118 +1,119 @@ -/* -* 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 java.io.InputStream; - -import javax.xml.bind.JAXBException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slcommands.SLCommand; -import at.gv.egiz.bku.slcommands.SLSourceContext; -import at.gv.egiz.bku.slcommands.SLTargetContext; - -/** - * Facade for the access controller - */ -public class SecurityManagerFacade { - - private static Log log = LogFactory.getLog(SecurityManagerFacade.class); - - private boolean allowUnmatched = false; - private ChainChecker inputFilter = null; - private ChainChecker outputFilter = null; - - public boolean mayInvokeCommand(SLCommand cmd, SLSourceContext ctx) { - if (inputFilter != null) { - AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass( - ctx.isSourceIsDataURL(), ctx.getSourceUrl(), ctx - .getSourceCertificate()); - AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx - .getSourceUrl().toString()); - try { - ChainResult cr = inputFilter.check(acc); - if (cr.matchFound()) { - if (cr.getAction() == Action.ALLOW) { - return true; - } else { - return false; - } - } else { - return allowUnmatched; - } - } catch (Exception e) { - log.error(e); - return false; - } - } else { - log.warn("No input chain defined"); - return allowUnmatched; - } - } - - public boolean maySendResult(SLCommand cmd, SLTargetContext ctx) { - if (outputFilter != null) { - AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass( - ctx.isTargetIsDataURL(), ctx.getTargetUrl(), ctx - .getTargetCertificate()); - AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx - .getTargetUrl().toString()); - try { - ChainResult cr = outputFilter.check(acc); - if (cr.matchFound()) { - if (cr.getAction() == Action.ALLOW) { - return true; - } else { - return false; - } - } else { - return allowUnmatched; - } - } catch (Exception e) { - log.error(e); - return false; - } - } else { - log.warn("No output chain defined"); - return allowUnmatched; - } - } - - /** - * Default policy if not match was found - * - * @param allow - */ - public void setAllowUnmatched(boolean allow) { - this.allowUnmatched = allow; - } - - public void init(InputStream is) { - inputFilter = null; - outputFilter = null; - AccessControllerFactory fab = AccessControllerFactory.getInstance(); - try { - fab.init(is); - } catch (JAXBException e) { - log.error(e); - } - inputFilter = fab.getChainChecker(AccessControllerFactory.INPUT_CHAIN); - outputFilter = fab.getChainChecker(AccessControllerFactory.OUTPUT_CHAIN); - } -} +/* +* 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 java.io.InputStream; + +import javax.xml.bind.JAXBException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLSourceContext; +import at.gv.egiz.bku.slcommands.SLTargetContext; +import at.gv.egiz.bku.slexceptions.SLException; + +/** + * Facade for the access controller + */ +public class SecurityManagerFacade { + + private final Logger log = LoggerFactory.getLogger(SecurityManagerFacade.class); + + private boolean allowUnmatched = false; + private ChainChecker inputFilter = null; + private ChainChecker outputFilter = null; + + public boolean mayInvokeCommand(SLCommand cmd, SLSourceContext ctx) { + if (inputFilter != null) { + AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass( + ctx.isSourceIsDataURL(), ctx.getSourceUrl(), ctx + .getSourceCertificate()); + AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx + .getSourceUrl().toString()); + try { + ChainResult cr = inputFilter.check(acc); + if (cr.matchFound()) { + if (cr.getAction() == Action.ALLOW) { + return true; + } else { + return false; + } + } else { + return allowUnmatched; + } + } catch (SLException e) { + log.error("Check failed.", e); + return false; + } + } else { + log.warn("No input chain defined."); + return allowUnmatched; + } + } + + public boolean maySendResult(SLCommand cmd, SLTargetContext ctx) { + if (outputFilter != null) { + AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass( + ctx.isTargetIsDataURL(), ctx.getTargetUrl(), ctx + .getTargetCertificate()); + AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx + .getTargetUrl().toString()); + try { + ChainResult cr = outputFilter.check(acc); + if (cr.matchFound()) { + if (cr.getAction() == Action.ALLOW) { + return true; + } else { + return false; + } + } else { + return allowUnmatched; + } + } catch (SLException e) { + log.error("Check failed.", e); + return false; + } + } else { + log.warn("No output chain defined."); + return allowUnmatched; + } + } + + /** + * Default policy if not match was found + * + * @param allow + */ + public void setAllowUnmatched(boolean allow) { + this.allowUnmatched = allow; + } + + public void init(InputStream is) { + inputFilter = null; + outputFilter = null; + AccessControllerFactory fab = AccessControllerFactory.getInstance(); + try { + fab.init(is); + } catch (JAXBException e) { + log.error("Failed to initialize AccessControllerFactory.", e); + } + inputFilter = fab.getChainChecker(AccessControllerFactory.INPUT_CHAIN); + outputFilter = fab.getChainChecker(AccessControllerFactory.OUTPUT_CHAIN); + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java index 23f62134..5201e817 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java @@ -16,74 +16,119 @@ */ package at.gv.egiz.bku.binding; -import at.gv.egiz.bku.conf.Configuration; -import java.io.InputStream; import java.util.Date; +import java.util.Locale; +import org.apache.commons.configuration.Configuration; +import org.slf4j.MDC; + +import at.gv.egiz.bku.slcommands.SLCommandFactory; import at.gv.egiz.bku.slcommands.SLCommandInvoker; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; import at.gv.egiz.stal.STAL; public abstract class AbstractBindingProcessor implements BindingProcessor { + + protected Configuration configuration; + + protected SLCommandFactory slCommandFactory; + + protected Locale locale = Locale.getDefault(); + protected Id id; - protected Configuration config; protected STAL stal; protected SLCommandInvoker commandInvoker; + protected long lastAccessedTime = System.currentTimeMillis(); - public AbstractBindingProcessor(String idString) { - this.id = IdFactory.getInstance().createId(idString); + protected URLDereferencer urlDereferencer; + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; } - /** - * @see java.lang.Thread#run() - */ - public abstract void run(); + @Override + public void setSlCommandFactory(SLCommandFactory slCommandFactory) { + this.slCommandFactory = slCommandFactory; + } - /** - * The caller is advised to check the result in case an error occurred. - * - * @see #getResult() - */ - public abstract void consumeRequestStream(InputStream aIs); + @Override + public void setLocale(Locale locale) { + if (locale == null) { + throw new NullPointerException("Locale must not be set to null."); + } + this.locale = locale; + } + + @Override + public void init(String id, STAL stal, SLCommandInvoker commandInvoker) { + if (id == null) { + throw new NullPointerException("Id must not be null."); + } + if (stal == null) { + throw new NullPointerException("STAL must not null."); + } + if (commandInvoker == null) { + throw new NullPointerException("CommandInvoker must null."); + } + this.id = IdFactory.getInstance().createId(id); + this.stal = stal; + this.commandInvoker = commandInvoker; + } + @Override public Id getId() { return id; } + @Override public STAL getSTAL() { return stal; } + @Override public SLCommandInvoker getCommandInvoker() { return commandInvoker; } - + + @Override public void updateLastAccessTime() { lastAccessedTime = System.currentTimeMillis(); } + @Override public Date getLastAccessTime() { return new Date(lastAccessedTime); } - /** - * To be called after object creation. - * - * @param aStal - * must not be null - * @param aCommandInvoker - * must not be null - */ - public void init(STAL aStal, SLCommandInvoker aCommandInvoker, Configuration conf) { - if (aStal == null) { - throw new NullPointerException("STAL must not be set to null"); + @Override + public void run() { + + if (this.id != null) { + MDC.put("id", this.id.toString()); } - if (aCommandInvoker == null) { - throw new NullPointerException("Commandinvoker must not be set to null"); + try { + process(); + } finally { + MDC.remove("id"); } - config = conf; - stal = aStal; - commandInvoker = aCommandInvoker; - Thread.currentThread().setName("BPID#"+getId().toString()); + + } + + public abstract void process(); + + /** + * @return the urlDereferencer + */ + public URLDereferencer getUrlDereferencer() { + return urlDereferencer; + } + + /** + * @param urlDereferencer the urlDereferencer to set + */ + public void setUrlDereferencer(URLDereferencer urlDereferencer) { + this.urlDereferencer = urlDereferencer; } + } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java new file mode 100644 index 00000000..8cf71260 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessorFactory.java @@ -0,0 +1,81 @@ +/* +* Copyright 2009 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.binding; + +import java.util.Set; + +import org.apache.commons.configuration.Configuration; + +import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.utils.binding.Protocol; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; + + +public abstract class AbstractBindingProcessorFactory implements BindingProcessorFactory { + + protected Set supportedProtocols; + protected SLCommandFactory slCommandFactory; + protected Configuration configuration; + protected URLDereferencer urlDereferencer; + + @Override + public Set getSupportedProtocols() { + return supportedProtocols; + } + + @Override + public SLCommandFactory getSlCommandFactory() { + return slCommandFactory; + } + + @Override + public void setSlCommandFactory(SLCommandFactory slCommandFactory) { + this.slCommandFactory = slCommandFactory; + } + + @Override + public Configuration getConfiguration() { + return configuration; + } + + @Override + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + /** + * @return the urlDereferencer + */ + public URLDereferencer getUrlDereferencer() { + return urlDereferencer; + } + + /** + * @param urlDereferencer the urlDereferencer to set + */ + public void setUrlDereferencer(URLDereferencer urlDereferencer) { + this.urlDereferencer = urlDereferencer; + } + + protected void configureBindingProcessor(AbstractBindingProcessor bindingProcessor) { + bindingProcessor.setConfiguration(configuration); + bindingProcessor.setSlCommandFactory(slCommandFactory); + bindingProcessor.setUrlDereferencer(urlDereferencer); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java index 0d978992..148fe296 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java @@ -1,78 +1,147 @@ /* -* 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.binding; -import at.gv.egiz.bku.conf.Configuration; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import java.util.Locale; +import at.gv.egiz.bku.slcommands.SLCommandFactory; import at.gv.egiz.bku.slcommands.SLCommandInvoker; import at.gv.egiz.stal.STAL; /** - * Represents an single instance of a SL HTTP binding. + * BindingProcessors implement the processing of a specific protocol binding + * (e.g. HTTP) for Security Layer requests. * - * @author wbauer - * + * @author wbauer, mcentner */ public interface BindingProcessor extends Runnable { /** - * The stream must be read completely within this method. + * Sets the command factory for creating Security Layer. Must be set before + * {@link #consumeRequestStream(String, InputStream)} is called. + * + * @param slCommandFactory + * the command factory for creating Security Layer commands. + */ + void setSlCommandFactory(SLCommandFactory slCommandFactory); + + /** + * Sets the preferred locale for user interaction. If the locale is not set + * the default locale will be used. Should be set before + * {@link #consumeRequestStream(String, InputStream)} is called to allow for a + * proper localization. + * + * @param locale + * must not be null. + */ + public void setLocale(Locale locale); + + /** + * Instructs this BindingProcessor to consume the request + * inputStream. + *

+ * Implementing classes are assumed to read the entire provided + * inputStream + *

+ *

+ * Any errors are reported via the result produced by this BindingProcessor. + *

* - * The caller is advised to check the result in case an error occurred. + * @param url + * the URL request is associated with (e.g. has been received on). + * + * @see BindingProcessor#writeResultTo(OutputStream, String) + */ + public void consumeRequestStream(String url, InputStream aIs); + + /** + * Initialize this BindingProcessor for processing. This method must be called + * before {@link #run()} is called. * - * @see #getResult() + * @param id + * the (unique) processing id (usually a HTTP session id) + * @param stal + * the STAL + * @param commandInvoker + * the CommandInvoker + * @throws NullPointerException + * if one of the provided parameters is null */ - public void consumeRequestStream(InputStream aIs); + public void init(String id, STAL stal, SLCommandInvoker commandInvoker); /** - * The unique Id of this http binding instance. - * @return + * Returns the unique processing id. + * + * @return the unique processing id or null if not yet assigned. */ public Id getId(); /** - * The used underlying STAL instance - * @return + * Returns the STAL used for processing. + * + * @return the STAL used for processing or null if not yet + * assigned. */ public STAL getSTAL(); + /** + * Returns the CommandInvoker used for processing. + * + * @return the CommandInvoker used for processing or null if not + * yet assigned. + */ public SLCommandInvoker getCommandInvoker(); - public Date getLastAccessTime(); - - public void updateLastAccessTime(); - + /** + * Returns the ContentType of the processing result. + * + * @return the ContentType type of the processing result or + * null if a result is not yet available. + */ public String getResultContentType(); - - public void writeResultTo(OutputStream os, String encoding) throws IOException; - public void init(STAL aStal, SLCommandInvoker aCommandInvoker, Configuration config); - /** - * Sets the preferred locale for userinteraction. - * If the locale is not set the default locale will be used. - * @param locale must not be null. - */ - public void setLocale(Locale locale); - - public boolean isFinished(); + * Writes the processing result to the given outputStream using + * the given character encoding. + * + * @param outputStream + * the OutputStream to write the result to + * @param encoding + * the character encoding to be used + * @throws IOException + * if writing to outputStream fails for any reason + */ + public void writeResultTo(OutputStream outputStream, String encoding) + throws IOException; + + /** + * Returns the time of the last access to this BindingProcessor instance. + * + * @return the time of the last access to this BindingProcessor instance. + */ + public Date getLastAccessTime(); + + /** + * Updates the time this BindingProcessor was accessed last. + */ + public void updateLastAccessTime(); + } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java new file mode 100644 index 00000000..ac922974 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFactory.java @@ -0,0 +1,42 @@ +/* +* Copyright 2009 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.binding; + +import java.util.Set; + +import org.apache.commons.configuration.Configuration; + +import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.utils.binding.Protocol; + + +public interface BindingProcessorFactory { + + public Set getSupportedProtocols(); + + public void setConfiguration(Configuration configuration); + + public Configuration getConfiguration(); + + public void setSlCommandFactory(SLCommandFactory commandFactory); + + public SLCommandFactory getSlCommandFactory(); + + public BindingProcessor createBindingProcessor(); + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java new file mode 100644 index 00000000..f0c65323 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorFuture.java @@ -0,0 +1,73 @@ +/* +* Copyright 2009 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.binding; + +import java.util.concurrent.FutureTask; + +public class BindingProcessorFuture extends FutureTask { + + private BindingProcessor bindingProcessor; + + private long startTime; + + private long executionTime; + + public BindingProcessorFuture(BindingProcessor bindingProcessor) { + super(bindingProcessor, null); + this.bindingProcessor = bindingProcessor; + } + + /** + * @return the bindingProcessor + */ + public BindingProcessor getBindingProcessor() { + return bindingProcessor; + } + + /* (non-Javadoc) + * @see java.util.concurrent.FutureTask#run() + */ + @Override + public void run() { + startTime = System.currentTimeMillis(); + try { + super.run(); + } finally { + executionTime = System.currentTimeMillis() - startTime; + } + } + + /** + * @return the startTime + */ + public long getStartTime() { + return startTime; + } + + /** + * @return the executionTime + */ + public long getExecutionTime() { + return executionTime; + } + + public long getAge() { + return System.currentTimeMillis() - startTime; + } + +} 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 9cad95a4..f32d3c4b 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 @@ -1,107 +1,103 @@ /* -* 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.binding; -import java.net.MalformedURLException; import java.util.Locale; import java.util.Set; -import at.gv.egiz.bku.slcommands.SLCommandInvoker; -import at.gv.egiz.stal.STALFactory; - /** - * Central player that handles the protocol binding. - * - * @author wbauer + * A BindingProcessorManager provides factory methods for creating + * BindingProcessors and allows for scheduling them for processing. * + * @author wbauer, mcentner */ public interface BindingProcessorManager { /** - * FactoryMethod creating a new BindingProcessor object. - * The created binding processor must be passed to the process method to execute. + * Creates a new BindingProcessor for the given protocol. * - * @param urlString - * the source url - * @param aSessionId - * optional an external sessionId (e.g. http session) could be - * provided. This parameter may be null. - * @param locale the locale used for user interaction, may be null + * @param protocol + * the name of the protocol binding the created BindingProcessor is + * required to implement + * @param locale + * the locale to be used by the binding processor, may be + * null */ - public BindingProcessor createBindingProcessor(String urlString, - String aSessionId, Locale locale) throws MalformedURLException; + public BindingProcessor createBindingProcessor(String protocol, Locale locale); /** - * FactoryMethod creating a new BindingProcessor object. - * The created binding processor must be passed to the process method to execute. + * Creates a new BindingProcessor for the given protocol. * - * @param protcol - * the source url - * @param aSessionId - * optional an external sessionId (e.g. http session) could be - * provided. This parameter may be null. + * @param protocol + * the name of the protocol binding the created BindingProcessor is + * required to implement */ - public BindingProcessor createBindingProcessor(String urlString, - String aSessionId) throws MalformedURLException; + public BindingProcessor createBindingProcessor(String protocol); - /** - * Gets the binding processor with a certain id. The binding processor must be passed to the - * process method before it is managed and thus returned by this method. - * @param aId must not be null - * @return null if the binding processor was not "processed" before. + * Returns the BindingProcessor which has been scheduled for processing with + * the given id. + * + * @param id + * the processing id of the requested BindingProcessor + * + * @return the BindingProcessor which has been scheduled for processing with + * the given id, or null if no + * BindingProcessor has been scheduled with the given id. */ - public BindingProcessor getBindingProcessor(Id aId); + public BindingProcessor getBindingProcessor(Id id); /** - * Sets the STAL factory that is used for creating STAL objects that are used by BindingProcessor objects. - * For each new BindingProcessor a new STAL object is created. - * @param aStalFactory the factory to be used. Must not be null. + * Schedules the given BindingProcessor for processing. + *

+ *

    + *
  1. Creates a processing context with the given id.
  2. + *
  3. Schedules the given BindingProcessor for processing, and
  4. + *
  5. Immediately returns the processing context.
  6. + *
+ *

+ * + * @param id + * @param bindingProcessor */ - public void setSTALFactory(STALFactory aStalFactory); - + public BindingProcessorFuture process(Id id, BindingProcessor bindingProcessor); + /** - * Sets the invoker to be used. - * @param invoker + * Removes the BindingProcessor with the given processing id. + * + * @param id + * the processing id of the BindingProcessor to be removed */ - public void setSLCommandInvoker(SLCommandInvoker invoker); + public void removeBindingProcessor(Id id); /** - * Creates a processing context, - * schedules the provided binding processor for processing and - * immediately returns the context. + * Returns the set of Ids of currently managed BindingProcessor. * - * @param aBindingProcessor + * @return the set of Ids of currently managed BindingProcessor. */ - public ProcessingContext process(BindingProcessor aBindingProcessor); - + public Set getManagedIds(); + /** - * Removes a formerly added (by calling the process method) binding processor. - * @param bindingProcessor must not be null + * Schedule shutdown of this BindingProcessorManager. */ - public void removeBindingProcessor(Id sessionId); - + public void shutdown(); + /** - * A set of all managed binding processors. - * @return + * Immediately shutdown this BindingProcessorManager. */ - public Set getManagedIds(); - - 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 bf9a63e2..eee80b03 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 @@ -16,315 +16,283 @@ */ package at.gv.egiz.bku.binding; -import at.gv.egiz.bku.conf.Configuration; -import java.net.MalformedURLException; -import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.apache.commons.configuration.Configuration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import at.gv.egiz.bku.jmx.ComponentMXBean; +import at.gv.egiz.bku.jmx.ComponentState; import at.gv.egiz.bku.slcommands.SLCommandInvoker; import at.gv.egiz.bku.slexceptions.SLRuntimeException; import at.gv.egiz.bku.utils.binding.Protocol; -import at.gv.egiz.stal.STAL; import at.gv.egiz.stal.STALFactory; /** * This class maintains all active BindingProcessor Objects. Currently, only * HTTPBinding is supported. */ -public class BindingProcessorManagerImpl implements BindingProcessorManager { +public class BindingProcessorManagerImpl implements BindingProcessorManager, ComponentMXBean { + + public static long DEFAULT_MAX_ACCEPTED_AGE = 2 * 60 * 1000; + + public static int DEFAULT_CLEAN_UP_INTERVAL = 60; - public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP, - Protocol.HTTPS }; + private final Logger log = LoggerFactory.getLogger(BindingProcessorManagerImpl.class); - private static Log log = LogFactory.getLog(BindingProcessorManagerImpl.class); + private List factories = Collections.emptyList(); - /** spring injected config - * Passed to created bindingprocessors, to replace their configuration */ - protected Configuration config; + private Configuration configuration; - protected STALFactory stalFactory; - protected SLCommandInvoker commandInvokerClass; + private STALFactory stalFactory; + + private SLCommandInvoker commandInvoker; - private RemovalStrategy removalStrategy; - private ExecutorService executorService; - private Map contextMap = Collections.synchronizedMap(new HashMap()); -// private Map bindingProcessorMap = Collections -// .synchronizedMap(new HashMap()); + private ExecutorService executorService = Executors.newCachedThreadPool(); + private Map submittedFutures = Collections + .synchronizedMap(new HashMap()); + + private int cleanUpInterval = DEFAULT_CLEAN_UP_INTERVAL; + + private long maxAcceptedAge = DEFAULT_MAX_ACCEPTED_AGE; + + private ScheduledExecutorService cleanUpService = Executors + .newSingleThreadScheduledExecutor(); + + public BindingProcessorManagerImpl() { + cleanUpService.scheduleAtFixedRate(new CleanUpTask(), cleanUpInterval, + cleanUpInterval, TimeUnit.SECONDS); + } + /** - * Container to hold a Future and Bindingprocessor object as map value. - * - * @author wbauer - * @see BindingProcessorManagerImpl#bindingProcessorMap + * @return the configuration */ -// static class MapEntityWrapper { -// private Future future; -// private BindingProcessor bindingProcessor; -// -// public MapEntityWrapper(Future future, BindingProcessor bindingProcessor) { -// if ((bindingProcessor == null) || (future == null)) { -// throw new NullPointerException("Argument must not be null"); -// } -// this.bindingProcessor = bindingProcessor; -// this.future = future; -// } -// -// public Future getFuture() { -// return future; -// } -// -// public BindingProcessor getBindingProcessor() { -// return bindingProcessor; -// } -// -// public int hashCode() { -// return bindingProcessor.getId().hashCode(); -// } -// -// public boolean equals(Object other) { -// if (other instanceof MapEntityWrapper) { -// MapEntityWrapper o = (MapEntityWrapper) other; -// return (o.bindingProcessor.getId().equals(bindingProcessor.getId())); -// } else { -// return false; -// } -// } -// } + public Configuration getConfiguration() { + return configuration; + } /** - * - * @param fab - * must not be null - * @param ci - * must not be null (prototype to generate new instances) + * @param configuration the configuration to set */ - public BindingProcessorManagerImpl(STALFactory fab, SLCommandInvoker ci, Configuration conf) { - if (fab == null) { - throw new NullPointerException("STALFactory must not be null"); - } - stalFactory = fab; - if (ci == null) { - throw new NullPointerException("SLCommandInvoker must not be null"); - } - commandInvokerClass = ci; - config = conf; - executorService = Executors.newCachedThreadPool(); + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; } /** - * - * @return the STALFactory currently used. + * @return the factoryMap */ - public STALFactory getStalFactory() { - return stalFactory; + public List getFactories() { + return factories; } /** - * Sets the STALFactory to be used. - * - * @param stalFactory + * @param factoryMap the factoryMap to set */ - public void setStalFactory(STALFactory stalFactory) { - this.stalFactory = stalFactory; + public void setFactories(List factories) { + this.factories = factories; } /** - * Could be used to setup a new executor service during application stratup. + * Sets a SLCommandInvoker prototype used to create a SLCommandInvoker for + * initialization of a BindingProcessor. * - * @param executorService + * @param invoker + */ + public void setSlCommandInvoker(SLCommandInvoker invoker) { + commandInvoker = invoker; + } + + /** + * @return the SLCommandInvoker prototype used to create a SLCommandInvoker + * for initialization of a BindingProcessor. */ - public void setExecutorService(ExecutorService executorService) { - this.executorService = executorService; + public SLCommandInvoker getCommandInvoker() { + return commandInvoker; } - public void setRemovalStrategy(RemovalStrategy aStrategy) { - removalStrategy = aStrategy; + /** + * @return the STALFactory currently used. + */ + public STALFactory getStalFactory() { + return stalFactory; } - public RemovalStrategy getRemovlaStrategy() { - return removalStrategy; + /** + * Sets the STALFactory used to create a STAL implementation for initialization of + * a BindingProcessor. + * + * @param stalFactory + */ + public void setStalFactory(STALFactory stalFactory) { + this.stalFactory = stalFactory; } + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#shutdown() + */ + @Override public void shutdown() { - log.info("Shutting down the BindingProcessorManager"); + log.info("Shutting down the BindingProcessorManager."); executorService.shutdown(); + cleanUpService.shutdown(); } + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#shutdownNow() + */ + @Override public void shutdownNow() { log.info("Shutting down the BindingProcessorManager NOW!"); + cleanUpService.shutdownNow(); executorService.shutdownNow(); - log.debug("Number of binding contexts currently managed: " - + contextMap.size()); -// + bindingProcessorMap.size()); + log.debug("Number of binding contexts currently managed: {}.", submittedFutures.size()); if (log.isDebugEnabled()) { - for (ProcessingContext ctx : contextMap.values()) { - Id bpId = ctx.getBindingProcessor().getId(); - Future future = ctx.getFuture(); - log.debug(bpId + " cancelled: " + future.isCancelled()); - log.debug(bpId + " done: " + future.isDone()); + for (BindingProcessorFuture future : submittedFutures.values()) { + if (future.isCancelled()) { + log.debug("BindingProcessor {} is cancelled.", future.getBindingProcessor().getId()); + } else { + log.debug("BindingProcessor {} is done: {}.", future.getBindingProcessor().getId(), future.isDone()); + } } -// for (Iterator it = bindingProcessorMap.values() -// .iterator(); it.hasNext();) { -// MapEntityWrapper entry = it.next(); -// log.debug(entry.getBindingProcessor().getId() + ": isDone: " -// + entry.getFuture().isDone()); -// log.debug(entry.getBindingProcessor().getId() + ": isCanceled: " -// + entry.getFuture().isCancelled()); -// } } } - /** - * Uses the default locale + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#createBindingProcessor(java.lang.String, java.lang.String) */ - public BindingProcessor createBindingProcessor(String srcUrl, - String aSessionId) throws MalformedURLException { - return createBindingProcessor(srcUrl, aSessionId, null); + @Override + public BindingProcessor createBindingProcessor(String protocol) { + Protocol p = Protocol.fromString(protocol); + for (BindingProcessorFactory factory : factories) { + if (factory.getSupportedProtocols().contains(p)) { + return factory.createBindingProcessor(); + } + } + throw new IllegalArgumentException(); } - /** - * FactoryMethod creating a new BindingProcessor object. - * - * @param protocol - * must not be null - * @throws MalformedURLException + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#createBindingProcessor(java.lang.String, java.lang.String, java.util.Locale) */ - public BindingProcessor createBindingProcessor(String srcUrl, - String aSessionId, Locale locale) throws MalformedURLException { - URL url = new URL(srcUrl); - String low = url.getProtocol().toLowerCase(); - Protocol proto = null; - for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) { - if (SUPPORTED_PROTOCOLS[i].toString().equals(low)) { - proto = SUPPORTED_PROTOCOLS[i]; - break; - } - } - if (proto == null) { - throw new UnsupportedOperationException(); - } - BindingProcessor bindingProcessor = new HTTPBindingProcessor(aSessionId, - commandInvokerClass.newInstance(), url); - stalFactory.setLocale(locale); - STAL stal = stalFactory.createSTAL(); - bindingProcessor.init(stal, commandInvokerClass.newInstance(), config); - if (locale != null) { - bindingProcessor.setLocale(locale); -// stal.setLocale(locale); - } + @Override + public BindingProcessor createBindingProcessor(String protocol, Locale locale) { + BindingProcessor bindingProcessor = createBindingProcessor(protocol); + bindingProcessor.setLocale(locale); return bindingProcessor; } - /** - * @return the bindingprocessor object for this id or null if no - * bindingprocessor was found. + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#process(java.lang.String, at.gv.egiz.bku.binding.BindingProcessor) */ - @Override - public BindingProcessor getBindingProcessor(Id aId) { -// if (bindingProcessorMap.get(aId) != null) { -// return bindingProcessorMap.get(aId).getBindingProcessor(); - ProcessingContext ctx = contextMap.get(aId); - if (ctx != null) { - return ctx.getBindingProcessor(); - } else { - return null; + @Override + public BindingProcessorFuture process(Id id, BindingProcessor bindingProcessor) { + + log.trace("Initialize BindingProcessor for processing."); + bindingProcessor.init(id.toString(), stalFactory.createSTAL(), commandInvoker.newInstance()); + + BindingProcessorFuture future = new BindingProcessorFuture(bindingProcessor); + if (submittedFutures.containsKey(bindingProcessor.getId())) { + log.error("BindingProcessor with with id {} already submitted.", id); + throw new SLRuntimeException("BindingProcessor with with id " + id + + " already submitted."); } + + try { + log.debug("Submitting BindingProcessor {} for processing.", id); + executorService.execute(future); + submittedFutures.put(bindingProcessor.getId(), future); + } catch (RejectedExecutionException e) { + log.error("BindingProcessor {} processing rejected.", id, e); + throw new SLRuntimeException("BindingProcessor {} " + id + " processing rejected.", e); + } + + return future; + } - /** - * + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#getBindingProcessor(at.gv.egiz.bku.binding.Id) */ - @Override - public void setSTALFactory(STALFactory aStalFactory) { - if (aStalFactory == null) { - throw new NullPointerException("Cannot set STALFactory to null"); + @Override + public BindingProcessor getBindingProcessor(Id id) { + BindingProcessorFuture future = submittedFutures.get(id); + if (future != null) { + return future.getBindingProcessor(); + } else { + return null; } - stalFactory = aStalFactory; } - /** - * Causes the BindingProcessorManager to manage the provided BindingProcessor - * Creates a processing context, - * schedules the provided binding processor for processing and - * immediately returns the context. - * - * @param aBindingProcessor - * must not be null + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#removeBindingProcessor(at.gv.egiz.bku.binding.Id) */ @Override - public ProcessingContext process(BindingProcessor aBindingProcessor) { - if (contextMap.containsKey(aBindingProcessor.getId())) { -// if (bindingProcessorMap.containsKey(aBindingProcessor.getId())) { - log.fatal("Clashing ids, cannot process bindingprocessor with id:" - + aBindingProcessor.getId()); - throw new SLRuntimeException( - "Clashing ids, cannot process bindingprocessor with id:" - + aBindingProcessor.getId()); + public void removeBindingProcessor(Id id) { + BindingProcessorFuture future = submittedFutures.remove(id); + if (future != null) { + if (!future.isDone()) { + log.debug("Interrupting BindingProcessor {}.", id ); + future.cancel(true); + } + if (log.isInfoEnabled()) { + Object[] args = {id, future.getExecutionTime() / 1000.0, future.getAge() / 1000.0}; + log.info("Removing BindingProcessor {} (active:{}s/age:{}s).", args); + } } - log.debug("processing bindingprocessor: " + aBindingProcessor.getId()); - Future f = executorService.submit(aBindingProcessor); - ProcessingContext ctx = new ProcessingContext(aBindingProcessor, f); - contextMap.put(aBindingProcessor.getId(), ctx); -// bindingProcessorMap.put(aBindingProcessor.getId(), new MapEntityWrapper(f, -// aBindingProcessor)); - return ctx; } + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.BindingProcessorManager#getManagedIds() + */ @Override - public void setSLCommandInvoker(SLCommandInvoker invoker) { - commandInvokerClass = invoker; + public Set getManagedIds() { + return Collections.unmodifiableSet(new HashSet(submittedFutures.keySet())); } + /* (non-Javadoc) + * @see at.gv.egiz.bku.jmx.ComponentMXBean#checkComponentState() + */ @Override - public void removeBindingProcessor(Id sessionId) { - log.debug("Removing binding processor: " + sessionId); - ProcessingContext ctx = contextMap.get(sessionId); - if (ctx == null) { - log.warn("no processing context to remove for session " + sessionId); - return; - } - Future f = ctx.getFuture(); - -// MapEntityWrapper wrapper = bindingProcessorMap.get(sessionId); -// if (wrapper == null) { -// return; -// } -// Future f = wrapper.getFuture(); - - if (!f.isDone()) { - log.trace("canceling " + sessionId); - f.cancel(true); - } - contextMap.remove(sessionId); -// bindingProcessorMap.remove(sessionId); + public ComponentState checkComponentState() { + return new ComponentState(true); } - - @Override - public Set getManagedIds() { - Set result = new HashSet(); - synchronized (contextMap) { - for (Id id : contextMap.keySet()) { - result.add(id); + + public class CleanUpTask implements Runnable { + + @Override + public void run() { + Collection futures = submittedFutures.values(); + List toBeRemoved = new ArrayList(); + int active = 0; + for(BindingProcessorFuture future : futures) { + BindingProcessor bindingProcessor = future.getBindingProcessor(); + if (!future.isDone()) { + active++; + } + if ((bindingProcessor.getLastAccessTime().getTime() - System + .currentTimeMillis()) > maxAcceptedAge) { + toBeRemoved.add(bindingProcessor.getId()); + } + } + for (Id id : toBeRemoved) { + removeBindingProcessor(id); } } -// synchronized (bindingProcessorMap) { -// for (Iterator it = bindingProcessorMap.keySet().iterator(); it -// .hasNext();) { -// result.add(it.next()); -// } -// } - return result; + } -} \ No newline at end of file +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java new file mode 100644 index 00000000..d6e5c701 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataURLConnectionFactory.java @@ -0,0 +1,26 @@ +/* +* Copyright 2009 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.binding; + +import java.net.URL; + +public abstract class DataURLConnectionFactory { + + public abstract DataUrlConnection openConnection(URL url); + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java index d3945253..f267f9a9 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java @@ -16,18 +16,9 @@ */ package at.gv.egiz.bku.binding; -import at.gv.egiz.bku.conf.Configurator; +import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.Properties; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSocketFactory; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slexceptions.SLRuntimeException; /** * Used to handle DataUrl connections as specified in the CCE's HTTP protocol binding. @@ -35,77 +26,37 @@ import at.gv.egiz.bku.slexceptions.SLRuntimeException; */ public class DataUrl { - private static Log log = LogFactory.getLog(DataUrl.class); - private static DataUrlConnectionSPI connection; - private static Properties configuration; - private static SSLSocketFactory sslSocketFactory; - private static HostnameVerifier hostNameVerifier; - private URL url; - - /** spring injected config, to replace configuration */ - //private Configuration config; - + private static DataURLConnectionFactory connectionFactory; + /** - * Sets the default DataUrlConnection implementation - * @param aClass must not be null + * @return the connectionFactory */ - static void setDataUrlConnectionImpl(DataUrlConnectionSPI conn) { - if (conn != null) { - connection = conn; - } - } - - public DataUrl(String aUrlString) throws MalformedURLException { - url = new URL(aUrlString); - if (connection == null) { - log.debug("Using default DataURLConnection class"); - connection = new DataUrlConnectionImpl(); - } - connection.setConfiguration(configuration); - connection.setSSLSocketFactory(sslSocketFactory); - connection.setHostnameVerifier(hostNameVerifier); + public static DataURLConnectionFactory getConnectionFactory() { + return connectionFactory; } - public DataUrlConnection openConnection() { - try { - log.debug("Opening dataurl connection"); - DataUrlConnectionSPI retVal = connection.newInstance(); - retVal.init(url); - return retVal; - } catch (Exception e) { - log.error(e); - throw new SLRuntimeException("Cannot instantiate a dataurlconnection:", e); - } - } - - /** - * set configuration for all subsequently instantiated DataURL objects - * @param props + * @param connectionFactory the connectionFactory to set */ - public static void setConfiguration(Properties props) { - configuration = props; - if (configuration != null) { - String className = configuration.getProperty(Configurator.DATAURLCONNECTION_CONFIG_P); - if (className != null) { - log.warn("Set DataURLConnection class not supported!"); - } - } + public static void setConnectionFactory( + DataURLConnectionFactory connectionFactory) { + DataUrl.connectionFactory = connectionFactory; } /** - * set SSLSocketFactory for all subsequently instantiated DataURL objects - * @param socketFactory + * The URL. */ - public static void setSSLSocketFactory(SSLSocketFactory socketFactory) { - sslSocketFactory = socketFactory; + private URL url; + + public DataUrl(String spec) throws MalformedURLException { + url = new URL(spec); } - /** - * set HostnameVerifier for all subsequently instantiated DataURL objects - * @param hostNameVerifier - */ - public static void setHostNameVerifier(HostnameVerifier hostNameVerifier) { - DataUrl.hostNameVerifier = hostNameVerifier; + public DataUrlConnection openConnection() throws IOException { + if (connectionFactory != null) { + return connectionFactory.openConnection(url); + } else { + return new DataUrlConnectionImpl(url); + } } } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java index 384cf71c..13b1e627 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java @@ -1,82 +1,92 @@ /* -* 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.binding; import java.io.IOException; -import java.io.InputStream; import java.net.SocketTimeoutException; import java.net.URL; -import java.security.cert.X509Certificate; +import java.net.URLConnection; import at.gv.egiz.bku.slcommands.SLResult; /** - * Transmit a security layer result to DataURL via HTTP POST, encoded as multipart/form-data. - * The HTTP header user-agent is set to citizen-card-environment/1.2 BKU2 1.0. - * The form-parameter ResponseType is set to HTTP-Security-Layer-RESPONSE. - * All other headers/parameters are set by the caller. + * Transmit a security layer result to DataURL via HTTP POST, encoded as + * multipart/form-data. The HTTP header user-agent is set to + * citizen-card-environment/1.2 BKU2 1.0. The form-parameter + * ResponseType is set to HTTP-Security-Layer-RESPONSE. All other + * headers/parameters are set by the caller. * * @author clemens */ -public interface DataUrlConnection { +public abstract class DataUrlConnection { + + public static final String FORMPARAM_RESPONSETYPE = "ResponseType"; + public static final String DEFAULT_RESPONSETYPE = "HTTP-Security-Layer-RESPONSE"; + public static final String FORMPARAM_XMLRESPONSE = "XMLResponse"; + public static final String FORMPARAM_BINARYRESPONSE = "BinaryResponse"; + + public static final String XML_RESPONSE_ENCODING = "UTF-8"; - public static final String FORMPARAM_RESPONSETYPE = "ResponseType"; - public static final String DEFAULT_RESPONSETYPE = "HTTP-Security-Layer-RESPONSE"; - public static final String FORMPARAM_XMLRESPONSE = "XMLResponse"; - public static final String FORMPARAM_BINARYRESPONSE = "BinaryResponse"; - - public static final String XML_RESPONSE_ENCODING = "UTF-8"; + /** + * The URL to send responses and retrieve any further requests. + */ + protected URL url; - - public String getProtocol(); - - public URL getUrl(); - - /** - * Set a HTTP Header. - * @param key - * @param value multiple values are assumed to have the correct formatting (comma-separated list) - */ - public void setHTTPHeader(String key, String value); + /** + * Constructs a DataURL connection to the specified URL. + * + * @param url + * the URL to send responses and retrieve any further requests + */ + protected DataUrlConnection(URL url) { + this.url = url; + } - /** - * Set a form-parameter. - * @param name - * @param data - * @param contentType may be null - * @param charSet may be null - * @param transferEncoding may be null - */ - public void setHTTPFormParameter(String name, InputStream data, String contentType, String charSet, String transferEncoding); - - /** - * @pre httpHeaders != null - * @throws java.net.SocketTimeoutException - * @throws java.io.IOException - */ - public void connect() throws SocketTimeoutException, IOException; + /** + * Returns the URL to send responses and retrieve any further requests. + * + * @return the URL + */ + public URL getURL() { + return url; + } - public X509Certificate getServerCertificate(); + /** + * @see URLConnection#connect() + */ + public abstract void connect() throws SocketTimeoutException, IOException; - /** - * @pre connection != null - * @throws java.io.IOException - */ - public void transmit(SLResult slResult) throws IOException; + /** + * Transmit the given SLResult to the resource identified by this + * URL. + * + * @param slResult the SLResult + * @throws IOException if an I/O exception occurs + */ + public abstract void transmit(SLResult slResult) throws IOException; - public DataUrlResponse getResponse() throws IOException; + /** + * Returns the DataUrlResponse received from the resource + * identified by this URL. + * + * @return the DataUrlResponse received + * + * @throws IOException if an I/O exception occurs + */ + public abstract DataUrlResponse getResponse() throws IOException; + } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java index 93e5bb1c..1ce6d2cc 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java @@ -26,29 +26,27 @@ import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.Charset; -import java.security.cert.X509Certificate; +import java.security.cert.Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Properties; -import java.util.Set; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSocketFactory; import javax.xml.transform.stream.StreamResult; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.bku.binding.multipart.InputStreamPartSource; import at.gv.egiz.bku.binding.multipart.SLResultPart; -import at.gv.egiz.bku.conf.Configurator; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slcommands.SLResult.SLResultType; import at.gv.egiz.bku.slexceptions.SLRuntimeException; @@ -62,168 +60,144 @@ import at.gv.egiz.bku.utils.binding.Protocol; * systems. * */ -public class DataUrlConnectionImpl implements DataUrlConnectionSPI { +public class DataUrlConnectionImpl extends HttpsDataURLConnection { - private final static Log log = LogFactory.getLog(DataUrlConnectionImpl.class); - - public static final byte[] B_DEFAULT_RESPONSETYPE = DEFAULT_RESPONSETYPE.getBytes(Charset.forName("UTF-8")); + private final Logger log = LoggerFactory.getLogger(DataUrlConnectionImpl.class); + + public static final byte[] B_DEFAULT_RESPONSETYPE = DEFAULT_RESPONSETYPE + .getBytes(Charset.forName("UTF-8")); /** - * Supported protocols are HTTP and HTTPS. + * Supported protocols are HTTP and HTTPS. */ public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP, Protocol.HTTPS }; /** - * The X509 certificate of the DataURL server. - */ - protected X509Certificate serverCertificate; - - /** - * The protocol of the DataURL. - */ - protected Protocol protocol; - - /** - * Use application/x-www-form-urlencoded instead of - * standard conform application/x-www-form-urlencoded. + * Use application/x-www-form-urlencoded instead of standard + * conform application/x-www-form-urlencoded. */ protected boolean urlEncoded = true; - - /** - * The value of the DataURL. - */ - protected URL url; - + /** * The URLConnection used for communication with the DataURL server. */ private HttpURLConnection connection; - - /** - * The HTTP request headers. - */ - protected Map requestHttpHeaders; - + /** * The HTTP form parameters. */ - protected ArrayList httpFormParameter; - + protected List httpFormParameter = new ArrayList(); + /** * The boundary for multipart/form-data requests. */ protected String boundary; - - /** - * The configuration properties. - */ - protected Properties config = null; - - /** - * The SSLSocketFactory for HTTPS connections. - */ - protected SSLSocketFactory sslSocketFactory; - - /** - * The HostnameVerifier for HTTPS connections. - */ - protected HostnameVerifier hostnameVerifier; /** * The response of the DataURL server. */ - protected DataUrlResponse result; + protected DataUrlResponse response; - /* (non-Javadoc) - * @see at.gv.egiz.bku.binding.DataUrlConnection#getProtocol() + /** + * Constructs a new instance of this DataUrlConnection implementation. + * + * @param url the URL + * + * @throws IOException if an I/O exception occurs */ - public String getProtocol() { + public DataUrlConnectionImpl(URL url) throws IOException { + super(url); + + Protocol protocol = null; + for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) { + if (SUPPORTED_PROTOCOLS[i].toString().equalsIgnoreCase(url.getProtocol())) { + protocol = SUPPORTED_PROTOCOLS[i]; + break; + } + } if (protocol == null) { - return null; + throw new SLRuntimeException("Protocol " + url.getProtocol() + + " not supported for data url."); } - return protocol.toString(); + connection = (HttpURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(false); + + connection.setDoOutput(true); + + + boundary = "--" + IdFactory.getInstance().createId().toString(); } - /* (non-Javadoc) + @Override + public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { + if (connection instanceof HttpsURLConnection) { + ((HttpsURLConnection) connection).setHostnameVerifier(hostnameVerifier); + } + } + + @Override + public void setSSLSocketFactory(SSLSocketFactory socketFactory) { + if (connection instanceof HttpsURLConnection) { + ((HttpsURLConnection) connection).setSSLSocketFactory(socketFactory); + } + } + + /* + * (non-Javadoc) + * * @see at.gv.egiz.bku.binding.DataUrlConnection#connect() */ public void connect() throws SocketTimeoutException, IOException { - connection = (HttpURLConnection) url.openConnection(); - if (connection instanceof HttpsURLConnection) { - log.trace("Detected ssl connection"); - HttpsURLConnection https = (HttpsURLConnection) connection; - if (sslSocketFactory != null) { - log.debug("Setting custom ssl socket factory for ssl connection"); - https.setSSLSocketFactory(sslSocketFactory); - } else { - log.trace("No custom socket factory set"); - } - if (hostnameVerifier != null) { - log.debug("Setting custom hostname verifier"); - https.setHostnameVerifier(hostnameVerifier); - } - } else { - log.trace("No secure connection with: " + url + " class=" - + connection.getClass()); - } - connection.setDoOutput(true); // Transfer-Encoding: chunked is problematic ... // e.g. https://issues.apache.org/bugzilla/show_bug.cgi?id=37794 // ... therefore disabled. // connection.setChunkedStreamingMode(5*1024); if (urlEncoded) { - log.debug("Setting DataURL Content-Type to " - + HttpUtil.APPLICATION_URL_ENCODED); + log.debug("Setting DataURL Content-Type to {}.", + HttpUtil.APPLICATION_URL_ENCODED); connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE, HttpUtil.APPLICATION_URL_ENCODED); } else { - log.debug("Setting DataURL Content-Type to " - + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY); + log.debug("Setting DataURL Content-Type to {}.", + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY); connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE, HttpUtil.MULTIPART_FOTMDATA + HttpUtil.SEPERATOR[0] + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY + "=" + boundary); } - Set headers = requestHttpHeaders.keySet(); - Iterator headerIt = headers.iterator(); - while (headerIt.hasNext()) { - String name = headerIt.next(); - connection.setRequestProperty(name, requestHttpHeaders.get(name)); - } - log.trace("Connecting to: " + url); + log.trace("Connecting to URL '{}'.", url); connection.connect(); - if (connection instanceof HttpsURLConnection) { - HttpsURLConnection ssl = (HttpsURLConnection) connection; - X509Certificate[] certs = (X509Certificate[]) ssl.getServerCertificates(); - if ((certs != null) && (certs.length >= 1)) { - log.trace("Server certificate: " + certs[0]); - serverCertificate = certs[0]; - } - } } /* (non-Javadoc) - * @see at.gv.egiz.bku.binding.DataUrlConnection#getServerCertificate() + * @see at.gv.egiz.bku.binding.HttpsDataURLConnection#getServerCertificates() */ - public X509Certificate getServerCertificate() { - return serverCertificate; + @Override + public Certificate[] getServerCertificates() + throws SSLPeerUnverifiedException, IllegalStateException { + if (connection instanceof HttpsURLConnection) { + return ((HttpsURLConnection) connection).getServerCertificates(); + } else { + return null; + } } /* (non-Javadoc) - * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPHeader(java.lang.String, java.lang.String) + * @see at.gv.egiz.bku.binding.HttpDataURLConnection#setHTTPHeader(java.lang.String, java.lang.String) */ + @Override public void setHTTPHeader(String name, String value) { - if (name != null && value != null) { - requestHttpHeaders.put(name, value); - } + connection.setRequestProperty(name, value); } /* (non-Javadoc) - * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPFormParameter(java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String) + * @see at.gv.egiz.bku.binding.HttpDataURLConnection#setHTTPFormParameter(java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String) */ + @Override public void setHTTPFormParameter(String name, InputStream data, String contentType, String charSet, String transferEncoding) { - // if a content type is specified we have to switch to multipart/formdata encoding + // if a content type is specified we have to switch to multipart/form-data + // encoding if (contentType != null && contentType.length() > 0) { urlEncoded = false; } @@ -231,27 +205,27 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { charSet, transferEncoding)); } - - /* (non-Javadoc) * @see at.gv.egiz.bku.binding.DataUrlConnection#transmit(at.gv.egiz.bku.slcommands.SLResult) */ + @Override public void transmit(SLResult slResult) throws IOException { - log.trace("Sending data"); + log.trace("Sending data."); if (urlEncoded) { // // application/x-www-form-urlencoded (legacy, SL < 1.2) // - + OutputStream os = connection.getOutputStream(); - OutputStreamWriter streamWriter = new OutputStreamWriter(os, HttpUtil.DEFAULT_CHARSET); + OutputStreamWriter streamWriter = new OutputStreamWriter(os, + HttpUtil.DEFAULT_CHARSET); // ResponseType streamWriter.write(FORMPARAM_RESPONSETYPE); streamWriter.write("="); streamWriter.write(URLEncoder.encode(DEFAULT_RESPONSETYPE, "UTF-8")); streamWriter.write("&"); - + // XMLResponse / Binary Response if (slResult.getResultType() == SLResultType.XML) { streamWriter.write(DataUrlConnection.FORMPARAM_XMLRESPONSE); @@ -271,17 +245,18 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { streamWriter.write("&"); streamWriter.write(URLEncoder.encode(formParameter.getName(), "UTF-8")); streamWriter.write("="); - InputStreamReader reader = new InputStreamReader(formParameter.getData(), - (formParameter.getCharSet() != null) - ? formParameter.getCharSet() - : "UTF-8"); // assume request was application/x-www-form-urlencoded, formParam therefore UTF-8 + InputStreamReader reader = new InputStreamReader(formParameter + .getData(), (formParameter.getCharSet() != null) ? formParameter + .getCharSet() : "UTF-8"); // assume request was + // application/x-www-form-urlencoded, + // formParam therefore UTF-8 while ((len = reader.read(cbuf)) != -1) { urlEnc.write(cbuf, 0, len); } urlEnc.flush(); } streamWriter.close(); - + } else { // // multipart/form-data (conforming to SL 1.2) @@ -294,7 +269,7 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { DEFAULT_RESPONSETYPE, "UTF-8"); responseType.setTransferEncoding(null); parts.add(responseType); - + // XMLResponse / Binary Response SLResultPart slResultPart = new SLResultPart(slResult, XML_RESPONSE_ENCODING); @@ -307,7 +282,7 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { slResultPart.setContentType(slResult.getMimeType()); } parts.add(slResultPart); - + // transfer parameters for (HTTPFormParameter formParameter : httpFormParameter) { InputStreamPartSource source = new InputStreamPartSource(null, @@ -319,20 +294,21 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } OutputStream os = connection.getOutputStream(); - Part.sendParts(os, parts.toArray(new Part[parts.size()]), boundary.getBytes()); + Part.sendParts(os, parts.toArray(new Part[parts.size()]), boundary + .getBytes()); os.close(); - + } - + // MultipartRequestEntity PostMethod InputStream is = null; try { is = connection.getInputStream(); } catch (IOException iox) { - log.info(iox); + log.info("Failed to get InputStream of HTTPUrlConnection.", iox); } - log.trace("Reading response"); - result = new DataUrlResponse(url.toString(), connection.getResponseCode(), + log.trace("Reading response."); + response = new DataUrlResponse(url.toString(), connection.getResponseCode(), is); Map responseHttpHeaders = new HashMap(); Map> httpHeaders = connection.getHeaderFields(); @@ -349,105 +325,26 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { responseHttpHeaders.put(key, valString); } } - result.setResponseHttpHeaders(responseHttpHeaders); + response.setResponseHttpHeaders(responseHttpHeaders); } @Override public DataUrlResponse getResponse() throws IOException { - return result; - } - - /** - * inits protocol, url, httpHeaders, formParams - * - * @param url - * must not be null - */ - @Override - public void init(URL url) { - - for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) { - if (SUPPORTED_PROTOCOLS[i].toString().equalsIgnoreCase(url.getProtocol())) { - protocol = SUPPORTED_PROTOCOLS[i]; - break; - } - } - if (protocol == null) { - throw new SLRuntimeException("Protocol " + url.getProtocol() - + " not supported for data url"); - } - this.url = url; - boundary = "--" + IdFactory.getInstance().createId().toString(); - requestHttpHeaders = new HashMap(); - - if (config != null) { - String version = config.getProperty(Configurator.SIGNATURE_LAYOUT); - if ((version != null) && (!"".equals(version.trim()))) { - log.debug("setting SignatureLayout header to " + version); - requestHttpHeaders.put(Configurator.SIGNATURE_LAYOUT, version); - } else { - log.debug("do not set SignatureLayout header"); - } - String userAgent = config.getProperty(Configurator.USERAGENT_CONFIG_P, Configurator.USERAGENT_DEFAULT); - requestHttpHeaders.put(HttpUtil.HTTP_HEADER_USER_AGENT, userAgent); - } else { - requestHttpHeaders - .put(HttpUtil.HTTP_HEADER_USER_AGENT, Configurator.USERAGENT_DEFAULT); - - } - - httpFormParameter = new ArrayList(); - - } - - @Override - public DataUrlConnectionSPI newInstance() { - DataUrlConnectionSPI uc = new DataUrlConnectionImpl(); - uc.setConfiguration(config); - uc.setSSLSocketFactory(sslSocketFactory); - uc.setHostnameVerifier(hostnameVerifier); - return uc; + return response; } - @Override - public URL getUrl() { - return url; - } - - @Override - public void setConfiguration(Properties config) { - this.config = config; - } - - @Override - public void setSSLSocketFactory(SSLSocketFactory socketFactory) { - this.sslSocketFactory = socketFactory; - } - - @Override - public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { - this.hostnameVerifier = hostnameVerifier; - } - public class HTTPFormParameter { - private String name; - + private String name; + private InputStream data; - + private String contentType; - + private String charSet; - + private String transferEncoding; - - /** - * @param name - * @param data - * @param contentType - * @param charSet - * @param transferEncoding - */ + public HTTPFormParameter(String name, InputStream data, String contentType, String charSet, String transferEncoding) { super(); @@ -466,7 +363,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } /** - * @param name the name to set + * @param name + * the name to set */ public void setName(String name) { this.name = name; @@ -480,7 +378,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } /** - * @param data the data to set + * @param data + * the data to set */ public void setData(InputStream data) { this.data = data; @@ -494,7 +393,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } /** - * @param contentType the contentType to set + * @param contentType + * the contentType to set */ public void setContentType(String contentType) { this.contentType = contentType; @@ -508,7 +408,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } /** - * @param charSet the charSet to set + * @param charSet + * the charSet to set */ public void setCharSet(String charSet) { this.charSet = charSet; @@ -522,13 +423,12 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } /** - * @param transferEncoding the transferEncoding to set + * @param transferEncoding + * the transferEncoding to set */ public void setTransferEncoding(String transferEncoding) { this.transferEncoding = transferEncoding; } - - } -} \ No newline at end of file +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java deleted file mode 100644 index f838b919..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java +++ /dev/null @@ -1,64 +0,0 @@ -/* -* 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.binding; - -import java.net.URL; -import java.util.Properties; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSocketFactory; - -/** - * Prototype of a DataurlconnectionSPI - * @author wbauer - * - */ -public interface DataUrlConnectionSPI extends DataUrlConnection { - - /** - * Returns a new instance of this class to handle a dataurl. - * Called by the factory each time the openConnection method is called. - * @return - */ - public DataUrlConnectionSPI newInstance(); - - /** - * Initializes the DataUrlConnection - * @param url - */ - public void init(URL url); - - /** - * Sets configuration parameters for this connection - * @param config - */ - public void setConfiguration(Properties config); - - /** - * Sets the socketfactory to be used for ssl connections. - * @param socketFactory if null the socket factory will not be set explicitly - */ - public void setSSLSocketFactory(SSLSocketFactory socketFactory); - - /** - * Sets the hostname verifier to be used, - * @param hostnameVerifier if null the default hostname verifier will be used - */ - public void setHostnameVerifier(HostnameVerifier hostnameVerifier); - - -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java deleted file mode 100644 index d17a27c2..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* 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.binding; - -import java.util.Iterator; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This class can be used to check the BindingProcessorManager for expired entries and remove them. - * Should be run periodically. - * - */ -public class ExpiryRemover implements RemovalStrategy { - - private static Log log = LogFactory.getLog(ExpiryRemover.class); - - protected BindingProcessorManager bindingProcessorManager; - // keep max 5 min. - protected long maxAcceptedAge = 1000 * 60 * 5; - - @Override - public void execute() { - log.debug("Triggered Expiry Remover"); - if (bindingProcessorManager == null) { - log.warn("Bindingprocessor not set, skipping removal"); - return; - } - Set managedIds = bindingProcessorManager.getManagedIds(); - for (Iterator it = managedIds.iterator(); it.hasNext();) { - Id bindId = it.next(); - BindingProcessor bp = bindingProcessorManager.getBindingProcessor(bindId); - if (bp != null) { - if (bp.getLastAccessTime().getTime() < (System.currentTimeMillis() - maxAcceptedAge)) { - log.debug("Removing binding processor: " + bp.getId()); - bindingProcessorManager.removeBindingProcessor(bp.getId()); - } - } - } - } - - public void setMaxAcceptedAge(long maxAcceptedAge) { - this.maxAcceptedAge = maxAcceptedAge; - } - - @Override - public void setBindingProcessorManager(BindingProcessorManager bp) { - bindingProcessorManager = bp; - } - -} \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java new file mode 100644 index 00000000..2f62775b --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLDereferencer.java @@ -0,0 +1,71 @@ +/* +* Copyright 2009 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.binding; + +import java.io.IOException; +import java.io.InputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.utils.urldereferencer.StreamData; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; + +public class FormDataURLDereferencer implements URLDereferencer { + + public final static String PROTOCOL = "formdata"; + + private final Logger log = LoggerFactory.getLogger(FormDataURLDereferencer.class); + + private URLDereferencer urlDereferencer; + + private FormDataURLSupplier formDataURLSupplier; + + public FormDataURLDereferencer(URLDereferencer urlDereferencer, FormDataURLSupplier formDataURLSupplier) { + this.urlDereferencer = urlDereferencer; + this.formDataURLSupplier = formDataURLSupplier; + } + + @Override + public StreamData dereference(String url) + throws IOException { + + String urlString = url.toLowerCase().trim(); + if (urlString.startsWith(PROTOCOL)) { + log.debug("Requested to dereference a formdata url."); + return dereferenceFormData(url); + } else { + return urlDereferencer.dereference(url); + } + + } + + protected StreamData dereferenceFormData(String url) throws IOException { + log.debug("Dereferencing formdata url: {}.", url); + String[] parts = url.split(":", 2); + + String contentType = formDataURLSupplier.getFormDataContentType(parts[1]); + InputStream is = formDataURLSupplier.getFormData(parts[1]); + if (is != null) { + return new StreamData(url, contentType, is); + } + throw new IOException("Cannot dereference URL: '" + url + "' not found."); + } + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java new file mode 100644 index 00000000..a248e683 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java @@ -0,0 +1,27 @@ +/* +* 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.binding; + +import java.io.InputStream; + +public interface FormDataURLSupplier { + + public InputStream getFormData(String aParameterName); + + public String getFormDataContentType(String aParameterName); + +} \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java index e39addb5..db422498 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java @@ -1,844 +1,35 @@ /* - * 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.binding; +* Copyright 2009 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. +*/ -import iaik.utils.Base64InputStream; +package at.gv.egiz.bku.binding; -import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.net.URL; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; import java.util.Map; -import javax.net.ssl.SSLHandshakeException; -import javax.xml.transform.Templates; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.URIResolver; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slcommands.ErrorResult; -import at.gv.egiz.bku.slcommands.SLCommand; -import at.gv.egiz.bku.slcommands.SLCommandContext; -import at.gv.egiz.bku.slcommands.SLCommandFactory; -import at.gv.egiz.bku.slcommands.SLCommandInvoker; -import at.gv.egiz.bku.slcommands.SLResult; -import at.gv.egiz.bku.slcommands.SLSourceContext; -import at.gv.egiz.bku.slcommands.SLTargetContext; -import at.gv.egiz.bku.slcommands.impl.ErrorResultImpl; -import at.gv.egiz.bku.slexceptions.SLBindingException; -import at.gv.egiz.bku.slexceptions.SLException; -import at.gv.egiz.bku.slexceptions.SLRuntimeException; -import at.gv.egiz.bku.utils.StreamUtil; -import at.gv.egiz.bku.utils.binding.Protocol; -import at.gv.egiz.bku.utils.urldereferencer.FormDataURLSupplier; -import at.gv.egiz.bku.utils.urldereferencer.SimpleFormDataContextImpl; -import at.gv.egiz.bku.utils.urldereferencer.StreamData; -import at.gv.egiz.bku.utils.urldereferencer.URIResolverAdapter; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; -import at.gv.egiz.stal.QuitRequest; -import at.gv.egiz.stal.STALRequest; - -/** - * Class performing the HTTP binding as defined by the CCE specification. - * Currently a huge monolithic class. - * - * @TODO refactor - */ -@SuppressWarnings("unchecked") -public class HTTPBindingProcessor extends AbstractBindingProcessor implements - FormDataURLSupplier { - - private static Log log = LogFactory.getLog(HTTPBindingProcessor.class); - - private static enum State { - INIT, PROCESS, DATAURL, TRANSFORM, FINISHED - }; - - public final static Collection XML_REQ_TRANSFER_ENCODING = Arrays - .asList(new String[] { "binary" }); - - protected static String XML_MIME_TYPE = "text/xml"; - protected static String BINARY_MIME_TYPE = "application/octet-stream"; - - /** - * If null everything is ok and the result is taken from the command invoker. - */ - protected SLException bindingProcessorError; - protected SLCommandInvoker commandInvoker; - protected DataUrlResponse dataUrlResponse; - protected Map headerMap = Collections.EMPTY_MAP; - protected SLCommand slCommand; - protected Map formParameterMap = new HashMap(); - protected SLSourceContext srcContex = new SLSourceContext(); - protected SLTargetContext targetContext = new SLTargetContext(); - protected URL srcUrl; - protected State currentState = State.INIT; - protected Templates templates = null; - protected String resultContentType = null; - protected SLResult slResult = null; - protected int responseCode = 200; - protected Map responseHeaders = Collections.EMPTY_MAP; - protected Locale locale = Locale.getDefault(); - protected boolean finished = false; - - /** - * - * @param id - * may be null. In this case a new session id will be created. - * @param cmdInvoker - * must not be null; - */ - public HTTPBindingProcessor(String id, SLCommandInvoker cmdInvoker, URL source) { - super(id); - this.srcUrl = source; - Protocol protocol = Protocol.fromString(source.getProtocol()); - if ((protocol != Protocol.HTTP) && (protocol != Protocol.HTTPS)) { - throw new SLRuntimeException("Protocol not supported: " + protocol); - } - if (cmdInvoker == null) { - throw new NullPointerException("Commandinvoker cannot be set to null"); - } - commandInvoker = cmdInvoker; - srcContex.setSourceUrl(source); - srcContex.setSourceIsDataURL(false); - } - - //---------------------------------------------------------------------------- - // ----------- BEGIN CONVENIENCE METHODS ----------- - - protected void sendSTALQuit() { - log.info("Sending QUIT command to STAL"); - List quit = new ArrayList(1); - quit.add(new QuitRequest()); - getSTAL().handleRequest(quit); - } - - protected String getFormParameterAsString(String formParameterName) { - FormParameter fp = formParameterMap.get(formParameterName); - return getFormParameterAsString(fp); - } - - protected String getFormParameterAsString(FormParameter fp) { - if (fp == null) { - return null; - } - try { - return StreamUtil.asString(fp.getFormParameterValue(), HttpUtil - .getCharset(fp.getFormParameterContentType(), true)); - } catch (IOException e) { - return null; - } - } - - protected String getDataUrl() { - return getFormParameterAsString(FixedFormParameters.DATAURL); - } - - protected String getStyleSheetUrl() { - return getFormParameterAsString(FixedFormParameters.STYLESHEETURL); - } - - protected List getFormParameters(String parameterNamePostfix) { - List resultList = new ArrayList(); - for (Iterator fpi = formParameterMap.keySet().iterator(); fpi - .hasNext();) { - String paramName = fpi.next(); - if (paramName.endsWith(parameterNamePostfix)) { - resultList.add(formParameterMap.get(paramName)); - } - } - return resultList; - } - - protected List getTransferHeaders() { - return getFormParameters("__"); - } - - protected List getTransferForms() { - List resultList = new ArrayList(); - for (Iterator fpi = formParameterMap.keySet().iterator(); fpi - .hasNext();) { - String paramName = fpi.next(); - if ((paramName.endsWith("_")) && (!paramName.endsWith("__"))) { - resultList.add(formParameterMap.get(paramName)); - } - } - return resultList; - } - - protected void closeDataUrlConnection() { - log.debug("Closing data url input stream"); - if (dataUrlResponse == null) { - return; - } - InputStream is = dataUrlResponse.getStream(); - if (is != null) { - try { - is.close(); - } catch (IOException e) { - log.info("Error closing input stream to dataurl server:" + e); - } - } - } - - //---------------------------------------------------------------------------- - // ----------- END CONVENIENCE METHODS ----------- - - //---------------------------------------------------------------------------- - // -- BEGIN Methods that handle the http binding activities as defined in the - // activity diagram -- - - protected void init() { - log.info("Starting Bindingprocessor in Thread: " - + Thread.currentThread().getId()); - if (bindingProcessorError != null) { - log.debug("Detected binding processor error, sending quit command"); - // sendSTALQuit(); - currentState = State.FINISHED; - } else if (slCommand == null) { - log.error("SLCommand not set (consumeRequest not called ??)"); - bindingProcessorError = new SLException(2000); - // sendSTALQuit(); - currentState = State.FINISHED; - } else { - currentState = State.PROCESS; - } - } - - protected void processRequest() { - log.debug("Entered State: " + State.PROCESS); - log.debug("Processing command: " + slCommand); - commandInvoker.setCommand(slCommand); - responseCode = 200; - responseHeaders = Collections.EMPTY_MAP; - dataUrlResponse = null; - try { - commandInvoker.invoke(srcContex); - } catch (SLException e) { - log.info("Caught exception: " + e); - bindingProcessorError = e; - currentState = State.TRANSFORM; - } - if (getDataUrl() != null) { - log.debug("Data Url set to: " + getDataUrl()); - currentState = State.DATAURL; - } else { - log.debug("No data url set"); - currentState = State.TRANSFORM; - } - } - - protected void handleDataUrl() { - log.debug("Entered State: " + State.DATAURL); - try { - DataUrl dataUrl = new DataUrl(getDataUrl()); - DataUrlConnection conn = dataUrl.openConnection(); - - // set transfer headers - for (FormParameter fp : getTransferHeaders()) { - String paramString = getFormParameterAsString(fp); - if (paramString == null) { - log.error("Got empty transfer header, ignoring this"); - } else { - String[] keyVal = paramString.split(":", 2); - String key = keyVal[0]; - String val = null; - if (keyVal.length == 2) { - val = keyVal[1]; - val = val.trim(); - } else { - log.error("Invalid transfer header encoding: "+paramString); - throw new SLBindingException(2005); - } - log.debug("Setting header " + key + " to value " + val); - conn.setHTTPHeader(key, val); - } - } - - // set transfer form parameters - for (FormParameter fp : getTransferForms()) { - String contentTransferEncoding = null; - String contentType = fp.getFormParameterContentType(); - String charSet = HttpUtil.getCharset(contentType, false); - if (charSet != null) { - contentType = contentType.substring(0, contentType - .lastIndexOf(HttpUtil.SEPERATOR[0])); - } - for (Iterator header = fp.getHeaderNames(); header.hasNext();) { - if (HttpUtil.CONTENT_TRANSFER_ENCODING - .equalsIgnoreCase(header.next())) { - contentTransferEncoding = getFormParameterAsString(fp); - } - } - log.debug("Setting form: " + fp.getFormParameterName() - + " contentType: " + contentType + " charset: " + charSet - + " contentTransferEncoding: " + contentTransferEncoding); - conn.setHTTPFormParameter(fp.getFormParameterName(), fp - .getFormParameterValue(), contentType, charSet, - contentTransferEncoding); - } - - // connect - conn.connect(); - // fetch and set SL result - targetContext.setTargetIsDataURL(true); - targetContext.setTargetCertificate(conn.getServerCertificate()); - targetContext.setTargetUrl(conn.getUrl()); - SLResult result = commandInvoker.getResult(targetContext); - - // transfer result - conn.transmit(result); - - // process Dataurl response - dataUrlResponse = conn.getResponse(); - log.debug("Received data url response code: " - + dataUrlResponse.getResponseCode()); - - switch (dataUrlResponse.getResponseCode()) { - case 200: - String contentType = dataUrlResponse.getContentType(); - log.debug("Got dataurl response content type: " + contentType); - if (contentType != null) { - if ((contentType.startsWith(HttpUtil.APPLICATION_URL_ENCODED)) - || (contentType.startsWith(HttpUtil.MULTIPART_FOTMDATA))) { - log.debug("Detected SL Request in dataurl response"); - // process headers and request - setHTTPHeaders(dataUrlResponse.getResponseHeaders()); - consumeRequestStream(dataUrlResponse.getStream()); - //TODO check for bindingProcessorError - closeDataUrlConnection(); - srcContex.setSourceCertificate(conn.getServerCertificate()); - srcContex.setSourceIsDataURL(true); - srcContex.setSourceUrl(conn.getUrl()); - currentState = State.PROCESS; - } else if (((contentType.startsWith(HttpUtil.TXT_HTML)) - || (contentType.startsWith(HttpUtil.TXT_PLAIN)) - || (contentType.startsWith(HttpUtil.TXT_XML))) - && (dataUrlResponse.isHttpResponseXMLOK())) { - log.info("Dataurl response matches with content type: " - + contentType); - currentState = State.TRANSFORM; - - } else if ((contentType.startsWith(HttpUtil.TXT_XML)) - && (!dataUrlResponse.isHttpResponseXMLOK())) { - log - .debug("Detected text/xml dataurl response with content != "); - headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType); - assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset( - contentType, true)); - closeDataUrlConnection(); - srcContex.setSourceCertificate(conn.getServerCertificate()); - srcContex.setSourceIsDataURL(true); - srcContex.setSourceUrl(conn.getUrl()); - currentState = State.PROCESS; - // just to be complete, actually not used - srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders() - .get(HttpUtil.HTTP_HEADER_REFERER)); - } else { - resultContentType = contentType; - responseHeaders = dataUrlResponse.getResponseHeaders(); - responseCode = dataUrlResponse.getResponseCode(); - currentState = State.FINISHED; - } - } else { - log.debug("Content type not set in dataurl response"); - closeDataUrlConnection(); - throw new SLBindingException(2007); - } - - break; - case 307: - contentType = dataUrlResponse.getContentType(); - if ((contentType != null) && (contentType.startsWith(HttpUtil.TXT_XML))) { - log.debug("Received dataurl response code 307 with XML content"); - String location = dataUrlResponse.getResponseHeaders().get( - HttpUtil.HTTP_HEADER_LOCATION); - if (location == null) { - log - .error("Did not get a location header for a 307 data url response"); - throw new SLBindingException(2003); - } - // consumeRequestStream(dataUrlResponse.getStream()); - FormParameterStore fp = new FormParameterStore(); - fp.init(location.getBytes(HttpUtil.DEFAULT_CHARSET), - FixedFormParameters.DATAURL, null, null); - formParameterMap.put(FixedFormParameters.DATAURL, fp); - headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType); - assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset( - dataUrlResponse.getContentType(), true)); - closeDataUrlConnection(); - srcContex.setSourceCertificate(conn.getServerCertificate()); - srcContex.setSourceIsDataURL(true); - srcContex.setSourceUrl(conn.getUrl()); - currentState = State.PROCESS; - // just to be complete, actually not used - srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders() - .get(HttpUtil.HTTP_HEADER_REFERER)); - - } else { - log.debug("Received dataurl response code 307 non XML content: " - + dataUrlResponse.getContentType()); - resultContentType = dataUrlResponse.getContentType(); - currentState = State.FINISHED; - } - responseHeaders = dataUrlResponse.getResponseHeaders(); - responseCode = dataUrlResponse.getResponseCode(); - break; - - case 301: - case 302: - case 303: - responseHeaders = dataUrlResponse.getResponseHeaders(); - responseCode = dataUrlResponse.getResponseCode(); - resultContentType = dataUrlResponse.getContentType(); - currentState = State.FINISHED; - break; - - default: - // issue error - log.info("Unexpected response code from dataurl server: " - + dataUrlResponse.getResponseCode()); - throw new SLBindingException(2007); - } - - } catch (SLException slx) { - bindingProcessorError = slx; - log.error("Error during dataurl communication"); - resultContentType = HttpUtil.TXT_XML; - currentState = State.TRANSFORM; - } catch (SSLHandshakeException hx) { - bindingProcessorError = new SLException(2010); - log.info("Error during dataurl communication", hx); - resultContentType = HttpUtil.TXT_XML; - currentState = State.TRANSFORM; - } catch (IOException e) { - bindingProcessorError = new SLBindingException(2001); - log.error("Error while data url handling", e); - resultContentType = HttpUtil.TXT_XML; - currentState = State.TRANSFORM; - return; - } - } - - protected void transformResult() { - log.debug("Entered State: " + State.TRANSFORM); - if (bindingProcessorError != null) { - resultContentType = HttpUtil.TXT_XML; - } else if (dataUrlResponse != null) { - resultContentType = dataUrlResponse.getContentType(); - } else { - targetContext.setTargetIsDataURL(false); - targetContext.setTargetUrl(srcUrl); - try { - slResult = commandInvoker.getResult(targetContext); - resultContentType = slResult.getMimeType(); - log - .debug("Successfully got SLResult from commandinvoker, setting mimetype to: " - + resultContentType); - } catch (SLException e) { - log.info("Cannot get result from invoker:", e); - bindingProcessorError = new SLException(6002); - resultContentType = HttpUtil.TXT_XML; - } - } - templates = getTemplates(getStyleSheetUrl()); - if (templates != null) { - log.debug("Output transformation required"); - resultContentType = templates.getOutputProperties().getProperty("media-type"); - log.debug("Got media type from stylesheet: " + resultContentType); - if (resultContentType == null) { - log.debug("Setting to default text/xml result conent type"); - resultContentType = "text/xml"; - } - log.debug("Deferring sytylesheet processing"); - } - currentState = State.FINISHED; - } - - protected void finished() { - log.debug("Entered State: " + State.FINISHED); - if (bindingProcessorError != null) { - log.debug("Binding processor error, sending quit command"); - resultContentType = HttpUtil.TXT_XML; - } - sendSTALQuit(); - log.info("Terminating Bindingprocessor; Thread: " - + Thread.currentThread().getId()); - finished = true; - } - - // -- END Methods that handle the http binding activities as defined in the - // activity diagram -- - //---------------------------------------------------------------------------- - - /** - * Sets the headers of the SL Request. IMPORTANT: make sure to set all headers - * before invoking {@link #consumeRequestStream(InputStream)} - * - * @param aHeaderMap - * if null all header will be cleared. - */ - public void setHTTPHeaders(Map aHeaderMap) { - headerMap = new HashMap(); - // ensure lowercase keys - if (aHeaderMap != null) { - for (String s : aHeaderMap.keySet()) { - if (s != null) { - headerMap.put(s.toLowerCase(), aHeaderMap.get(s)); - if (s.equalsIgnoreCase(HttpUtil.HTTP_HEADER_REFERER)) { - String referer = aHeaderMap.get(s); - log.debug("Got referer header: " + referer); - srcContex.setSourceHTTPReferer(referer); - } - } - } - } - } - - public void setSourceCertificate(X509Certificate aCert) { - srcContex.setSourceCertificate(aCert); - } - - /** - * The HTTPBindingProcessor does not handle redirect URLs. It only provides - * the parameter. - * - * @return null if redirect url is not set. - */ - public String getRedirectURL() { - return getFormParameterAsString(FixedFormParameters.REDIRECTURL); - } - - public String getFormDataContentType(String aParameterName) { - FormParameter fp = formParameterMap.get(aParameterName); - if (fp != null) { - return fp.getFormParameterContentType(); - } - return null; - } - - public InputStream getFormData(String aParameterName) { - FormParameter fp = formParameterMap.get(aParameterName); - if (fp != null) { - final String enc = fp.getHeaderValue("Content-Transfer-Encoding"); - if (enc == null || "binary".equals(enc)) { - return fp.getFormParameterValue(); - } else if ("base64".equals(enc)) { - return new Base64InputStream(fp.getFormParameterValue()); - } else { - return new InputStream() { - @Override - public int read() throws IOException { - throw new IOException("Content-Transfer-Encoding : " + enc - + " is not supported."); - } - }; - } - } - return null; - } - - protected void assignXMLRequest(InputStream is, String charset) - throws IOException, SLException { - Reader r = new InputStreamReader(is, charset); - StreamSource source = new StreamSource(r); - SLCommandContext commandCtx = new SLCommandContext(); - commandCtx.setSTAL(getSTAL()); - commandCtx.setURLDereferencerContext(new SimpleFormDataContextImpl(this)); - commandCtx.setLocale(locale); - slCommand = SLCommandFactory.getInstance().createSLCommand(source, - commandCtx); - log.debug("Created new command: " + slCommand); - } - - @Override - public void run() { - boolean done = false; - int hopcounter = 0; - if (bindingProcessorError != null) { - currentState = State.FINISHED; - } - try { - while (!done) { - try { - switch (currentState) { - case INIT: - init(); - break; - case PROCESS: - processRequest(); - break; - case DATAURL: - handleDataUrl(); - if (++hopcounter > config.getMaxDataUrlHops()) { - log.error("Maximum number of dataurl hops reached"); - bindingProcessorError = new SLBindingException(2000); - currentState = State.FINISHED; - } - break; - case TRANSFORM: - transformResult(); - break; - case FINISHED: - done = true; - finished(); - break; - } - } catch (RuntimeException rte) { - throw rte; - } catch (Exception t) { - log.error("Caught unexpected exception", t); - responseCode = 200; - resultContentType = HttpUtil.TXT_XML; - responseHeaders = Collections.EMPTY_MAP; - bindingProcessorError = new SLException(2000); - currentState = State.FINISHED; - } - } - } catch (Throwable t) { - log.error("Caught unexpected exception", t); - responseCode = 200; - resultContentType = HttpUtil.TXT_XML; - responseHeaders = Collections.EMPTY_MAP; - bindingProcessorError = new SLException(2000); - currentState = State.FINISHED; - } - log.debug("Terminated http binding processor"); - finished = true; - } - - @Override - public void consumeRequestStream(InputStream is) { - try { - log.debug("Start consuming request stream"); - formParameterMap.clear(); - String cl = headerMap - .get(HttpUtil.HTTP_HEADER_CONTENT_TYPE.toLowerCase()); - if (cl == null) { - log.info("No content type set in http header"); - throw new SLBindingException(2006); - } - InputDecoder id = InputDecoderFactory.getDecoder(cl, is); - if (id == null) { - log.error("Cannot get inputdecoder for is"); - throw new SLException(2006); - } - for (Iterator fpi = id.getFormParameterIterator(); fpi - .hasNext();) { - FormParameter fp = fpi.next(); - log.debug("Got request parameter with name: " - + fp.getFormParameterName()); - if (fp.getFormParameterName().equals(FixedFormParameters.XMLREQUEST)) { - log.debug("Creating XML Request"); - for (Iterator headerIterator = fp.getHeaderNames(); headerIterator - .hasNext();) { - String headerName = headerIterator.next(); - if (HttpUtil.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) { - String transferEncoding = fp.getHeaderValue(headerName); - log.debug("Got transfer encoding for xmlrequest: " - + transferEncoding); - if (XML_REQ_TRANSFER_ENCODING.contains(transferEncoding)) { - log.debug("Supported transfer encoding: " + transferEncoding); - } else { - log - .error("Transferencoding not supported: " - + transferEncoding); - throw new SLBindingException(2005); - } - } - } - String charset = HttpUtil.getCharset(cl, true); - assignXMLRequest(fp.getFormParameterValue(), charset); - } else { - FormParameterStore fps = new FormParameterStore(); - fps.init(fp); - //if (!fps.isEmpty()) { - log.debug("Setting form parameter: " + fps.getFormParameterName()); - formParameterMap.put(fps.getFormParameterName(), fps); - //} - } - } - if (slCommand == null) { - throw new SLBindingException(2004); - } - } catch (SLException slx) { - log.info("Error while consuming input stream " + slx); - bindingProcessorError = slx; - } catch (Throwable t) { - log.info("Error while consuming input stream " + t, t); - bindingProcessorError = new SLException(2000); - } finally { - try { - if (is.read() != -1) { - log.warn("Request input stream not completely read."); - while (is.read() != -1); - } - } catch (IOException e) { - log.error(e); - } - } - } - - @Override - public String getResultContentType() { - return resultContentType; - } - - protected Templates getTemplates(String styleSheetURL) { - if (styleSheetURL == null) { - log.debug("Stylesheet URL not set"); - return null; - } - try { - URLDereferencerContext urlCtx = new SimpleFormDataContextImpl(this); - URIResolver resolver = new URIResolverAdapter(URLDereferencer - .getInstance(), urlCtx); - TransformerFactory factory = TransformerFactory.newInstance(); - factory.setURIResolver(resolver); - StreamData sd = URLDereferencer.getInstance().dereference(styleSheetURL, - urlCtx); - return factory.newTemplates(new StreamSource(sd.getStream())); - } catch (Exception ex) { - log.info("Cannot instantiate transformer", ex); - bindingProcessorError = new SLException(2002); - return null; - } - } - - protected void handleBindingProcessorError(OutputStream os, String encoding, - Templates templates) throws IOException { - log.debug("Writing error as result"); - ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError, locale); - Writer writer = writeXMLDeclarationAndProcessingInstruction(os, encoding); - error.writeTo(new StreamResult(writer), templates, true); - } - - protected Writer writeXMLDeclarationAndProcessingInstruction(OutputStream os, String encoding) throws IOException { - if (encoding == null) { - encoding = HttpUtil.DEFAULT_CHARSET; - } - OutputStreamWriter writer = new OutputStreamWriter(os, encoding); - writer.write("\n"); - writer.write("\n"); - return writer; - } - - @Override - public void writeResultTo(OutputStream os, String encoding) - throws IOException { - if (encoding == null) { - encoding = HttpUtil.DEFAULT_CHARSET; - } - if (bindingProcessorError != null) { - log.debug("Detected error in binding processor, writing error as result"); - handleBindingProcessorError(os, encoding, templates); - return; - } else if (dataUrlResponse != null) { - log.debug("Writing data url response as result"); - String charEnc = HttpUtil.getCharset(dataUrlResponse.getContentType(), - true); - InputStreamReader isr = new InputStreamReader( - dataUrlResponse.getStream(), charEnc); - OutputStreamWriter osw = new OutputStreamWriter(os, encoding); - if (templates == null) { - StreamUtil.copyStream(isr, osw); - } else { - try { - Transformer transformer = templates.newTransformer(); - transformer.transform(new StreamSource(isr), new StreamResult(osw)); - } catch (TransformerException e) { - log.fatal("Exception occured during result transformation", e); - // bindingProcessorError = new SLException(2008); - // handleBindingProcessorError(os, encoding, null); - return; - } - } - osw.flush(); - isr.close(); - } else if (slResult == null) { - // result not yet assigned -> must be a cancel - bindingProcessorError = new SLException(6001); - handleBindingProcessorError(os, encoding, templates); - return; - } else { - log.debug("Getting result from invoker"); - boolean fragment = false; - Writer writer; - if (slResult instanceof ErrorResult) { - writer = writeXMLDeclarationAndProcessingInstruction(os, encoding); - fragment = true; - } else { - writer = new OutputStreamWriter(os, encoding); - } - slResult.writeTo(new StreamResult(writer), templates, fragment); - writer.flush(); - } - } +public interface HTTPBindingProcessor extends BindingProcessor { - /** - * The response code from the dataurl server or 200 if no dataurl server - * created the result - * - * @return - */ - public int getResponseCode() { - return responseCode; - } + public void setHTTPHeaders(Map headerMap); + + public InputStream getFormData(String parameterName); - /** - * All headers from the data url server in case of a direct forward from the - * dataurl server. - * - * @return - */ - public Map getResponseHeaders() { - return responseHeaders; - } + public String getRedirectURL(); - @Override - public void setLocale(Locale locale) { - if (locale == null) { - throw new NullPointerException("Locale must not be set to null"); - } - this.locale = locale; - } + public int getResponseCode(); - @Override - public boolean isFinished() { - return finished; - } -} \ No newline at end of file + public Map getResponseHeaders(); + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java new file mode 100644 index 00000000..41688e9b --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorFactory.java @@ -0,0 +1,80 @@ +/* +* Copyright 2009 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.binding; + + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; + + +import at.gv.egiz.bku.utils.binding.Protocol; + +public class HTTPBindingProcessorFactory extends AbstractBindingProcessorFactory implements BindingProcessorFactory { + + private HostnameVerifier hostnameVerifier; + + private SSLSocketFactory sslSocketFactory; + + public HTTPBindingProcessorFactory() { + Set sp = new HashSet(); + Collections.addAll(sp, Protocol.HTTP, Protocol.HTTPS); + supportedProtocols = Collections.unmodifiableSet(sp); + } + + /** + * @return the hostnameVerifier + */ + public HostnameVerifier getHostnameVerifier() { + return hostnameVerifier; + } + + /** + * @param hostnameVerifier the hostnameVerifier to set + */ + public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { + this.hostnameVerifier = hostnameVerifier; + } + + /** + * @return the sslSocketFactory + */ + public SSLSocketFactory getSslSocketFactory() { + return sslSocketFactory; + } + + /** + * @param sslSocketFactory the sslSocketFactory to set + */ + public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) { + this.sslSocketFactory = sslSocketFactory; + } + + @Override + public BindingProcessor createBindingProcessor() { + HTTPBindingProcessorImpl httpBindingProcessor = new HTTPBindingProcessorImpl(); + configureBindingProcessor(httpBindingProcessor); + httpBindingProcessor.setHostnameVerifier(hostnameVerifier); + httpBindingProcessor.setSslSocketFactory(sslSocketFactory); + return httpBindingProcessor; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java new file mode 100644 index 00000000..b5f34689 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessorImpl.java @@ -0,0 +1,896 @@ +/* + * 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.binding; + +import iaik.utils.Base64InputStream; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLSocketFactory; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; +import at.gv.egiz.bku.slcommands.ErrorResult; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slcommands.SLResult; +import at.gv.egiz.bku.slcommands.SLSourceContext; +import at.gv.egiz.bku.slcommands.SLTargetContext; +import at.gv.egiz.bku.slcommands.impl.ErrorResultImpl; +import at.gv.egiz.bku.slexceptions.SLBindingException; +import at.gv.egiz.bku.slexceptions.SLException; +import at.gv.egiz.bku.spring.ConfigurationFactoryBean; +import at.gv.egiz.bku.utils.StreamUtil; +import at.gv.egiz.bku.utils.urldereferencer.StreamData; +import at.gv.egiz.bku.utils.urldereferencer.URIResolverAdapter; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; +import at.gv.egiz.stal.QuitRequest; +import at.gv.egiz.stal.STALRequest; + +/** + * Class performing the HTTP binding as defined by the CCE specification. + * Currently a huge monolithic class. + * + * @TODO refactor + */ +@SuppressWarnings("unchecked") +public class HTTPBindingProcessorImpl extends AbstractBindingProcessor implements + HTTPBindingProcessor, FormDataURLSupplier { + + private final Logger log = LoggerFactory.getLogger(HTTPBindingProcessorImpl.class); + + private static enum State { + INIT, PROCESS, DATAURL, TRANSFORM, FINISHED + }; + + public final static Collection XML_REQ_TRANSFER_ENCODING = Arrays + .asList(new String[] { "binary" }); + + protected static String XML_MIME_TYPE = "text/xml"; + protected static String BINARY_MIME_TYPE = "application/octet-stream"; + + /** + * The citizen card environment identifier for Server and + * UserAgent headers. + */ + protected static String CITIZENC_CARD_ENVIRONMENT = "citizen-card-environment/1.2"; + + /** + * The configuration facade used to access the MOCCA configuration. + */ + protected ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade implements MoccaConfigurationFacade { + + public static final String DATAURLCLIENT_MAXHOPS = "DataURLConnection.MaxHops"; + + public int getMaxDataUrlHops() { + return configuration.getInt(DATAURLCLIENT_MAXHOPS, 10); + } + + public String getProductName() { + return configuration.getString( + ConfigurationFactoryBean.MOCCA_IMPLEMENTATIONNAME_PROPERTY, "MOCCA"); + } + + public String getProductVersion() { + return configuration.getString( + ConfigurationFactoryBean.MOCCA_IMPLEMENTATIONVERSION_PROPERTY, + "UNKNOWN"); + } + + public String getSignatureLayout() { + return configuration + .getString(ConfigurationFactoryBean.SIGNATURE_LAYOUT_PROPERTY); + } + + } + + /** + * If null everything is ok and the result is taken from the command invoker. + */ + protected SLException bindingProcessorError; + protected SSLSocketFactory sslSocketFactory; + protected HostnameVerifier hostnameVerifier; + protected DataUrlResponse dataUrlResponse; + protected Map headerMap = Collections.EMPTY_MAP; + protected SLCommand slCommand; + protected Map formParameterMap = new HashMap(); + protected SLSourceContext srcContex = new SLSourceContext(); + protected SLTargetContext targetContext = new SLTargetContext(); + protected URL srcUrl; + protected State currentState = State.INIT; + protected Templates templates = null; + protected String resultContentType = null; + protected SLResult slResult = null; + protected int responseCode = 200; + protected Map responseHeaders = Collections.EMPTY_MAP; + protected boolean finished = false; + + @Override + public void setUrlDereferencer(URLDereferencer urlDereferencer) { + super.setUrlDereferencer(new FormDataURLDereferencer(urlDereferencer, this)); + } + + /** + * @return the sslSocketFactory + */ + public SSLSocketFactory getSslSocketFactory() { + return sslSocketFactory; + } + + /** + * @param sslSocketFactory + * the sslSocketFactory to set + */ + public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) { + this.sslSocketFactory = sslSocketFactory; + } + + /** + * @return the hostnameVerifier + */ + public HostnameVerifier getHostnameVerifier() { + return hostnameVerifier; + } + + /** + * @param hostnameVerifier + * the hostnameVerifier to set + */ + public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { + this.hostnameVerifier = hostnameVerifier; + } + + protected void sendSTALQuit() { + log.debug("Sending QUIT command to STAL."); + List quit = new ArrayList(1); + quit.add(new QuitRequest()); + getSTAL().handleRequest(quit); + } + + protected String getFormParameterAsString(String formParameterName) { + FormParameter fp = formParameterMap.get(formParameterName); + return getFormParameterAsString(fp); + } + + protected String getFormParameterAsString(FormParameter fp) { + if (fp == null) { + return null; + } + try { + return StreamUtil.asString(fp.getFormParameterValue(), HttpUtil + .getCharset(fp.getFormParameterContentType(), true)); + } catch (IOException e) { + return null; + } + } + + protected String getDataUrl() { + return getFormParameterAsString(FixedFormParameters.DATAURL); + } + + protected String getStyleSheetUrl() { + return getFormParameterAsString(FixedFormParameters.STYLESHEETURL); + } + + protected List getFormParameters(String parameterNamePostfix) { + List resultList = new ArrayList(); + for (Iterator fpi = formParameterMap.keySet().iterator(); fpi + .hasNext();) { + String paramName = fpi.next(); + if (paramName.endsWith(parameterNamePostfix)) { + resultList.add(formParameterMap.get(paramName)); + } + } + return resultList; + } + + protected List getTransferHeaders() { + return getFormParameters("__"); + } + + protected List getTransferForms() { + List resultList = new ArrayList(); + for (Iterator fpi = formParameterMap.keySet().iterator(); fpi + .hasNext();) { + String paramName = fpi.next(); + if ((paramName.endsWith("_")) && (!paramName.endsWith("__"))) { + resultList.add(formParameterMap.get(paramName)); + } + } + return resultList; + } + + protected void closeDataUrlConnection() { + log.debug("Closing data url input stream."); + if (dataUrlResponse == null) { + return; + } + InputStream is = dataUrlResponse.getStream(); + if (is != null) { + try { + is.close(); + } catch (IOException e) { + log.info("Error closing input stream to dataurl server.", e); + } + } + } + + //---------------------------------------------------------------------------- + // ----------- END CONVENIENCE METHODS ----------- + + //---------------------------------------------------------------------------- + // -- BEGIN Methods that handle the http binding activities as defined in the + // activity diagram -- + + protected void init() { + log.info("Starting Bindingprocessor : {}.", id); + if (bindingProcessorError != null) { + log.debug("Detected binding processor error, sending quit command."); + currentState = State.FINISHED; + } else if (slCommand == null) { + log.error("SLCommand not set. (consumeRequest not called?)"); + bindingProcessorError = new SLException(2000); + currentState = State.FINISHED; + } else { + currentState = State.PROCESS; + } + } + + protected void processRequest() { + log.info("Entered State: {}, Processing {}.", State.PROCESS, slCommand.getName()); + SLCommandContext commandCtx = new SLCommandContext( + getSTAL(), + new FormDataURLDereferencer(urlDereferencer, this), + locale); + commandInvoker.setCommand(commandCtx, slCommand); + responseCode = 200; + responseHeaders = Collections.EMPTY_MAP; + dataUrlResponse = null; + try { + commandInvoker.invoke(srcContex); + } catch (SLException e) { + log.info("Failed to invoke command.", e); + bindingProcessorError = e; + currentState = State.TRANSFORM; + } + if (getDataUrl() != null) { + log.debug("DataUrl set to: {}.", getDataUrl()); + currentState = State.DATAURL; + } else { + log.debug("No data url set."); + currentState = State.TRANSFORM; + } + } + + protected void handleDataUrl() { + log.info("Entered State: {}, DataURL={}.", State.DATAURL, getDataUrl()); + try { + DataUrl dataUrl = new DataUrl(getDataUrl()); + HttpsDataURLConnection conn = (HttpsDataURLConnection) dataUrl.openConnection(); + + // set user agent and signature layout headers + conn.setHTTPHeader(HttpUtil.HTTP_HEADER_USER_AGENT, getServerHeaderValue()); + conn.setHTTPHeader(HttpUtil.HTTP_HEADER_SIGNATURE_LAYOUT, getSignatureLayoutHeaderValue()); + conn.setHostnameVerifier(hostnameVerifier); + conn.setSSLSocketFactory(sslSocketFactory); + + // set transfer headers + for (FormParameter fp : getTransferHeaders()) { + String paramString = getFormParameterAsString(fp); + if (paramString == null) { + log.error("Got empty transfer header, ignoring this."); + } else { + String[] keyVal = paramString.split(":", 2); + String key = keyVal[0]; + String val = null; + if (keyVal.length == 2) { + val = keyVal[1]; + val = val.trim(); + } else { + log.error("Invalid transfer header encoding: {}.", paramString); + throw new SLBindingException(2005); + } + log.debug("Setting header '{}' to value '{}'.", key, val); + conn.setHTTPHeader(key, val); + } + } + + // set transfer form parameters + for (FormParameter fp : getTransferForms()) { + String contentTransferEncoding = null; + String contentType = fp.getFormParameterContentType(); + String charSet = HttpUtil.getCharset(contentType, false); + if (charSet != null) { + contentType = contentType.substring(0, contentType + .lastIndexOf(HttpUtil.SEPERATOR[0])); + } + for (Iterator header = fp.getHeaderNames(); header.hasNext();) { + if (HttpUtil.CONTENT_TRANSFER_ENCODING + .equalsIgnoreCase(header.next())) { + contentTransferEncoding = getFormParameterAsString(fp); + } + } + if (log.isDebugEnabled()) { + Object[] args = {fp.getFormParameterName(), contentType, contentTransferEncoding}; + log.debug("Setting form parameter '{}'" + + " (content-type {}, charset {}, content transfer encoding {})", args); + } + conn.setHTTPFormParameter(fp.getFormParameterName(), fp + .getFormParameterValue(), contentType, charSet, + contentTransferEncoding); + } + + // connect + conn.connect(); + // fetch and set SL result + targetContext.setTargetIsDataURL(true); + X509Certificate serverCertificate = null; + if (conn.getServerCertificates() instanceof X509Certificate[]) { + serverCertificate = (X509Certificate) conn.getServerCertificates()[0]; + } + targetContext.setTargetCertificate(serverCertificate); + targetContext.setTargetUrl(conn.getURL()); + SLResult result = commandInvoker.getResult(targetContext); + + // transfer result + conn.transmit(result); + + // process Dataurl response + dataUrlResponse = conn.getResponse(); + log.debug("Received data url response code: {}.", dataUrlResponse.getResponseCode()); + + switch (dataUrlResponse.getResponseCode()) { + case 200: + String contentType = dataUrlResponse.getContentType(); + log.debug("Got dataurl response content type: {}.", contentType); + if (contentType != null) { + if ((contentType.startsWith(HttpUtil.APPLICATION_URL_ENCODED)) + || (contentType.startsWith(HttpUtil.MULTIPART_FOTMDATA))) { + log.debug("Detected SL Request in dataurl response."); + // process headers and request + setHTTPHeaders(dataUrlResponse.getResponseHeaders()); + consumeRequestStream(dataUrlResponse.getUrl(), dataUrlResponse.getStream()); + //TODO check for bindingProcessorError + closeDataUrlConnection(); + srcContex.setSourceCertificate(serverCertificate); + srcContex.setSourceIsDataURL(true); + srcContex.setSourceUrl(conn.getURL()); + currentState = State.PROCESS; + } else if (((contentType.startsWith(HttpUtil.TXT_HTML)) + || (contentType.startsWith(HttpUtil.TXT_PLAIN)) + || (contentType.startsWith(HttpUtil.TXT_XML))) + && (dataUrlResponse.isHttpResponseXMLOK())) { + log.info("Dataurl response matches with content type: {}.", contentType); + currentState = State.TRANSFORM; + + } else if ((contentType.startsWith(HttpUtil.TXT_XML)) + && (!dataUrlResponse.isHttpResponseXMLOK())) { + log.debug("Detected text/xml dataurl response with content != "); + headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType); + assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset( + contentType, true)); + closeDataUrlConnection(); + srcContex.setSourceCertificate(serverCertificate); + srcContex.setSourceIsDataURL(true); + srcContex.setSourceUrl(conn.getURL()); + currentState = State.PROCESS; + // just to be complete, actually not used + srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders() + .get(HttpUtil.HTTP_HEADER_REFERER)); + } else { + resultContentType = contentType; + responseHeaders = dataUrlResponse.getResponseHeaders(); + responseCode = dataUrlResponse.getResponseCode(); + currentState = State.FINISHED; + } + } else { + log.debug("Content type not set in dataurl response."); + closeDataUrlConnection(); + throw new SLBindingException(2007); + } + + break; + case 307: + contentType = dataUrlResponse.getContentType(); + if ((contentType != null) && (contentType.startsWith(HttpUtil.TXT_XML))) { + log.debug("Received dataurl response code 307 with XML content."); + String location = dataUrlResponse.getResponseHeaders().get( + HttpUtil.HTTP_HEADER_LOCATION); + if (location == null) { + log.error("Did not get a location header for a 307 data url response."); + throw new SLBindingException(2003); + } + // consumeRequestStream(dataUrlResponse.getStream()); + FormParameterStore fp = new FormParameterStore(); + fp.init(location.getBytes(HttpUtil.DEFAULT_CHARSET), + FixedFormParameters.DATAURL, null, null); + formParameterMap.put(FixedFormParameters.DATAURL, fp); + headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType); + assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset( + dataUrlResponse.getContentType(), true)); + closeDataUrlConnection(); + srcContex.setSourceCertificate(serverCertificate); + srcContex.setSourceIsDataURL(true); + srcContex.setSourceUrl(conn.getURL()); + currentState = State.PROCESS; + // just to be complete, actually not used + srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders() + .get(HttpUtil.HTTP_HEADER_REFERER)); + + } else { + log.debug("Received dataurl response code 307 non XML content: {}.", + dataUrlResponse.getContentType()); + resultContentType = dataUrlResponse.getContentType(); + currentState = State.FINISHED; + } + responseHeaders = dataUrlResponse.getResponseHeaders(); + responseCode = dataUrlResponse.getResponseCode(); + break; + + case 301: + case 302: + case 303: + responseHeaders = dataUrlResponse.getResponseHeaders(); + responseCode = dataUrlResponse.getResponseCode(); + resultContentType = dataUrlResponse.getContentType(); + currentState = State.FINISHED; + break; + + default: + // issue error + log.info("Unexpected response code from dataurl server: {}.", + dataUrlResponse.getResponseCode()); + throw new SLBindingException(2007); + } + + } catch (SLException slx) { + bindingProcessorError = slx; + log.error("Error during dataurl communication."); + resultContentType = HttpUtil.TXT_XML; + currentState = State.TRANSFORM; + } catch (SSLHandshakeException hx) { + bindingProcessorError = new SLException(2010); + log.info("Error during dataurl communication.", hx); + resultContentType = HttpUtil.TXT_XML; + currentState = State.TRANSFORM; + } catch (IOException e) { + bindingProcessorError = new SLBindingException(2001); + log.error("Error while data url handling", e); + resultContentType = HttpUtil.TXT_XML; + currentState = State.TRANSFORM; + return; + } + } + + protected void transformResult() { + log.info("Entered State: {}.", State.TRANSFORM); + if (bindingProcessorError != null) { + resultContentType = HttpUtil.TXT_XML; + } else if (dataUrlResponse != null) { + resultContentType = dataUrlResponse.getContentType(); + } else { + targetContext.setTargetIsDataURL(false); + targetContext.setTargetUrl(srcUrl); + try { + slResult = commandInvoker.getResult(targetContext); + resultContentType = slResult.getMimeType(); + log.debug("Successfully got SLResult from commandinvoker, setting mimetype to: {}.", + resultContentType); + } catch (SLException e) { + log.info("Cannot get result from invoker:", e); + bindingProcessorError = new SLException(6002); + resultContentType = HttpUtil.TXT_XML; + } + } + templates = getTemplates(getStyleSheetUrl()); + if (templates != null) { + log.debug("Output transformation required."); + resultContentType = templates.getOutputProperties().getProperty("media-type"); + log.debug("Got media type from stylesheet: {}.", resultContentType); + if (resultContentType == null) { + log.debug("Setting to default text/xml result conent type."); + resultContentType = "text/xml"; + } + log.debug("Deferring sytylesheet processing."); + } + currentState = State.FINISHED; + } + + protected void finished() { + log.info("Entered State: {}.", State.FINISHED); + if (bindingProcessorError != null) { + log.debug("Binding processor error, sending quit command."); + resultContentType = HttpUtil.TXT_XML; + } + sendSTALQuit(); + log.info("Terminating Bindingprocessor : {}.", id); + finished = true; + } + + // -- END Methods that handle the http binding activities as defined in the + // activity diagram -- + //---------------------------------------------------------------------------- + + public String getServerHeaderValue() { + return CITIZENC_CARD_ENVIRONMENT + " " + + configurationFacade.getProductName() + "/" + + configurationFacade.getProductVersion(); + } + + public String getSignatureLayoutHeaderValue() { + return configurationFacade.getSignatureLayout(); + } + + /** + * Sets the headers of the SL Request. IMPORTANT: make sure to set all headers + * before invoking {@link #consumeRequestStream(String, InputStream)} + * + * @param aHeaderMap + * if null all header will be cleared. + */ + @Override + public void setHTTPHeaders(Map aHeaderMap) { + headerMap = new HashMap(); + // ensure lowercase keys + if (aHeaderMap != null) { + for (String s : aHeaderMap.keySet()) { + if (s != null) { + headerMap.put(s.toLowerCase(), aHeaderMap.get(s)); + if (s.equalsIgnoreCase(HttpUtil.HTTP_HEADER_REFERER)) { + String referer = aHeaderMap.get(s); + log.debug("Got referer header: {}.", referer); + srcContex.setSourceHTTPReferer(referer); + } + } + } + } + } + + public void setSourceCertificate(X509Certificate aCert) { + srcContex.setSourceCertificate(aCert); + } + + /** + * The HTTPBindingProcessor does not handle redirect URLs. It only provides + * the parameter. + * + * @return null if redirect url is not set. + */ + public String getRedirectURL() { + return getFormParameterAsString(FixedFormParameters.REDIRECTURL); + } + + public String getFormDataContentType(String aParameterName) { + FormParameter fp = formParameterMap.get(aParameterName); + if (fp != null) { + return fp.getFormParameterContentType(); + } + return null; + } + + public InputStream getFormData(String aParameterName) { + FormParameter fp = formParameterMap.get(aParameterName); + if (fp != null) { + final String enc = fp.getHeaderValue("Content-Transfer-Encoding"); + if (enc == null || "binary".equals(enc)) { + return fp.getFormParameterValue(); + } else if ("base64".equals(enc)) { + return new Base64InputStream(fp.getFormParameterValue()); + } else { + return new InputStream() { + @Override + public int read() throws IOException { + throw new IOException("Content-Transfer-Encoding : " + enc + + " is not supported."); + } + }; + } + } + return null; + } + + protected void assignXMLRequest(InputStream is, String charset) + throws IOException, SLException { + Reader r = new InputStreamReader(is, charset); + StreamSource source = new StreamSource(r); + slCommand = slCommandFactory.createSLCommand(source); + log.info("XMLRequest={}. Created new command: {}.", slCommand.getName(), slCommand + .getClass().getName()); + } + + @Override + public void process() { + boolean done = false; + int hopcounter = 0; + if (bindingProcessorError != null) { + currentState = State.FINISHED; + } + try { + while (!done) { + try { + switch (currentState) { + case INIT: + init(); + break; + case PROCESS: + processRequest(); + break; + case DATAURL: + handleDataUrl(); + if (++hopcounter > configurationFacade.getMaxDataUrlHops()) { + log.error("Maximum number ({}) of dataurl hops reached.", + configurationFacade.getMaxDataUrlHops()); + bindingProcessorError = new SLBindingException(2000); + currentState = State.FINISHED; + } + break; + case TRANSFORM: + transformResult(); + break; + case FINISHED: + done = true; + finished(); + break; + } + } catch (RuntimeException rte) { + throw rte; + } catch (Exception e) { + log.error("Caught unexpected exception.", e); + responseCode = 200; + resultContentType = HttpUtil.TXT_XML; + responseHeaders = Collections.EMPTY_MAP; + bindingProcessorError = new SLException(2000); + currentState = State.FINISHED; + } + } + } catch (Throwable t) { + log.error("Caught unexpected exception.", t); + responseCode = 200; + resultContentType = HttpUtil.TXT_XML; + responseHeaders = Collections.EMPTY_MAP; + bindingProcessorError = new SLException(2000); + currentState = State.FINISHED; + } + log.debug("Terminated http binding processor."); + finished = true; + } + + @Override + public void consumeRequestStream(String url, InputStream is) { + try { + this.srcUrl = new URL(url); + srcContex.setSourceUrl(srcUrl); + srcContex.setSourceIsDataURL(false); + log.debug("Start consuming request stream."); + formParameterMap.clear(); + String ct = headerMap + .get(HttpUtil.HTTP_HEADER_CONTENT_TYPE.toLowerCase()); + if (ct == null) { + log.info("No content type set in http header."); + throw new SLBindingException(2006); + } + InputDecoder id = InputDecoderFactory.getDecoder(ct, is); + if (id == null) { + log.error("Cannot get inputdecoder for content type {}.", ct); + throw new SLException(2006); + } + for (Iterator fpi = id.getFormParameterIterator(); fpi + .hasNext();) { + FormParameter fp = fpi.next(); + log.debug("Got request parameter with name: {}.", fp.getFormParameterName()); + if (fp.getFormParameterName().equals(FixedFormParameters.XMLREQUEST)) { + log.debug("Creating XML Request."); + for (Iterator headerIterator = fp.getHeaderNames(); headerIterator + .hasNext();) { + String headerName = headerIterator.next(); + if (HttpUtil.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) { + String transferEncoding = fp.getHeaderValue(headerName); + log.debug("Got transfer encoding for xmlrequest: {}.", + transferEncoding); + if (XML_REQ_TRANSFER_ENCODING.contains(transferEncoding)) { + log.debug("Supported transfer encoding: {}.", transferEncoding); + } else { + log.error("Transfer encoding '{}' not supported.", transferEncoding); + throw new SLBindingException(2005); + } + } + } + String charset = HttpUtil.getCharset(ct, true); + assignXMLRequest(fp.getFormParameterValue(), charset); + } else { + FormParameterStore fps = new FormParameterStore(); + fps.init(fp); + //if (!fps.isEmpty()) { + log.debug("Setting form parameter: {}.", fps.getFormParameterName()); + formParameterMap.put(fps.getFormParameterName(), fps); + //} + } + } + if (slCommand == null) { + throw new SLBindingException(2004); + } + } catch (SLException slx) { + log.info("Error while consuming input stream.", slx); + bindingProcessorError = slx; + } catch (Throwable t) { + log.info("Error while consuming input stream.", t); + bindingProcessorError = new SLException(2000); + } finally { + try { + if (is.read() != -1) { + log.warn("Request input stream not completely read."); + while (is.read() != -1); + } + log.debug("Finished consuming request stream."); + } catch (IOException e) { + log.error("Failed to read request input stream.", e); + } + } + } + + @Override + public String getResultContentType() { + return resultContentType; + } + + protected Templates getTemplates(String styleSheetURL) { + if (styleSheetURL == null) { + log.debug("Stylesheet URL not set."); + return null; + } + try { + TransformerFactory factory = TransformerFactory.newInstance(); + factory.setURIResolver(new URIResolverAdapter(urlDereferencer)); + StreamData sd = urlDereferencer.dereference(styleSheetURL); + return factory.newTemplates(new StreamSource(sd.getStream())); + } catch (Exception ex) { + log.info("Cannot instantiate transformer.", ex); + bindingProcessorError = new SLException(2002); + return null; + } + } + + protected void handleBindingProcessorError(OutputStream os, String encoding, + Templates templates) throws IOException { + log.debug("Writing error as result."); + ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError, locale); + Writer writer = writeXMLDeclarationAndProcessingInstruction(os, encoding); + error.writeTo(new StreamResult(writer), templates, true); + } + + protected Writer writeXMLDeclarationAndProcessingInstruction(OutputStream os, String encoding) throws IOException { + if (encoding == null) { + encoding = HttpUtil.DEFAULT_CHARSET; + } + OutputStreamWriter writer = new OutputStreamWriter(os, encoding); + writer.write("\n"); + writer.write("\n"); + return writer; + } + + @Override + public void writeResultTo(OutputStream os, String encoding) + throws IOException { + if (encoding == null) { + encoding = HttpUtil.DEFAULT_CHARSET; + } + if (bindingProcessorError != null) { + log.debug("Detected error in binding processor, writing error as result."); + handleBindingProcessorError(os, encoding, templates); + return; + } else if (dataUrlResponse != null) { + log.debug("Writing data url response as result."); + String charEnc = HttpUtil.getCharset(dataUrlResponse.getContentType(), + true); + InputStreamReader isr = new InputStreamReader( + dataUrlResponse.getStream(), charEnc); + OutputStreamWriter osw = new OutputStreamWriter(os, encoding); + if (templates == null) { + StreamUtil.copyStream(isr, osw); + } else { + try { + Transformer transformer = templates.newTransformer(); + transformer.transform(new StreamSource(isr), new StreamResult(osw)); + } catch (TransformerException e) { + log.error("Exception occured during result transformation.", e); + // bindingProcessorError = new SLException(2008); + // handleBindingProcessorError(os, encoding, null); + return; + } + } + osw.flush(); + isr.close(); + } else if (slResult == null) { + // result not yet assigned -> must be a cancel + bindingProcessorError = new SLException(6001); + handleBindingProcessorError(os, encoding, templates); + return; + } else { + log.debug("Getting result from invoker."); + boolean fragment = false; + Writer writer; + if (slResult instanceof ErrorResult) { + writer = writeXMLDeclarationAndProcessingInstruction(os, encoding); + fragment = true; + } else { + writer = new OutputStreamWriter(os, encoding); + } + slResult.writeTo(new StreamResult(writer), templates, fragment); + writer.flush(); + } + } + + /** + * The response code from the dataurl server or 200 if no dataurl server + * created the result + * + * @return + */ + @Override + public int getResponseCode() { + return responseCode; + } + + /** + * All headers from the data url server in case of a direct forward from the + * dataurl server. + * + * @return + */ + @Override + public Map getResponseHeaders() { + LinkedHashMap headers = new LinkedHashMap(); + headers.put(HttpUtil.HTTP_HEADER_SERVER, getServerHeaderValue()); + headers.put(HttpUtil.HTTP_HEADER_SIGNATURE_LAYOUT, getSignatureLayoutHeaderValue()); + headers.putAll(responseHeaders); + return headers; + } + + public boolean isFinished() { + return finished; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java new file mode 100644 index 00000000..d4ee55d2 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpDataURLConnection.java @@ -0,0 +1,68 @@ +/* + * Copyright 2009 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.binding; + +import java.io.InputStream; +import java.net.URL; + +/** + * A HTTP DataURLConnection. + * + * @author mcentner + */ +public abstract class HttpDataURLConnection extends DataUrlConnection { + + /** + * Constructs a DataURL connection to the specified URL. + * + * @param url + * the URL to send responses and retrieve any further requests + */ + public HttpDataURLConnection(URL url) { + super(url); + } + + /** + * Set a HTTP header. + * + * @param key + * the key + * @param value + * multiple values are assumed to have the correct formatting + * (comma-separated list) + */ + public abstract void setHTTPHeader(String key, String value); + + /** + * Set a HTTP form parameter to be transmitted with the SLResult. + * + * @param name + * the name of the form parameter + * @param data + * the content of the form parameter + * @param contentType + * the content type (may be null) + * @param charSet + * the character set (may be null) + * @param transferEncoding + * the transfer encoding (may be null) + */ + public abstract void setHTTPFormParameter(String name, InputStream data, + String contentType, String charSet, String transferEncoding); + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java index 5ea7b25e..8282e34e 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java @@ -31,7 +31,8 @@ public class HttpUtil { public final static String HTTP_HEADER_CONTENT_TYPE = "Content-Type"; public static final String HTTP_HEADER_USER_AGENT = "User-Agent"; public static final String HTTP_HEADER_SERVER = "Server"; - public final static String HTTP_HEADER_REFERER = "Referer"; + public final static String HTTP_HEADER_REFERER = "Referer"; + public static final String HTTP_HEADER_SIGNATURE_LAYOUT = "SignatureLayout"; public final static String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding"; public final static String MULTIPART_FOTMDATA = "multipart/form-data"; public final static String MULTIPART_FOTMDATA_BOUNDARY = "boundary"; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java new file mode 100644 index 00000000..0054d52c --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpsDataURLConnection.java @@ -0,0 +1,72 @@ +/* +* Copyright 2009 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.binding; + +import java.io.IOException; +import java.net.URL; +import java.security.cert.Certificate; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSocketFactory; + +public abstract class HttpsDataURLConnection extends HttpDataURLConnection { + + /** + * Construct a new + * + * @param url + * @throws IOException + */ + public HttpsDataURLConnection(URL url) { + super(url); + } + + /** + * Sets the SSLSocketFactory to be used when this instance + * creates sockets for secure https URL connections. + * + * @param socketFactory + * the SSL socket factory + */ + public abstract void setSSLSocketFactory(SSLSocketFactory socketFactory); + + /** + * Sets the HostnameVerifier for this instance. + * + * @param hostnameVerifier + * the host name verifier + */ + public abstract void setHostnameVerifier(HostnameVerifier hostnameVerifier); + + /** + * Returns the server's certificate chain which was established as part of + * defining the session. + * + * @return an ordered array of server certificates, with the peer's own + * certificate first followed by any certificate authorities. + * + * @throws SSLPeerUnverifiedException + * if the peer is not verified. + * @throws IllegalStateException + * if this method is called before the connection has been + * established. + */ + public abstract Certificate[] getServerCertificates() throws SSLPeerUnverifiedException, IllegalStateException; + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java index 60bf69a4..a29101f4 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java @@ -14,93 +14,93 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.bku.binding; - -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Creates or converts Ids for BindingProcessors. - * @author wbauer - * - */ -public class IdFactory { - - public static int DEFAULT_NUMBER_OF_BITS = 168; - - private static Log log = LogFactory.getLog(IdFactory.class); - - private static IdFactory instance = new IdFactory(); - - private SecureRandom random; - private int numberOfBits = DEFAULT_NUMBER_OF_BITS; - - private IdFactory() { - try { - random = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - log.error("Cannot instantiate secure random" + e); - } - } - - public static IdFactory getInstance() { - return instance; - } - - - /** - * set the secure random number generator to create secure ids. - * - * @param random - * must not be null - */ - public void setSecureRandom(SecureRandom random) { - if (random == null) { - throw new NullPointerException("Cannot set secure random to null"); - } - this.random = random; - } - - /** - * Don't use this method unless you know exactly what you do ! - * Be sure to use a sufficient large entropy - * @param numberOfBits >=1 (although this small entropy does not make sense) - */ - public void setNumberOfBits(int numberOfBits) { - if (numberOfBits <1) { - throw new IllegalArgumentException("Cannot set number of bits < 1"); - } - this.numberOfBits = numberOfBits; - } - - public int getNumberOfBits() { - return numberOfBits; - } - - /** - * Creates a new Id object with the factory's secure RNG and the set number of - * bits. - * - * @return - */ - public Id createId() { - return new IdImpl(numberOfBits, random); - } - - /** - * Creates an Id object for the provided String - * - * @param idString - * may be null in this case the method call creates a new Id. - * @return - */ - public Id createId(String idString) { - if (idString == null) { - return createId(); - } - return new IdImpl(idString); - } -} \ No newline at end of file +package at.gv.egiz.bku.binding; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Creates or converts Ids for BindingProcessors. + * @author wbauer + * + */ +public class IdFactory { + + private final Logger log = LoggerFactory.getLogger(IdFactory.class); + + public static int DEFAULT_NUMBER_OF_BITS = 168; + + private static IdFactory instance = new IdFactory(); + + private SecureRandom random; + private int numberOfBits = DEFAULT_NUMBER_OF_BITS; + + private IdFactory() { + try { + random = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + log.error("Cannot instantiate secure random.", e); + } + } + + public static IdFactory getInstance() { + return instance; + } + + + /** + * set the secure random number generator to create secure ids. + * + * @param random + * must not be null + */ + public void setSecureRandom(SecureRandom random) { + if (random == null) { + throw new NullPointerException("Cannot set secure random to null"); + } + this.random = random; + } + + /** + * Don't use this method unless you know exactly what you do ! + * Be sure to use a sufficient large entropy + * @param numberOfBits >=1 (although this small entropy does not make sense) + */ + public void setNumberOfBits(int numberOfBits) { + if (numberOfBits <1) { + throw new IllegalArgumentException("Cannot set number of bits < 1"); + } + this.numberOfBits = numberOfBits; + } + + public int getNumberOfBits() { + return numberOfBits; + } + + /** + * Creates a new Id object with the factory's secure RNG and the set number of + * bits. + * + * @return + */ + public Id createId() { + return new IdImpl(numberOfBits, random); + } + + /** + * Creates an Id object for the provided String + * + * @param idString + * may be null in this case the method call creates a new Id. + * @return + */ + public Id createId(String idString) { + if (idString == null) { + return createId(); + } + return new IdImpl(idString); + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java index c8a76823..096754a6 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java @@ -22,8 +22,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Implementation that uses a Base64 representation for self generated Ids. @@ -31,7 +31,8 @@ import org.apache.commons.logging.LogFactory; * */ public class IdImpl implements at.gv.egiz.bku.binding.Id { - private static Log log = LogFactory.getLog(IdImpl.class); + + private final Logger log = LoggerFactory.getLogger(IdImpl.class); private String idString; @@ -50,7 +51,7 @@ public class IdImpl implements at.gv.egiz.bku.binding.Id { b64.close(); idString = new String(baos.toByteArray()); } catch (IOException e) { - log.error("Cannot create secure id: "+e); + log.error("Cannot create secure id.", e); } } @@ -80,4 +81,4 @@ public class IdImpl implements at.gv.egiz.bku.binding.Id { return false; } } -} \ No newline at end of file +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java index 211deee7..081d24d4 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java @@ -14,76 +14,78 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.bku.binding; - -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Factory to get a matching instance for a encoded input stream when reading a http request. - * - */ -public class InputDecoderFactory { - - public final static String MULTIPART_FORMDATA = "multipart/form-data"; - public final static String URL_ENCODED = "application/x-www-form-urlencoded"; - - private static InputDecoderFactory instance = new InputDecoderFactory(); - private static Log log = LogFactory.getLog(InputDecoderFactory.class); - - private String defaultEncoding = URL_ENCODED; - private Map> decoderMap = new HashMap>(); - - private InputDecoderFactory() { - decoderMap.put(MULTIPART_FORMDATA, MultiPartFormDataInputDecoder.class); - decoderMap.put(URL_ENCODED, XWWWFormUrlInputDecoder.class); - } - - public static InputDecoder getDefaultDecoder(InputStream is) { - return getDecoder(instance.defaultEncoding, is); - } - - /** - * - * @param contentType - * @param is - * @return null if the content type is not supported - */ - public static InputDecoder getDecoder(String contentType, InputStream is) { - String prefix = contentType.split(";")[0].trim().toLowerCase(); - Class dec = instance.decoderMap.get(prefix); - if (dec == null) { - log.info("Unknown encoding prefix " + contentType); - return null; - } - InputDecoder id; - try { - id = dec.newInstance(); - id.setContentType(contentType); - id.setInputStream(is); - return id; - } catch (InstantiationException e) { - log.error(e); - throw new IllegalArgumentException( - "Cannot get an input decoder for content type: " + contentType); - } catch (IllegalAccessException e) { - log.error(e); - throw new IllegalArgumentException( - "Cannot get an input decoder for content type: " + contentType); - } - } - - /** - * Allows to register decoders for special mime types. - * @param mimeType - * @param decoder - */ - public static void registerDecoder(String mimeType, - Class decoder) { - instance.decoderMap.put(mimeType.toLowerCase(), decoder); - } -} +package at.gv.egiz.bku.binding; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Factory to get a matching instance for a encoded input stream when reading a http request. + * + */ +public class InputDecoderFactory { + + public final static String MULTIPART_FORMDATA = "multipart/form-data"; + public final static String URL_ENCODED = "application/x-www-form-urlencoded"; + + private static InputDecoderFactory instance = new InputDecoderFactory(); + + private String defaultEncoding = URL_ENCODED; + private Map> decoderMap = new HashMap>(); + + private InputDecoderFactory() { + decoderMap.put(MULTIPART_FORMDATA, MultiPartFormDataInputDecoder.class); + decoderMap.put(URL_ENCODED, XWWWFormUrlInputDecoder.class); + } + + public static InputDecoder getDefaultDecoder(InputStream is) { + return getDecoder(instance.defaultEncoding, is); + } + + /** + * + * @param contentType + * @param is + * @return null if the content type is not supported + */ + public static InputDecoder getDecoder(String contentType, InputStream is) { + + Logger log = LoggerFactory.getLogger(InputDecoderFactory.class); + + String prefix = contentType.split(";")[0].trim().toLowerCase(); + Class dec = instance.decoderMap.get(prefix); + if (dec == null) { + log.info("Unknown encoding prefix " + contentType); + return null; + } + InputDecoder id; + try { + id = dec.newInstance(); + id.setContentType(contentType); + id.setInputStream(is); + return id; + } catch (InstantiationException e) { + log.error("Failed to instantiate InputDecoder.", e); + throw new IllegalArgumentException( + "Cannot get an input decoder for content type: " + contentType); + } catch (IllegalAccessException e) { + log.error("Failed to instantiate InputDecoder.", e); + throw new IllegalArgumentException( + "Cannot get an input decoder for content type: " + contentType); + } + } + + /** + * Allows to register decoders for special mime types. + * @param mimeType + * @param decoder + */ + public static void registerDecoder(String mimeType, + Class decoder) { + instance.decoderMap.put(mimeType.toLowerCase(), decoder); + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java index f8b13553..2dd57f12 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java @@ -14,120 +14,121 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.bku.binding; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; - -import org.apache.commons.fileupload.FileItemIterator; -import org.apache.commons.fileupload.FileItemStream; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slexceptions.SLRuntimeException; - -/** - * The code to detect the multipart boundary is based on - * org.apache.commons.fileupload.FileUploadBase of - * http://commons.apache.org/fileupload/ - * - * @author wbauer - * - */ -public class MultiPartFormDataInputDecoder implements InputDecoder, - RequestContext { - - private static Log log = LogFactory - .getLog(MultiPartFormDataInputDecoder.class); - - private String contentType; - private InputStream stream; - - @Override - public void setContentType(String contentType) { - this.contentType = contentType; - } - - @Override - public String getCharacterEncoding() { - return null; - } - - @Override - public int getContentLength() { - return 0; - } - - @Override - public String getContentType() { - return contentType; - } - - @Override - public InputStream getInputStream() throws IOException { - return stream; - } - - @Override - public Iterator getFormParameterIterator() { - try { - FileUpload fup = new FileUpload(); - FileItemIterator fit = fup.getItemIterator(this); - return new IteratorDelegator(fit); - } catch (Exception iox) { - log.error("Cannot decode multipart form data stream " + iox); - throw new SLRuntimeException(iox); - } - } - - @Override - public void setInputStream(InputStream is) { - stream = is; - } - - static class IteratorDelegator implements Iterator { - - private FileItemIterator fileItemIterator; - - public IteratorDelegator(FileItemIterator fit) { - fileItemIterator = fit; - } - - @Override - public boolean hasNext() { - try { - return fileItemIterator.hasNext(); - } catch (FileUploadException e) { - log.error(e); - throw new SLRuntimeException(e); - } catch (IOException e) { - log.error(e); - throw new SLRuntimeException(e); - } - } - - @Override - public FormParameter next() { - try { - FileItemStream item = fileItemIterator.next(); - return new FormParameterImpl(item.getContentType(), - item.getFieldName(), item.openStream(), item.getHeaders()); - } catch (FileUploadException e) { - log.error(e); - throw new SLRuntimeException(e); - } catch (IOException e) { - log.error(e); - throw new SLRuntimeException(e); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException("Remove not supported"); - } - } -} +package at.gv.egiz.bku.binding; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.apache.commons.fileupload.FileItemIterator; +import org.apache.commons.fileupload.FileItemStream; +import org.apache.commons.fileupload.FileUpload; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.RequestContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.slexceptions.SLRuntimeException; + +/** + * The code to detect the multipart boundary is based on + * org.apache.commons.fileupload.FileUploadBase of + * http://commons.apache.org/fileupload/ + * + * @author wbauer + * + */ +public class MultiPartFormDataInputDecoder implements InputDecoder, + RequestContext { + + private final Logger log = LoggerFactory.getLogger(MultiPartFormDataInputDecoder.class); + + private String contentType; + private InputStream stream; + + @Override + public void setContentType(String contentType) { + this.contentType = contentType; + } + + @Override + public String getCharacterEncoding() { + return null; + } + + @Override + public int getContentLength() { + return 0; + } + + @Override + public String getContentType() { + return contentType; + } + + @Override + public InputStream getInputStream() throws IOException { + return stream; + } + + @Override + public Iterator getFormParameterIterator() { + try { + FileUpload fup = new FileUpload(); + FileItemIterator fit = fup.getItemIterator(this); + return new IteratorDelegator(fit); + } catch (Exception iox) { + log.error("Cannot decode multipart form data stream " + iox); + throw new SLRuntimeException(iox); + } + } + + @Override + public void setInputStream(InputStream is) { + stream = is; + } + + static class IteratorDelegator implements Iterator { + + private final Logger log = LoggerFactory.getLogger(MultiPartFormDataInputDecoder.class); + + private FileItemIterator fileItemIterator; + + public IteratorDelegator(FileItemIterator fit) { + fileItemIterator = fit; + } + + @Override + public boolean hasNext() { + try { + return fileItemIterator.hasNext(); + } catch (FileUploadException e) { + log.error("Failed to get next file item.", e); + throw new SLRuntimeException(e); + } catch (IOException e) { + log.error("Failed to get next file item.", e); + throw new SLRuntimeException(e); + } + } + + @Override + public FormParameter next() { + try { + FileItemStream item = fileItemIterator.next(); + return new FormParameterImpl(item.getContentType(), + item.getFieldName(), item.openStream(), item.getHeaders()); + } catch (FileUploadException e) { + log.error("Failed to get next file item.", e); + throw new SLRuntimeException(e); + } catch (IOException e) { + log.error("Failed to get next file item.", e); + throw new SLRuntimeException(e); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Remove not supported"); + } + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java deleted file mode 100644 index 913259f6..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ProcessingContext.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.binding; - -import java.util.Hashtable; -import java.util.Map; -import java.util.concurrent.Future; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * - * @author Clemens Orthacker - */ -public class ProcessingContext { - - public static final String BINDING_PROCESSOR = "binding.processor"; - public static final String FUTURE = "future"; - - protected static final Log log = LogFactory.getLog(ProcessingContext.class); - - protected Map properties = new Hashtable(); - - public ProcessingContext(BindingProcessor bp, Future future) { - properties.put(BINDING_PROCESSOR, bp); - properties.put(FUTURE, future); - } - - public BindingProcessor getBindingProcessor() { - return (BindingProcessor) properties.get(BINDING_PROCESSOR); - } - - public Future getFuture() { - return (Future) properties.get(FUTURE); - } - - public Object get(String key) { - return properties.get(key); - } - - public void put(String key, Object value) { - properties.put(key, value); - } -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java deleted file mode 100644 index 6c2dcb9f..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java +++ /dev/null @@ -1,26 +0,0 @@ -/* -* 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.binding; - -/** - * Could be used to remove expired BindingProcessor objects from a BindingProcessorManager. - * - */ -public interface RemovalStrategy { - public void execute(); - public void setBindingProcessorManager(BindingProcessorManager bp); -} \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java index a23d96e8..c2ee4ee1 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java @@ -16,11 +16,14 @@ */ package at.gv.egiz.bku.binding; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.bku.accesscontroller.SecurityManagerFacade; +import at.gv.egiz.bku.jmx.ComponentMXBean; +import at.gv.egiz.bku.jmx.ComponentState; import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slcommands.SLCommandInvoker; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slcommands.SLSourceContext; @@ -31,10 +34,11 @@ import at.gv.egiz.bku.slexceptions.SLException; * This class implements the entry point for the CCEs security management. * */ -public class SLCommandInvokerImpl implements SLCommandInvoker { +public class SLCommandInvokerImpl implements SLCommandInvoker, ComponentMXBean { - private static Log log = LogFactory.getLog(SLCommandInvokerImpl.class); + private final Logger log = LoggerFactory.getLogger(SLCommandInvokerImpl.class); + protected SLCommandContext commandContext; protected SLCommand command; protected SLResult result; protected SecurityManagerFacade securityManager; @@ -46,12 +50,11 @@ public class SLCommandInvokerImpl implements SLCommandInvoker { */ public void invoke(SLSourceContext aContext) throws SLException { if (securityManager == null) { - log.warn("Security policy not implemented yet, invoking command: " - + command); - result = command.execute(); + log.warn("Security policy not implemented yet, invoking command: {}.", command); + result = command.execute(commandContext); } else { if (securityManager.mayInvokeCommand(command, aContext)) { - result = command.execute(); + result = command.execute(commandContext); } else { throw new SLException(6002); } @@ -60,9 +63,7 @@ public class SLCommandInvokerImpl implements SLCommandInvoker { public SLResult getResult(SLTargetContext aContext) throws SLException { if (securityManager == null) { - log - .warn("Security policy not implemented yet, getting result of command: " - + command); + log.warn("Security policy not implemented yet, getting result of command: {}.", command); return result; } else { if (securityManager.maySendResult(command, aContext)) { @@ -73,7 +74,8 @@ public class SLCommandInvokerImpl implements SLCommandInvoker { } } - public void setCommand(SLCommand aCmd) { + public void setCommand(SLCommandContext commandContext, SLCommand aCmd) { + this.commandContext = commandContext; command = aCmd; } @@ -92,4 +94,9 @@ public class SLCommandInvokerImpl implements SLCommandInvoker { this.securityManager = securityManager; } -} \ No newline at end of file + @Override + public ComponentState checkComponentState() { + return new ComponentState(true); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java index 9279130d..36d5f723 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java @@ -274,6 +274,7 @@ public class XWWWFormUrlInputIterator implements Iterator { pos = 0; } int c2 = Character.digit(buf[pos], 16); + pos++; return ((c1 << 4) | c2); } else { return buf[pos++]; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java deleted file mode 100644 index 6a95b369..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidator.java +++ /dev/null @@ -1,13 +0,0 @@ -package at.gv.egiz.bku.conf; - -import iaik.x509.X509Certificate; - -import java.io.File; - -public interface CertValidator { - - public abstract void init(File certDir, File caDir); - - public abstract boolean isCertificateValid(String transactionId, X509Certificate[] certs); - -} \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java deleted file mode 100644 index 766fe355..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java +++ /dev/null @@ -1,110 +0,0 @@ -package at.gv.egiz.bku.conf; - -import iaik.logging.LogConfigurationException; -import iaik.logging.TransactionId; -import iaik.logging.impl.TransactionIdImpl; -import iaik.logging.LoggerConfig; -import iaik.pki.DefaultPKIConfiguration; -import iaik.pki.DefaultPKIProfile; -import iaik.pki.PKIConfiguration; -import iaik.pki.PKIException; -import iaik.pki.PKIFactory; -import iaik.pki.PKIModule; -import iaik.pki.PKIProfile; -import iaik.pki.revocation.RevocationSourceTypes; -import iaik.pki.store.certstore.CertStoreParameters; -import iaik.pki.store.certstore.directory.DefaultDirectoryCertStoreParameters; -import iaik.pki.store.truststore.DefaultTrustStoreProfile; -import iaik.pki.store.truststore.TrustStoreProfile; -import iaik.pki.store.truststore.TrustStoreTypes; -import iaik.x509.X509Certificate; - -import java.io.File; -import java.util.Date; -import java.util.Properties; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class CertValidatorImpl implements CertValidator { - - private static Log log = LogFactory.getLog(CertValidatorImpl.class); - - private PKIFactory pkiFactory; - private PKIProfile profile; - - public CertValidatorImpl() { - - } - - /* (non-Javadoc) - * @see at.gv.egiz.bku.conf.CertValidator#init(java.io.File, java.io.File) - */ - public void init(File certDir, File caDir) { - // initialize IAIK logging for PKI module - log.debug("Configuring logging for IAIK PKI module"); - iaik.logging.LogFactory.configure(new LoggerConfig() { - - @Override - public Properties getProperties() throws LogConfigurationException { - return null; - } - - @Override - public String getNodeId() { - return "pki"; - } - - @Override - public String getFactory() { - return IAIKCommonsLogFactory.class.getName(); - } - }); - - - // the parameters specifying the directory certstore - CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters( - "CS-001", certDir.getAbsolutePath(), true, false) }; - - // create a new PKI configuration using the certstore parameters - PKIConfiguration pkiConfig = new DefaultPKIConfiguration( - certStoreParameters); - - // Transaction ID for logging - TransactionId tid = new TransactionIdImpl("Configure-PKI"); - // get PKI factory for creating PKI module(s) - pkiFactory = PKIFactory.getInstance(); - // configure the factory - try { - pkiFactory.configure(pkiConfig, tid); - } catch (PKIException e) { - log.error("Cannot configure PKI module", e); - } - // the truststore to be used - TrustStoreProfile trustProfile = new DefaultTrustStoreProfile("TS-001", - TrustStoreTypes.DIRECTORY, caDir.getAbsolutePath()); - profile = new DefaultPKIProfile(trustProfile); - ((DefaultPKIProfile)profile).setAutoAddCertificates(true); - ((DefaultPKIProfile) profile).setPreferredServiceOrder(new String[] { - RevocationSourceTypes.OCSP, RevocationSourceTypes.CRL }); - } - - /* (non-Javadoc) - * @see at.gv.egiz.bku.conf.CertValidator#isCertificateValid(java.lang.String, iaik.x509.X509Certificate[]) - */ - public boolean isCertificateValid(String transactionId, - X509Certificate[] certs) { - // Transaction ID for logging - TransactionId tid = new TransactionIdImpl(transactionId); - // get a PKIModule - PKIModule pkiModule; - try { - pkiModule = pkiFactory.getPKIModule(profile); - return pkiModule.validateCertificate(new Date(), certs[0], certs, null, - tid).isCertificateValid(); - } catch (PKIException e) { - log.error("Cannot validate certificate", e); - } - return false; - } -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java deleted file mode 100644 index f813b14d..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configuration.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.conf; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * BKU Common Configuration - * - * Injected to BKU Common classes as defined in mocca-conf.xml - * - * Replace at.gv.egiz.bku.conf.Configurator, - * currently only few configuration options are supported. - * - * @author Clemens Orthacker - */ -public class Configuration { - - public static final int MAX_DATAURL_HOPS_DEFAULT = 50; - public static final String IMPLEMENTATION_NAME_DEFAULT = "MOCCA"; - public static final String IMPLEMENTATION_VERSION_DEFAULT = "UNKNOWN"; - - private static final Log log = LogFactory.getLog(Configuration.class); - - private int maxDataUrlHops = -1; - private String implementationName; - private String implementationVersion; - - public void setMaxDataUrlHops(int maxDataUrlHops) { - this.maxDataUrlHops = maxDataUrlHops; - } - - /** - * Defines the maximum number of dataurl connects that are allowed within a - * single SL Request processing. - */ - public int getMaxDataUrlHops() { - if (maxDataUrlHops < 0) { - log.warn("maxDataUrlHops not configured, using default: " + MAX_DATAURL_HOPS_DEFAULT); - return MAX_DATAURL_HOPS_DEFAULT; - } - return maxDataUrlHops; - } - - /** - * @return the implementationName - */ - public String getImplementationName() { - if (implementationName == null) { - log.info("implementationName not configured, using default: " + IMPLEMENTATION_NAME_DEFAULT); - return "MOCCA"; - } - return implementationName; - } - - /** - * @param implementationName the implementationName to set - */ - public void setImplementationName(String implementationName) { - this.implementationName = implementationName; - } - - /** - * @return the implementationVersion - */ - public String getImplementationVersion() { - if (implementationName == null) { - log.info("implementationName not configured, using default: " + IMPLEMENTATION_VERSION_DEFAULT); - return IMPLEMENTATION_VERSION_DEFAULT; - } - return implementationVersion; - } - - /** - * @param implementationVersion the implementationVersion to set - */ - public void setImplementationVersion(String implementationVersion) { - this.implementationVersion = implementationVersion; - } - - - - -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java deleted file mode 100644 index 50f5d2b4..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java +++ /dev/null @@ -1,467 +0,0 @@ -package at.gv.egiz.bku.conf; - -import iaik.security.ecc.provider.ECCProvider; -import iaik.security.provider.IAIK; -import iaik.xml.crypto.XSecProvider; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.GeneralSecurityException; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.Provider; -import java.security.Security; -import java.security.Provider.Service; -import java.security.cert.CertStore; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.LDAPCertStoreParameters; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.binding.DataUrl; -import at.gv.egiz.bku.slcommands.impl.xsect.DataObject; -import at.gv.egiz.bku.slcommands.impl.xsect.STALProvider; -import at.gv.egiz.bku.slexceptions.SLRuntimeException; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; -import javax.net.ssl.SSLSocketFactory; - -public abstract class Configurator { - - private Log log = LogFactory.getLog(Configurator.class); - - public final static String USERAGENT_CONFIG_P = "UserAgent"; - public static final String DATAURLCONNECTION_CONFIG_P = "DataURLConnectionImplClass"; - - public static final String USERAGENT_DEFAULT = "citizen-card-environment/1.2 MOCCA/UNKNOWN"; - public static final String USERAGENT_BASE = "citizen-card-environment/1.2 MOCCA/"; - - public static final String SIGNATURE_LAYOUT = "SignatureLayout"; - - protected Properties properties; - - protected CertValidator certValidator; - protected String signaturLayoutVersion; - - protected Configurator() { - } - - protected abstract File getCertDir(); - - protected abstract File getCADir(); - - protected abstract InputStream getManifest(); - - private X509Certificate[] getCACerts() throws IOException, - CertificateException { - List caCerts = new ArrayList(); - File caDir = getCADir(); - if (caDir != null) { - if (!caDir.isDirectory()) { - log.error("Expecting directory as SSL.caDirectory parameter"); - throw new SLRuntimeException( - "Expecting directory as SSL.caDirectory parameter"); - } - log.info("loading trustStore from " + caDir.getAbsolutePath()); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - for (File f : caDir.listFiles()) { - try { - FileInputStream fis = new FileInputStream(f); - X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); - fis.close(); - log.debug("Adding trusted cert " + cert.getSubjectDN()); - caCerts.add(cert); - } catch (Exception e) { - log.error("Cannot add trusted ca", e); - } - } - return caCerts.toArray(new X509Certificate[caCerts.size()]); - } else { - log.warn("No CA certificates configured"); - } - return null; - } - - protected List getCertstore() throws IOException, - CertificateException, InvalidAlgorithmParameterException, - NoSuchAlgorithmException { - List resultList = new ArrayList(); - File certDir = getCertDir(); - if (certDir != null) { - if (!certDir.isDirectory()) { - log.error("Expecting directory as SSL.certDirectory parameter"); - throw new SLRuntimeException( - "Expecting directory as SSL.certDirectory parameter"); - } - log.info("loading certStore from " + certDir.getAbsolutePath()); - List certCollection = new LinkedList(); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - for (File f : certDir.listFiles()) { - try { - FileInputStream fis = new FileInputStream(f); - X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); - certCollection.add(cert); - fis.close(); - log - .trace("Added following cert to certstore: " - + cert.getSubjectDN()); - } catch (Exception ex) { - log.error("Cannot add certificate", ex); - } - } - CollectionCertStoreParameters csp = new CollectionCertStoreParameters( - certCollection); - resultList.add(CertStore.getInstance("Collection", csp)); - log.info("Added collection certstore"); - } else { - log.warn("No certstore directory configured"); - } - String ldapHost = getProperty("SSL.ldapServer"); - if ((ldapHost != null) && (!"".equals(ldapHost))) { - String ldapPortString = getProperty("SSL.ldapPort"); - int ldapPort = 389; - if (ldapPortString != null) { - try { - ldapPort = Integer.parseInt(ldapPortString); - } catch (NumberFormatException nfe) { - log.error("Invalid ldap port, using default 389"); - } - } else { - log.warn("ldap port not specified, using default 389"); - } - LDAPCertStoreParameters ldapParams = new LDAPCertStoreParameters( - ldapHost, ldapPort); - resultList.add(CertStore.getInstance("LDAP", ldapParams)); - log.info("Added LDAP certstore"); - } - return resultList; - } - - protected void configUrlConnections() { - HttpsURLConnection.setFollowRedirects(false); - HttpURLConnection.setFollowRedirects(false); - } - - protected void configureProviders() { - log.debug("Registering security providers"); - - IAIK iaikProvider = new IAIK(); - if (Security.getProvider(iaikProvider.getName()) == null) { - // register IAIK provider at first position - Security.insertProviderAt(iaikProvider, 1); - } else { - // IAIK provider already registered - log.info("Provider " + iaikProvider.getName() + " already registered."); - } - - ECCProvider eccProvider = new ECCProvider(false); - if (Security.getProvider(eccProvider.getName()) == null) { - // register ECC Provider at second position - Security.insertProviderAt(eccProvider, 2); - } else { - // ECC Provider already registered - log.info("Provider " + eccProvider.getName() + " already registered."); - } - - // registering STALProvider as delegation provider for XSECT - STALProvider stalProvider = new STALProvider(); - if (Security.getProvider(stalProvider.getName()) == null) { - // register STAL provider - Set services = stalProvider.getServices(); - StringBuilder sb = new StringBuilder(); - for (Service service : services) { - String algorithm = service.getType() + "." + service.getAlgorithm(); - XSecProvider.setDelegationProvider(algorithm, stalProvider.getName()); - sb.append("\n" + algorithm); - } - log - .debug("Registered STALProvider as XSecProvider delegation provider for the following services : " - + sb.toString()); - - Security.addProvider(stalProvider); - } else { - // STAL Provider already registered - log.info("Provider " + stalProvider.getName() + " already registered."); - } - - if (Security.getProvider(XSecProvider.NAME) == null) { - // register XML Security provider - XSecProvider.addAsProvider(false); - } else { - log.info("Provider " + XSecProvider.NAME + " already registered."); - } - - if (log.isDebugEnabled()) { - StringBuilder sb = new StringBuilder(); - sb.append("Registered providers: "); - int i = 1; - for (Provider prov : Security.getProviders()) { - sb.append((i++) + ". : " + prov); - } - log.debug(sb.toString()); - } - } - - protected void configViewer() { - String bv = properties.getProperty("ValidateHashDataInputs"); - if (bv != null) { - DataObject.enableHashDataInputValidation(Boolean.parseBoolean(bv)); - } else { - log.warn("ValidateHashDataInputs not set, falling back to default"); - } - } - - public void configureSingatureLayoutVersion() { - if (properties.get(SIGNATURE_LAYOUT) == null) { - try { - String classContainer = Configurator.class.getProtectionDomain() - .getCodeSource().getLocation().toString(); - URL manifestUrl = new URL("jar:" + classContainer - + "!/META-INF/MANIFEST.MF"); - Manifest manifest = new Manifest(manifestUrl.openStream()); - Attributes att = manifest.getMainAttributes(); - String layout = null; - if (att != null) { - layout = att.getValue(SIGNATURE_LAYOUT); - } - if (layout != null) { - log.info("setting SignatureLayout header to " + layout); - properties.put(SIGNATURE_LAYOUT, layout); - } else { - log.warn("no SignatureLayout version defined"); - } - } catch (Exception ex) { - log.warn("Cannot read manifest", ex); - } - } - } - - public void configureNetwork() { - String proxy = getProperty("HTTPProxyHost"); - String portString = getProperty("HTTPProxyPort"); - if ((proxy == null) || (proxy.equals(""))) { - log.info("No proxy configured"); - } else { - log.info("Setting proxy to: " + proxy + ":" + portString); - System.setProperty("proxyHost", proxy); - System.setProperty("proxyPort", portString); - } - String timeout = getProperty("DefaultSocketTimeout"); - if ((timeout != null) && (!timeout.equals(""))) { - System.setProperty("sun.net.client.defaultConnectTimeout", timeout); - } - } - - public void configureVersion() { - if (properties.getProperty(USERAGENT_CONFIG_P) == null) { - Properties p = new Properties(); - try { - InputStream is = getManifest(); - if (is != null) { - p.load(getManifest()); - String version = p.getProperty("Implementation-Build"); - if (version == null) { - version="UNKNOWN"; - } - properties.setProperty(USERAGENT_CONFIG_P, USERAGENT_BASE + version); - log.debug("Setting user agent to: " - + properties.getProperty(USERAGENT_CONFIG_P)); - } else { - log.warn("Failed to read manifest, setting user-agent to " + USERAGENT_DEFAULT); - properties.setProperty(USERAGENT_CONFIG_P, USERAGENT_DEFAULT); - } - } catch (IOException e) { - log.error(e); - } - } else { - log.info("using configured user agent " + properties.getProperty(USERAGENT_CONFIG_P)); - } - } - - /** - * TODO cleanup configuration (read MANIFEST, DataURLconfig,...) - */ - public void configure() { - configureProviders(); - configUrlConnections(); - configViewer(); - configureSSL(); - configureVersion(); - configureSingatureLayoutVersion(); - configureNetwork(); - //after configureVersion() and configureSignatureLayoutVersion() - DataUrl.setConfiguration(properties); - } - - public void setConfiguration(Properties props) { - this.properties = props; - } - - public String getProperty(String key) { - if (properties != null) { - return properties.getProperty(key); - } - return null; - } - - public void configureSSL() { - X509Certificate[] caCerts = null; - try { - caCerts = getCACerts(); - } catch (Exception e1) { - log.error("Cannot load CA certificates", e1); - } - String disableAll = getProperty("SSL.disableAllChecks"); - String disableHostnameVerification = getProperty("SSL.disableHostnameVerification"); - try { - KeyManager[] km = null; - SSLContext sslCtx = SSLContext - .getInstance(getProperty("SSL.sslProtocol")); - if ((disableAll != null) && (Boolean.parseBoolean(disableAll))) { - log.warn("--------------------------------------"); - log.warn(" Disabling SSL Certificate Validation "); - log.warn("--------------------------------------"); - - sslCtx.init(km, - new TrustManager[] { new MyAlwaysTrustManager(caCerts) }, null); - } else { - MyPKITrustManager pkixTM = new MyPKITrustManager(certValidator, - getCertDir(), getCADir(), caCerts); - sslCtx.init(km, new TrustManager[] { pkixTM }, null); - } - DataUrl.setSSLSocketFactory(sslCtx.getSocketFactory()); - URLDereferencer.getInstance().setSSLSocketFactory( - sslCtx.getSocketFactory()); - } catch (Exception e) { - log.error("Cannot configure SSL", e); - } - if ((disableAll != null && Boolean.parseBoolean(disableAll)) - || (disableHostnameVerification != null && Boolean - .parseBoolean(disableHostnameVerification))) { - log.warn("---------------------------------"); - log.warn(" Disabling Hostname Verification "); - log.warn("---------------------------------"); - DataUrl.setHostNameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }); - URLDereferencer.getInstance().setHostnameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }); - } - } - - public void setCertValidator(CertValidator certValidator) { - this.certValidator = certValidator; - } - - private static class MyPKITrustManager implements X509TrustManager { - private static Log log = LogFactory.getLog(MyPKITrustManager.class); - - private CertValidator certValidator; - private X509Certificate[] trustedCerts; - - public MyPKITrustManager(CertValidator cv, File certStore, File trustStore, - X509Certificate[] trustedCerts) { - certValidator = cv; - certValidator.init(certStore, trustStore); - this.trustedCerts = trustedCerts; - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - log.error("Did not expect this method to get called"); - throw new CertificateException("Method not implemented"); - } - - private static iaik.x509.X509Certificate[] convertCerts( - X509Certificate[] certs) throws GeneralSecurityException { - iaik.x509.X509Certificate[] retVal = new iaik.x509.X509Certificate[certs.length]; - int i = 0; - for (X509Certificate cert : certs) { - if (cert instanceof iaik.x509.X509Certificate) { - retVal[i++] = (iaik.x509.X509Certificate) cert; - } else { - retVal[i++] = new iaik.x509.X509Certificate(cert.getEncoded()); - } - } - return retVal; - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - try { - boolean valid = certValidator.isCertificateValid(Thread.currentThread() - .getName(), convertCerts(chain)); - if (!valid) { - throw new CertificateException("Certificate not valid"); - } - } catch (GeneralSecurityException e) { - throw new CertificateException(e); - } - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return trustedCerts; - } - } - - private static class MyAlwaysTrustManager implements X509TrustManager { - private static Log log = LogFactory.getLog(MyAlwaysTrustManager.class); - private X509Certificate[] trustedCerts; - - public MyAlwaysTrustManager(X509Certificate[] trustedCerts) { - this.trustedCerts = trustedCerts; - } - - @Override - public void checkClientTrusted(X509Certificate[] arg0, String arg1) - throws CertificateException { - log.error("Did not expect this method to get called"); - throw new CertificateException("Method not implemented"); - } - - @Override - public void checkServerTrusted(X509Certificate[] certs, String arg1) - throws CertificateException { - log.warn("-------------------------------------"); - log.warn("SSL Certificate Validation Disabled !"); - log.warn("-------------------------------------"); - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return trustedCerts; - } - } -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java deleted file mode 100644 index 1b7dd189..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * - */ -package at.gv.egiz.bku.conf; - -import iaik.logging.Log; -import iaik.logging.TransactionId; - -/** - * @author mcentner - * - */ -public class IAIKCommonsLog implements Log { - - /** - * The id that will be written to the log if the transactionid == null - */ - public final static String NO_ID = "Null-ID"; - - protected org.apache.commons.logging.Log commonsLog; - - protected String nodeId; - - public IAIKCommonsLog(org.apache.commons.logging.Log log) { - this.commonsLog = log; - } - - /* (non-Javadoc) - * @see iaik.logging.Log#debug(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) - */ - @Override - public void debug(TransactionId transactionId, Object message, Throwable t) { - if (commonsLog.isDebugEnabled()) { - commonsLog.debug(nodeId + ": " - + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " - + message, t); - } - } - - /* (non-Javadoc) - * @see iaik.logging.Log#info(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) - */ - @Override - public void info(TransactionId transactionId, Object message, Throwable t) { - if (commonsLog.isInfoEnabled()) { - commonsLog.info(nodeId + ": " - + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " - + message, t); - } - } - - /* (non-Javadoc) - * @see iaik.logging.Log#warn(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) - */ - @Override - public void warn(TransactionId transactionId, Object message, Throwable t) { - if (commonsLog.isWarnEnabled()) { - commonsLog.warn(nodeId + ": " - + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " - + message, t); - } - } - - /* (non-Javadoc) - * @see iaik.logging.Log#error(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) - */ - @Override - public void error(TransactionId transactionId, Object message, Throwable t) { - if (commonsLog.isErrorEnabled()) { - commonsLog.error(nodeId + ": " - + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " - + message, t); - } - } - - /* (non-Javadoc) - * @see iaik.logging.Log#fatal(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) - */ - @Override - public void fatal(TransactionId transactionId, Object message, Throwable t) { - if (commonsLog.isFatalEnabled()) { - commonsLog.fatal(nodeId + ": " - + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " - + message, t); - } - } - - /* (non-Javadoc) - * @see iaik.logging.Log#setNodeId(java.lang.String) - */ - @Override - public void setNodeId(String nodeId) { - this.nodeId = nodeId; - } - - /* (non-Javadoc) - * @see iaik.logging.Log#getNodeId() - */ - @Override - public String getNodeId() { - return nodeId; - } - - /* (non-Javadoc) - * @see iaik.logging.Log#isDebugEnabled() - */ - @Override - public boolean isDebugEnabled() { - return commonsLog.isDebugEnabled(); - } - - /* (non-Javadoc) - * @see iaik.logging.Log#isInfoEnabled() - */ - @Override - public boolean isInfoEnabled() { - return commonsLog.isInfoEnabled(); - } - - /* (non-Javadoc) - * @see iaik.logging.Log#isWarnEnabled() - */ - @Override - public boolean isWarnEnabled() { - return commonsLog.isWarnEnabled(); - } - - /* (non-Javadoc) - * @see iaik.logging.Log#isErrorEnabled() - */ - @Override - public boolean isErrorEnabled() { - return commonsLog.isErrorEnabled(); - } - - /* (non-Javadoc) - * @see iaik.logging.Log#isFatalEnabled() - */ - @Override - public boolean isFatalEnabled() { - return commonsLog.isFatalEnabled(); - } - -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java deleted file mode 100644 index 14e2c757..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * - */ -package at.gv.egiz.bku.conf; - -import org.apache.commons.logging.impl.WeakHashtable; - -import iaik.logging.Log; -import iaik.logging.LogConfigurationException; -import iaik.logging.LogFactory; - -/** - * @author mcentner - * - */ -public class IAIKCommonsLogFactory extends LogFactory { - - protected WeakHashtable instances = new WeakHashtable(); - - /* (non-Javadoc) - * @see iaik.logging.LogFactory#getInstance(java.lang.String) - */ - @Override - public Log getInstance(String name) throws LogConfigurationException { - org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(name); - Log log = (Log) instances.get(commonsLog); - if (log == null) { - log = new IAIKCommonsLog(commonsLog); - log.setNodeId(node_id_); - instances.put(commonsLog, log); - } - return log; - } - - /* (non-Javadoc) - * @see iaik.logging.LogFactory#getInstance(java.lang.Class) - */ - @SuppressWarnings("unchecked") - @Override - public Log getInstance(Class clazz) throws LogConfigurationException { - org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(clazz); - Log log = (Log) instances.get(commonsLog); - if (log == null) { - log = new IAIKCommonsLog(commonsLog); - log.setNodeId(node_id_); - instances.put(commonsLog, log); - } - return log; - } - - /* (non-Javadoc) - * @see iaik.logging.LogFactory#release() - */ - @Override - public void release() { - instances.clear(); - } - -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java new file mode 100644 index 00000000..b04509a0 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java @@ -0,0 +1,146 @@ +/** + * + */ +package at.gv.egiz.bku.conf; + +import org.slf4j.Logger; + +import iaik.logging.Log; +import iaik.logging.TransactionId; + +/** + * @author mcentner + * + */ +public class IAIKLogAdapter implements Log { + + /** + * The id that will be written to the log if the transactionid == null + */ + public final static String NO_ID = "Null-ID"; + + protected Logger log; + + protected String nodeId; + + public IAIKLogAdapter(Logger logger) { + this.log = logger; + } + + /* (non-Javadoc) + * @see iaik.logging.Log#debug(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void debug(TransactionId transactionId, Object message, Throwable t) { + if (log.isDebugEnabled()) { + log.debug(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#info(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void info(TransactionId transactionId, Object message, Throwable t) { + if (log.isInfoEnabled()) { + log.info(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#warn(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void warn(TransactionId transactionId, Object message, Throwable t) { + if (log.isWarnEnabled()) { + log.warn(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#error(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void error(TransactionId transactionId, Object message, Throwable t) { + if (log.isErrorEnabled()) { + log.error(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#fatal(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void fatal(TransactionId transactionId, Object message, Throwable t) { + if (log.isErrorEnabled()) { + log.error(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#setNodeId(java.lang.String) + */ + @Override + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + /* (non-Javadoc) + * @see iaik.logging.Log#getNodeId() + */ + @Override + public String getNodeId() { + return nodeId; + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isDebugEnabled() + */ + @Override + public boolean isDebugEnabled() { + return log.isDebugEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isInfoEnabled() + */ + @Override + public boolean isInfoEnabled() { + return log.isInfoEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isWarnEnabled() + */ + @Override + public boolean isWarnEnabled() { + return log.isWarnEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isErrorEnabled() + */ + @Override + public boolean isErrorEnabled() { + return log.isErrorEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isFatalEnabled() + */ + @Override + public boolean isFatalEnabled() { + return log.isErrorEnabled(); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java new file mode 100644 index 00000000..52c3d8d1 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapterFactory.java @@ -0,0 +1,62 @@ +/** + * + */ +package at.gv.egiz.bku.conf; + +import java.util.WeakHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import iaik.logging.Log; +import iaik.logging.LogConfigurationException; +import iaik.logging.LogFactory; + +/** + * @author mcentner + * + */ +public class IAIKLogAdapterFactory extends LogFactory { + + protected WeakHashMap instances = new WeakHashMap(); + + /* (non-Javadoc) + * @see iaik.logging.LogFactory#getInstance(java.lang.String) + */ + @Override + public synchronized Log getInstance(String name) throws LogConfigurationException { + Logger logger = LoggerFactory.getLogger(name); + Log log = instances.get(logger); + if (log == null) { + log = new IAIKLogAdapter(logger); + log.setNodeId(node_id_); + instances.put(logger, log); + } + return log; + } + + /* (non-Javadoc) + * @see iaik.logging.LogFactory#getInstance(java.lang.Class) + */ + @SuppressWarnings("unchecked") + @Override + public synchronized Log getInstance(Class clazz) throws LogConfigurationException { + Logger logger = LoggerFactory.getLogger(clazz); + Log log = instances.get(logger); + if (log == null) { + log = new IAIKLogAdapter(logger); + log.setNodeId(node_id_); + instances.put(logger, log); + } + return log; + } + + /* (non-Javadoc) + * @see iaik.logging.LogFactory#release() + */ + @Override + public void release() { + instances.clear(); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java new file mode 100644 index 00000000..52842167 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/MoccaConfigurationFacade.java @@ -0,0 +1,22 @@ +/* +* Copyright 2009 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.conf; + +public interface MoccaConfigurationFacade { + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java new file mode 100644 index 00000000..cb501b92 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentMXBean.java @@ -0,0 +1,27 @@ +/* +* Copyright 2009 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.jmx; + +import javax.management.MXBean; + +@MXBean +public interface ComponentMXBean { + + public ComponentState checkComponentState(); + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java new file mode 100644 index 00000000..9da8515f --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentState.java @@ -0,0 +1,38 @@ +/* +* Copyright 2009 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.jmx; + +import java.beans.ConstructorProperties; + +public class ComponentState { + + boolean ready; + + @ConstructorProperties({"ready"}) + public ComponentState(boolean ready) { + this.ready = ready; + } + + /** + * @return the ready + */ + public boolean isReady() { + return ready; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java new file mode 100644 index 00000000..562c2213 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/jmx/ComponentStateCheck.java @@ -0,0 +1,24 @@ +/* +* Copyright 2009 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.jmx; + +public interface ComponentStateCheck { + + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java new file mode 100644 index 00000000..951e09f4 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AbstractSLCommandFactory.java @@ -0,0 +1,46 @@ +/* +* Copyright 2009 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.slcommands; + +import javax.xml.bind.JAXBElement; + +import org.apache.commons.configuration.Configuration; + +import at.gv.egiz.bku.slexceptions.SLCommandException; + +public abstract class AbstractSLCommandFactory { + + protected Configuration configuration; + + public abstract SLCommand createSLCommand(JAXBElement object) throws SLCommandException; + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java index 2d87c39f..7db0098b 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java @@ -21,5 +21,5 @@ import at.gv.egiz.bku.slexceptions.SLRequestException; public interface CreateXMLSignatureCommand extends SLCommand { - public void prepareXMLSignature() throws SLCommandException, SLRequestException; + public void prepareXMLSignature(SLCommandContext commandContext) throws SLCommandException, SLRequestException; } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java index 4bc2820b..f27fd905 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java @@ -15,6 +15,11 @@ * limitations under the License. */ package at.gv.egiz.bku.slcommands; + +import org.w3c.dom.Element; -public interface CreateXMLSignatureResult extends SLResult { +public interface CreateXMLSignatureResult extends SLResult { + + public Element getContent(); + } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java index 5d52c0ea..5663627e 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java @@ -15,6 +15,12 @@ * limitations under the License. */ package at.gv.egiz.bku.slcommands; + -public interface ErrorResult extends SLResult { +public interface ErrorResult extends SLResult { + + public int getErrorCode(); + + public String getInfo(); + } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java index c6a51362..599f1ae0 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java @@ -16,5 +16,8 @@ */ package at.gv.egiz.bku.slcommands; -public interface InfoboxReadResult extends SLResult { +public interface InfoboxReadResult extends SLResult { + + public Object getContent(); + } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java index a8625946..d24c86ef 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java @@ -20,12 +20,16 @@ import at.gv.egiz.bku.slexceptions.SLCommandException; public interface SLCommand { - public final String NAMESPACE_URI = "http://www.buergerkarte.at/namespaces/securitylayer/1.2#"; + public final String NAMESPACE_URI = "http://www.buergerkarte.at/namespaces/securitylayer/1.2#"; + + public final String NAMESPACE_URI_20020225 = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#"; + + public final String NAMESPACE_URI_20020831 = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#"; public String getName(); - public void init(SLCommandContext aCtx, Object aUnmarshalledRequest) throws SLCommandException; + public void init(Object aUnmarshalledRequest) throws SLCommandException; - public SLResult execute(); + public SLResult execute(SLCommandContext commandContext); } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java index 5af2afac..f0e46d0c 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java @@ -18,30 +18,43 @@ package at.gv.egiz.bku.slcommands; import java.util.Locale; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; import at.gv.egiz.stal.STAL; public class SLCommandContext { - private STAL stal; - private URLDereferencerContext urlDerefCtx; + private STAL stal; + + private URLDereferencer urlDereferencer; - private Locale locale; - + private Locale locale; + + public SLCommandContext(STAL stal, URLDereferencer urlDereferencer) { + this.stal = stal; + this.urlDereferencer = urlDereferencer; + } + + public SLCommandContext(STAL stal, URLDereferencer urlDereferencer, + Locale locale) { + this.stal = stal; + this.urlDereferencer = urlDereferencer; + this.locale = locale; + } + public void setSTAL(STAL aStal) { this.stal = aStal; } - public void setURLDereferencerContext(URLDereferencerContext aCtx) { - this.urlDerefCtx = aCtx; + public void setURLDereferencer(URLDereferencer urlDereferencer) { + this.urlDereferencer = urlDereferencer; } public STAL getSTAL() { return stal; } - public URLDereferencerContext getURLDereferencerContext() { - return urlDerefCtx; + public URLDereferencer getURLDereferencer() { + return urlDereferencer; } public Locale getLocale() { diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java index ab2f08cc..0314869e 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java @@ -16,390 +16,211 @@ */ package at.gv.egiz.bku.slcommands; -import java.io.IOException; -import java.net.URL; import java.util.HashMap; import java.util.Map; -import javax.xml.XMLConstants; -import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.UnmarshalException; import javax.xml.bind.Unmarshaller; -import javax.xml.bind.ValidationEvent; -import javax.xml.bind.ValidationEventLocator; import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.xml.sax.SAXException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.xml.sax.SAXParseException; + import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLExceptionMessages; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; import at.gv.egiz.bku.slexceptions.SLVersionException; import at.gv.egiz.bku.utils.DebugReader; -import at.gv.egiz.slbinding.RedirectEventFilter; -import at.gv.egiz.slbinding.RedirectUnmarshallerListener; -import at.gv.egiz.validation.ReportingValidationEventHandler; - -public class SLCommandFactory { - - /** - * Schema files required for Security Layer command validation. - */ - public static final String[] SCHEMA_FILES = new String[]{ - "at/gv/egiz/bku/slcommands/schema/xml.xsd", - "at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd", - "at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd", - "at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd", - "at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd" - }; - /** - * Logging facility. - */ - static Log log = LogFactory.getLog(SLCommandFactory.class); - /** - * The instance returned by {@link #getInstance()}. - */ - private static SLCommandFactory instance; - /** - * Schema for Security Layer command validation. - */ - private Schema slSchema; - /** - * The JAXBContext. - */ - private JAXBContext jaxbContext; - /** - * The map of : to implementation class of the - * corresponding {@link SLCommand}. - */ - private Map> slRequestTypeMap = new HashMap>(); - - /** - * Configures the singleton instance with command implementations - * @param commandImplMap - * @throws ClassNotFoundException - */ - @SuppressWarnings("unchecked") - public void setCommandImpl(Map commandImplMap) throws ClassNotFoundException { - ClassLoader cl = getClass().getClassLoader(); - for (String key : commandImplMap.keySet()) { - Class impl = (Class) cl.loadClass(commandImplMap.get(key)); - log.debug("Registering sl command implementation for :"+key+ "; implementation class: "+impl.getCanonicalName()); - slRequestTypeMap.put(key, impl); +import at.gv.egiz.slbinding.SLUnmarshaller; + +public class SLCommandFactory extends SLUnmarshaller { + + private final Logger log = LoggerFactory.getLogger(SLCommandFactory.class); + + private static class SLCommandFactoryInstance { + private static final SLCommandFactory INSTANCE = new SLCommandFactory(); + } + + /** + * The mapping of a requests's qualified name to a concrete command factories. + */ + private Map slCommandFactories = new HashMap(); + + public void setConcreteFactories( + Map factories) { + if (log.isDebugEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("Registered sl command factory for"); + for (QName qname : factories.keySet()) { + sb.append("\n " + qname + " : " + factories.get(qname).getClass()); } + log.debug(sb.toString()); } - - /** - * Register an {@link SLCommand} implementation class of a Security Layer - * command with the given namespaceUri and localname - * . - * - * @param namespaceUri - * the namespace URI of the Security Layer command - * @param localname - * the localname of the Security Layer command - * @param slCommandClass - * the implementation class, or null to deregister a - * currently registered class - */ - public void setImplClass(String namespaceUri, String localname, - Class slCommandClass) { - if (slCommandClass != null) { - slRequestTypeMap.put(namespaceUri + ":" + localname, slCommandClass); - } else { - slRequestTypeMap.remove(namespaceUri + ":" + localname); - } - } - - /** - * Returns the implementation class of an {@link SLCommand} with the given - * name, or null if no such class is registered. - * - * @param name - * the QName of the Security Layer command - * @return the implementation class, or null if no class is - * registered for the given name - */ - public Class getImplClass(QName name) { - String namespaceURI = name.getNamespaceURI(); - String localPart = name.getLocalPart(); - return slRequestTypeMap.get(namespaceURI + ":" + localPart); - } - - /** - * Sets the schema to validate Security Layer commands with. - * - * @param slSchema the schema to validate Security Layer commands with - */ - public void setSLSchema(Schema slSchema) { - this.slSchema = slSchema; - } - - /** - * @return the jaxbContext - */ - public JAXBContext getJaxbContext() { - ensureJaxbContext(); - return jaxbContext; + slCommandFactories = factories; + } + + /** + * Get an instance of the SLCommandFactory. + */ + public synchronized static SLCommandFactory getInstance() { + return SLCommandFactoryInstance.INSTANCE; + } + + /** + * Private constructor used by {@link #getInstance()}. + */ + private SLCommandFactory() { + super(); + } + + /** + * Creates a new SLCommand from the given source and + * context. + * + * @param source + * the Source to unmarshall from + * @return the SLCommand unmarshalled from the given + * source + * @throws SLRequestException + * if unmarshalling fails + * @throws SLCommandException + * if command ist not supported + * @throws SLRuntimeException + * if an unexpected error occurs configuring the unmarshaller, if + * unmarshalling fails with an unexpected error or if the + * corresponding SLCommand could not be instantiated + * @throws SLVersionException + */ + public SLCommand createSLCommand(Source source) + throws SLCommandException, SLRuntimeException, SLRequestException, + SLVersionException { + + DebugReader dr = null; + if (log.isTraceEnabled() && source instanceof StreamSource) { + StreamSource streamSource = (StreamSource) source; + if (streamSource.getReader() != null) { + dr = new DebugReader(streamSource.getReader(), + "SLCommand unmarshalled from:\n"); + streamSource.setReader(dr); + } } - /** - * @param jaxbContext the jaxbContext to set - */ - public void setJaxbContext(JAXBContext jaxbContext) { - this.jaxbContext = jaxbContext; + Object object; + try { + object = unmarshalRequest(source); + } catch (SLRequestException e) { + throw e; + } finally { + if (dr != null) { + log.trace(dr.getCachedString()); + } } - /** - * Initialize the JAXBContext. - */ - private synchronized void ensureJaxbContext() { - if (jaxbContext == null) { - try { - // add top-level types explicitly to jaxb context, otherwise the unmarshaller won't find them. - // cf. http://forums.java.net/jive/thread.jspa?threadID=75778&tstart=0 - String slImplPkg = at.gv.egiz.slbinding.impl.CreateXMLSignatureResponseType.class.getPackage().getName(); - - String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName(); - String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName(); - String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName(); - String slPkgLegacy1_0 = at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory.class.getPackage().getName(); - String slPkgLegacy1_1 = at.buergerkarte.namespaces.securitylayer._20020831_.ObjectFactory.class.getPackage().getName(); - String contextPath = slImplPkg + ":" + slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg - + ":" + slPkgLegacy1_0 + ":" + slPkgLegacy1_1; - log.debug("jaxb context path: " + contextPath); - setJaxbContext(JAXBContext.newInstance(contextPath)); - } catch (JAXBException e) { - log.error("Failed to setup JAXBContext security layer request.", e); - throw new SLRuntimeException(e); - } - } + if (!(object instanceof JAXBElement)) { + // invalid request + log.info("Invalid security layer request.\n{}", object.toString()); + throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID, + new Object[] { object.toString() }); } - /** - * Initialize the security layer schema. - */ - private synchronized void ensureSchema() { - if (slSchema == null) { - try { - SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - ClassLoader cl = SLCommandFactory.class.getClassLoader(); - Source[] sources = new Source[SCHEMA_FILES.length]; - for (int i = 0; i < SCHEMA_FILES.length; i++) { - String schemaFile = SCHEMA_FILES[i]; - URL schemaURL = cl.getResource(schemaFile); - if (schemaURL == null) { - throw new SLRuntimeException("Failed to load schema file " + schemaFile + "."); - } - log.debug("Schema location: " + schemaURL); - sources[i] = new StreamSource(schemaURL.openStream()); - } - Schema schema = schemaFactory.newSchema(sources); - log.debug("Schema successfully created."); - setSLSchema(schema); - } catch (SAXException e) { - log.error("Failed to load security layer schema.", e); - throw new SLRuntimeException("Failed to load security layer schema.", e); - } catch (IOException e) { - log.error("Failed to load security layer schema.", e); - throw new SLRuntimeException("Failed to load security layer schema.", e); - } - - } - } - - /** - * Get an instance of the SLCommandFactory. - */ - public synchronized static SLCommandFactory getInstance() { - if (instance == null) { - instance = new SLCommandFactory(); - instance.ensureJaxbContext(); - instance.ensureSchema(); - } - return instance; + return createSLCommand((JAXBElement) object); + + } + + /** + * Creates a new SLCommand from the given element + * and context. + * + * @param element + * the request element + * @return the SLCommand for for the given element + * @throws SLCommandException + * if command ist not supported + * @throws SLVersionException + */ + public SLCommand createSLCommand(JAXBElement element) throws SLCommandException, SLVersionException { + + QName qName = element.getName(); + if (SLCommand.NAMESPACE_URI_20020831.equals(qName.getNamespaceURI()) + || SLCommand.NAMESPACE_URI_20020225.equals(qName.getNamespaceURI())) { + // security layer request version not supported + log.info("Unsupported security layer request version {}.", qName.getNamespaceURI()); + throw new SLVersionException(qName.getNamespaceURI()); } - /** - * Private constructor used by {@link #getInstance()}. - */ - private SLCommandFactory() { + AbstractSLCommandFactory concreteFactory = slCommandFactories.get(qName); + if (concreteFactory == null) { + // command not supported + log.info("Unsupported command received {}.", qName.toString()); + throw new SLCommandException(4011, + SLExceptionMessages.EC4011_NOTIMPLEMENTED, new Object[] { qName + .toString() }); } - /** - * Unmarshalls from the given source. - * - * @see Unmarshaller#unmarshal(Source) - * - * Note:Could replace JAXB's unmarshal-time validation engine (see commented code), however, - * we need a redirect filter. - * - * @param source - * the source to unmarshal from - * @return the object returned by {@link Unmarshaller#unmarshal(Source)} - * @throws SLRequestException - * if unmarshalling fails - * @throws SLRuntimeException - * if an unexpected error occurs configuring the unmarshaller or if - * unmarshalling fails with an unexpected error - */ - protected Object unmarshal(Source source) throws SLRuntimeException, + return concreteFactory.createSLCommand(element); + + } + + /** + * Unmarshalls from the given source. + * + * @see Unmarshaller#unmarshal(Source) + * + * Note:Could replace JAXB's unmarshal-time validation engine + * (see commented code), however, we need a redirect filter. + * + * @param source + * the source to unmarshal from + * @return the object returned by {@link Unmarshaller#unmarshal(Source)} + * @throws SLRequestException + * if unmarshalling fails + * @throws SLRuntimeException + * if an unexpected error occurs configuring the unmarshaller or if + * unmarshalling fails with an unexpected error + */ + protected Object unmarshalRequest(Source source) throws SLRuntimeException, SLRequestException { - Object object; - ReportingValidationEventHandler validationEventHandler = new ReportingValidationEventHandler(); - try { - - XMLInputFactory inputFactory = XMLInputFactory.newInstance(); - XMLEventReader eventReader = inputFactory.createXMLEventReader(source); - RedirectEventFilter redirectEventFilter = new RedirectEventFilter(); - XMLEventReader filteredReader = inputFactory.createFilteredReader(eventReader, redirectEventFilter); - - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - unmarshaller.setListener(new RedirectUnmarshallerListener(redirectEventFilter)); - if (slSchema != null) { - unmarshaller.setSchema(slSchema); - } - log.trace("Before unmarshal()."); - unmarshaller.setEventHandler(validationEventHandler); - object = unmarshaller.unmarshal(filteredReader); - log.trace("After unmarshal()."); - } catch (UnmarshalException e) { - if (log.isDebugEnabled()) { - log.debug("Failed to unmarshall security layer request.", e); - } else { - log.info("Failed to unmarshall security layer request." + e.getMessage()); - } - if (validationEventHandler.getErrorEvent() != null) { - // Validation Error - ValidationEvent errorEvent = validationEventHandler.getErrorEvent(); - ValidationEventLocator locator = errorEvent.getLocator(); - throw new SLRequestException(3002, - SLExceptionMessages.EC3002_INVALID, new Object[]{errorEvent.getMessage()}); - } - Throwable cause = e.getCause(); - if (cause instanceof SAXParseException) { - throw new SLRequestException(3000, - SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[]{cause.getMessage()}); - } else { - throw new SLRequestException(3000, - SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[]{e}); - } - } catch (JAXBException e) { - // unexpected error - log.error("Failed to unmarshall security layer request.", e); - throw new SLRuntimeException(e); - } catch (XMLStreamException e) { - // unexpected error - log.error("Failed to unmarshall security layer request.", e); - throw new SLRuntimeException(e); - } - - return object; + try { + return unmarshal(source); + } catch (UnmarshalException e) { + if (log.isDebugEnabled()) { + log.debug("Failed to unmarshall security layer request.", e); + } else { + log.info("Failed to unmarshall security layer request." + + e.getMessage()); + } + if (e.getLinkedException() != null) { + throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID, + new Object[] { e.getMessage() }); + } + Throwable cause = e.getCause(); + if (cause instanceof SAXParseException) { + throw new SLRequestException(3000, + SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[] { cause + .getMessage() }); + } else { + throw new SLRequestException(3000, + SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[] { e }); + } + } catch (JAXBException e) { + // unexpected error + log.error("Failed to unmarshall security layer request.", e); + throw new SLRuntimeException(e); + } catch (XMLStreamException e) { + // unexpected error + log.error("Failed to unmarshall security layer request.", e); + throw new SLRuntimeException(e); } - /** - * Creates a new SLCommand from the given source and - * context. - * - * @param source - * the Source to unmarshall from - * @param context - * the context for the created SLCommand - * @return the SLCommand unmarshalled from the given - * source - * @throws SLRequestException - * if unmarshalling fails - * @throws SLCommandException - * if command ist not supported - * @throws SLRuntimeException - * if an unexpected error occurs configuring the unmarshaller, if - * unmarshalling fails with an unexpected error or if the - * corresponding SLCommand could not be instantiated - * @throws SLVersionException - */ - @SuppressWarnings("unchecked") - public SLCommand createSLCommand(Source source, SLCommandContext context) - throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { - - DebugReader dr = null; - if (log.isTraceEnabled() && source instanceof StreamSource) { - StreamSource streamSource = (StreamSource) source; - if (streamSource.getReader() != null) { - dr = new DebugReader(streamSource.getReader(), "SLCommand unmarshalled from:\n"); - streamSource.setReader(dr); - } - } - - Object object; - try { - object = unmarshal(source); - } catch (SLRequestException e) { - throw e; - } finally { - if (dr != null) { - log.trace(dr.getCachedString()); - } - } - - if (!(object instanceof JAXBElement)) { - // invalid request - log.info("Invalid security layer request. " + object.toString()); - throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID, - new Object[]{object.toString()}); - } - - QName qName = ((JAXBElement) object).getName(); - if (!SLCommand.NAMESPACE_URI.equals(qName.getNamespaceURI())) { - // security layer request version not supported - log.info("Unsupported security layer request version : " + qName.getNamespaceURI()); - throw new SLVersionException(qName.getNamespaceURI()); - } - - Class implClass = getImplClass(qName); - if (implClass == null) { - // command not supported - log.info("Unsupported command received: " + qName.toString()); - throw new SLCommandException(4011, - SLExceptionMessages.EC4011_NOTIMPLEMENTED, new Object[]{qName.toString()}); - } - - - - // try to instantiate - SLCommand slCommand; - try { - slCommand = implClass.newInstance(); - log.debug("SLCommand " + slCommand.getClass().toString() + " created."); - } catch (InstantiationException e) { - // unexpected error - log.error("Failed to instantiate security layer command implementation.", - e); - throw new SLRuntimeException(e); - } catch (IllegalAccessException e) { - // unexpected error - log.error("Failed to instantiate security layer command implementation.", - e); - throw new SLRuntimeException(e); - } - - slCommand.init(context, (JAXBElement) object); - - return slCommand; - - } + } } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java index c28288c9..30be7673 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java @@ -36,7 +36,7 @@ public interface SLCommandInvoker { */ public SLResult getResult(SLTargetContext aContext) throws SLException; - public void setCommand(at.gv.egiz.bku.slcommands.SLCommand aCmd); + public void setCommand(SLCommandContext commandContext, at.gv.egiz.bku.slcommands.SLCommand aCmd); /** * Prototype creation diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java index e0a375cf..e3fb863c 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java @@ -20,15 +20,15 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.bku.slexceptions.SLRuntimeException; import at.gv.egiz.marshal.MarshallerFactory; public class SLMarshallerFactory { - static Log log = LogFactory.getLog(SLMarshallerFactory.class); + private final Logger log = LoggerFactory.getLogger(SLMarshallerFactory.class); /** * The JAXBContext used for result marshaling. @@ -98,6 +98,7 @@ public class SLMarshallerFactory { String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName(); legacyContext = JAXBContext.newInstance(slPkgLegacy1_0 + ":" + slPkgLegacy1_1 + ":" + xmldsigPkg + ":" + cardChannelPkg); } catch (JAXBException e) { + Logger log = LoggerFactory.getLogger(SLMarshallerFactory.class); log.error("Failed to setup JAXBContext security layer request.", e); throw new SLRuntimeException(e); } @@ -131,7 +132,7 @@ public class SLMarshallerFactory { try { return MarshallerFactory.createMarshaller(context, formattedOutput, fragment); } catch (JAXBException e) { - log.fatal("Failed to marshall error response.", e); + log.error("Failed to marshall error response.", e); throw new SLRuntimeException("Failed to marshall error response.", e); } } @@ -164,7 +165,7 @@ public class SLMarshallerFactory { ensureLegacyContext(); return MarshallerFactory.createMarshaller(legacyContext, formattedOutput, fragment); } catch (JAXBException e) { - log.fatal("Failed to marshall error response.", e); + log.error("Failed to marshall error response.", e); throw new SLRuntimeException("Failed to marshall error response.", e); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java index f25a0ea4..8a8a819a 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java @@ -19,9 +19,6 @@ package at.gv.egiz.bku.slcommands; import java.net.URL; import java.security.cert.X509Certificate; -import at.gv.egiz.bku.utils.binding.Protocol; - - public class SLSourceContext { private URL sourceUrl; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java index 9a4536e6..4da9abb7 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java @@ -26,8 +26,8 @@ import java.util.regex.Pattern; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.buergerkarte.namespaces.securitylayer._1.InfoboxAssocArrayPairType; import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadDataAssocArrayType; @@ -54,7 +54,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl /** * Logging facility. */ - private static Log log = LogFactory.getLog(AbstractAssocArrayInfobox.class); + private final Logger log = LoggerFactory.getLogger(AbstractAssocArrayInfobox.class); /** * The search string pattern. @@ -113,7 +113,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl // TODO : build pattern return Collections.emptyList(); } else { - log.info("Got invalid search string '" + searchString + "'"); + log.info("Got invalid search string '{}'.", searchString); throw new SLCommandException(4010); } @@ -170,14 +170,14 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl protected InfoboxReadResult readPairs(ReadPairs readPairs, SLCommandContext cmdCtx) throws SLCommandException { if (readPairs.isValuesAreXMLEntities() && !isValuesAreXMLEntities()) { - log.info("Got valuesAreXMLEntities=" + readPairs.isValuesAreXMLEntities() + " but infobox type is binary."); + log.info("Got valuesAreXMLEntities={} but infobox type is binary.", readPairs.isValuesAreXMLEntities()); throw new SLCommandException(4010); } List selectedKeys = selectKeys(readPairs.getSearchString()); if (readPairs.isUserMakesUnique() && selectedKeys.size() > 1) { - log.info("UserMakesUnique not supported"); + log.info("UserMakesUnique not supported."); // TODO: give more specific error message throw new SLCommandException(4010); } @@ -202,7 +202,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl protected InfoboxReadResult readValue(ReadValue readValue, SLCommandContext cmdCtx) throws SLCommandException { if (readValue.isValueIsXMLEntity() && !isValuesAreXMLEntities()) { - log.info("Got valuesAreXMLEntities=" + readValue.isValueIsXMLEntity() + " but infobox type is binary."); + log.info("Got valuesAreXMLEntities={} but infobox type is binary.", readValue.isValueIsXMLEntity()); throw new SLCommandException(4010); } @@ -232,7 +232,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl Object value = values.get(key); if (areXMLEntities) { if (value instanceof byte[]) { - log.info("Got valuesAreXMLEntities=" + areXMLEntities + " but infobox type is binary."); + log.info("Got valuesAreXMLEntities={} but infobox type is binary.", areXMLEntities); throw new SLCommandException(4122); } else { XMLContentType contentType = objectFactory.createXMLContentType(); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java index 23394bd5..feead9e5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java @@ -16,8 +16,8 @@ */ package at.gv.egiz.bku.slcommands.impl; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsBinaryFileType; import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; @@ -32,7 +32,7 @@ public abstract class AbstractBinaryFileInfobox extends AbstractInfoboxImpl impl /** * Logging facility. */ - private static Log log = LogFactory.getLog(AbstractBinaryFileInfobox.class); + private final Logger log = LoggerFactory.getLogger(AbstractBinaryFileInfobox.class); /** * Is this infobox' content an XML entity? @@ -57,7 +57,7 @@ public abstract class AbstractBinaryFileInfobox extends AbstractInfoboxImpl impl InfoboxReadParamsBinaryFileType binaryFileParameters = request.getBinaryFileParameters(); if (binaryFileParameters != null) { isXMLEntity = binaryFileParameters.isContentIsXMLEntity(); - log.debug("Got ContentIsXMLEntity=" + isXMLEntity + "."); + log.debug("Got ContentIsXMLEntity={}.", isXMLEntity); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java new file mode 100644 index 00000000..547f7eda --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandFactory.java @@ -0,0 +1,40 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory; + +public abstract class AbstractInfoboxCommandFactory extends AbstractSLCommandFactory { + + protected InfoboxFactory infoboxFactory; + + /** + * @return the infoboxFactory + */ + public InfoboxFactory getInfoboxFactory() { + return infoboxFactory; + } + + /** + * @param infoboxFactory the infoboxFactory to set + */ + public void setInfoboxFactory(InfoboxFactory infoboxFactory) { + this.infoboxFactory = infoboxFactory; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java index 8a7edb71..8a54260f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java @@ -16,7 +16,6 @@ */ package at.gv.egiz.bku.slcommands.impl; -import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slexceptions.SLCommandException; /** @@ -32,15 +31,34 @@ public abstract class AbstractInfoboxCommandImpl extends SLCommandImpl { * The infobox implementation. */ protected Infobox infobox; + + /** + * The infobox factory. + */ + protected InfoboxFactory infoboxFactory; + + /** + * @return the infoboxFactory + */ + public InfoboxFactory getInfoboxFactory() { + return infoboxFactory; + } + + /** + * @param infoboxFactory the infoboxFactory to set + */ + public void setInfoboxFactory(InfoboxFactory infoboxFactory) { + this.infoboxFactory = infoboxFactory; + } @Override - public void init(SLCommandContext ctx, Object request) + public void init(Object request) throws SLCommandException { - super.init(ctx, request); + super.init(request); String infoboxIdentifier = getInfoboxIdentifier(getRequestValue()); - infobox = InfoboxFactory.getInstance().createInfobox(infoboxIdentifier); + infobox = infoboxFactory.createInfobox(infoboxIdentifier); } /** diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java new file mode 100644 index 00000000..410d0cf8 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxFactory.java @@ -0,0 +1,24 @@ +/* +* Copyright 2009 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.slcommands.impl; + +public abstract class AbstractInfoboxFactory { + + public abstract Infobox createInfobox(); + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java new file mode 100644 index 00000000..ec46f8ac --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxFactory.java @@ -0,0 +1,27 @@ +/* +* Copyright 2009 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.slcommands.impl; + +public class CardChannelInfoboxFactory extends AbstractInfoboxFactory { + + @Override + public Infobox createInfobox() { + return new CardChannelInfoboxImpl(); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java index 19b84ac7..a7851b1e 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java @@ -30,8 +30,8 @@ import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.buergerkarte.namespaces.cardchannel.ATRType; import at.buergerkarte.namespaces.cardchannel.CommandAPDUType; @@ -58,7 +58,7 @@ import at.gv.egiz.stal.ext.APDUScriptResponse.ResponseScriptElement; public class CardChannelInfoboxImpl extends AbstractBinaryFileInfobox { - private static Log log = LogFactory.getLog(CardChannelInfoboxImpl.class); + private final Logger log = LoggerFactory.getLogger(CardChannelInfoboxImpl.class); private static WeakHashMap> scriptResults = new WeakHashMap>(); @@ -149,7 +149,7 @@ public class CardChannelInfoboxImpl extends AbstractBinaryFileInfobox { } - log.info("Infobox identifier is '" + getIdentifier() + "' but XMLContent does not contain 'Script'."); + log.info("Infobox identifier is '{}' but XMLContent does not contain 'Script'.", getIdentifier()); throw new SLCommandException(4010); } @@ -217,9 +217,7 @@ public class CardChannelInfoboxImpl extends AbstractBinaryFileInfobox { ResponseAPDUType responseAPDUType = objectFactory.createResponseAPDUType(); responseAPDUType.setSequence(BigInteger.valueOf(response.getSequence())); -// if (response.getRc() != 0) { - responseAPDUType.setRc(BigInteger.valueOf(response.getRc())); -// } + responseAPDUType.setRc(BigInteger.valueOf(response.getRc())); responseAPDUType.setSw(response.getSw()); responseAPDUType.setValue(response.getApdu()); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java new file mode 100644 index 00000000..5474f249 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxFactory.java @@ -0,0 +1,27 @@ +/* +* Copyright 2009 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.slcommands.impl; + +public class CertificatesInfoboxFactory extends AbstractInfoboxFactory { + + @Override + public Infobox createInfobox() { + return new CertificatesInfoboxImpl(); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java index 0208f137..8a80e824 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java @@ -23,8 +23,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slexceptions.SLCommandException; @@ -42,7 +42,7 @@ public class CertificatesInfoboxImpl extends AbstractAssocArrayInfobox { /** * Logging facility. */ - private static Log log = LogFactory.getLog(CertificatesInfoboxImpl.class); + private final Logger log = LoggerFactory.getLogger(CertificatesInfoboxImpl.class); /** * The valid keys. diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java new file mode 100644 index 00000000..750c2838 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandFactory.java @@ -0,0 +1,65 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import javax.xml.bind.JAXBElement; + +import org.apache.commons.configuration.Configuration; + +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; +import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.impl.xsect.DataObject; +import at.gv.egiz.bku.slexceptions.SLCommandException; + +public class CreateXMLSignatureCommandFactory extends AbstractSLCommandFactory { + + private ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + private class ConfigurationFacade implements MoccaConfigurationFacade { + + public static final String VALIDATE_HASH_DATA_INPUTS = "ValidateHashDataInputs"; + + public boolean getValidateHashDataInputs() { + return configuration.getBoolean(VALIDATE_HASH_DATA_INPUTS, true); + } + + } + + @Override + public SLCommand createSLCommand(JAXBElement element) throws SLCommandException { + + CreateXMLSignatureCommandImpl command = new CreateXMLSignatureCommandImpl(); + command.init(element); + return command; + + } + + /* (non-Javadoc) + * @see at.gv.egiz.bku.slcommands.AbstractSLCommandFactory#setConfiguration(org.apache.commons.configuration.Configuration) + */ + @Override + public void setConfiguration(Configuration configuration) { + // static configuration + super.setConfiguration(configuration); + DataObject.enableHashDataInputValidation(configurationFacade.getValidateHashDataInputs()); + } + + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java index 01686641..d52027b2 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java @@ -26,8 +26,8 @@ import javax.xml.crypto.MarshalException; import javax.xml.crypto.URIReferenceException; import javax.xml.crypto.dsig.XMLSignatureException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSSerializer; @@ -62,8 +62,7 @@ public class CreateXMLSignatureCommandImpl extends /** * Logging facility. */ - protected static Log log = LogFactory - .getLog(CreateXMLSignatureCommandImpl.class); + private final Logger log = LoggerFactory.getLogger(CreateXMLSignatureCommandImpl.class); /** * The signing certificate. @@ -79,23 +78,22 @@ public class CreateXMLSignatureCommandImpl extends * The to-be signed signature. */ protected Signature signature; - - @Override - public void init(SLCommandContext ctx, Object unmarshalledRequest) - throws SLCommandException { - super.init(ctx, unmarshalledRequest); - } - + + /** + * Disable hash data input validation? + */ + protected boolean disableHashdataInputValidation; + @Override - public void prepareXMLSignature() throws SLCommandException, + public void prepareXMLSignature(SLCommandContext commandContext) throws SLCommandException, SLRequestException { CreateXMLSignatureRequestType request = getRequestValue(); - // TODO: make configurable? + // TODO: make configurable? IdValueFactory idValueFactory = new IdValueFactoryImpl(); - // TODO: make configurable? + // TODO: make configurable? AlgorithmMethodFactory algorithmMethodFactory; try { algorithmMethodFactory = new AlgorithmMethodFactoryImpl( @@ -105,21 +103,21 @@ public class CreateXMLSignatureCommandImpl extends throw new SLCommandException(4006); } - signature = new Signature(getCmdCtx().getURLDereferencerContext(), + signature = new Signature(commandContext.getURLDereferencer(), idValueFactory, algorithmMethodFactory); - // SigningTime + // SigningTime signature.setSigningTime(new Date()); - // SigningCertificate + // SigningCertificate signature.setSignerCeritifcate(signingCertificate); - // SignatureInfo + // SignatureInfo if (request.getSignatureInfo() != null) { signature.setSignatureInfo(request.getSignatureInfo()); } - // DataObjects + // DataObjects for (DataObjectInfoType dataObjectInfo : request.getDataObjectInfo()) { signature.addDataObject(dataObjectInfo); } @@ -130,11 +128,12 @@ public class CreateXMLSignatureCommandImpl extends /** * Gets the signing certificate from STAL. + * @param commandContext TODO * * @throws SLCommandException * if getting the singing certificate fails */ - private void getSigningCertificate() throws SLCommandException { + private void getSigningCertificate(SLCommandContext commandContext) throws SLCommandException { CreateXMLSignatureRequestType request = getRequestValue(); keyboxIdentifier = request.getKeyboxIdentifier(); @@ -142,6 +141,8 @@ public class CreateXMLSignatureCommandImpl extends InfoboxReadRequest stalRequest = new InfoboxReadRequest(); stalRequest.setInfoboxIdentifier(keyboxIdentifier); + STALHelper stalHelper = new STALHelper(commandContext.getSTAL()); + stalHelper.transmitSTALRequest(Collections.singletonList((STALRequest) stalRequest)); List certificates = stalHelper.getCertificatesFromResponses(); if (certificates == null || certificates.size() != 1) { @@ -154,15 +155,16 @@ public class CreateXMLSignatureCommandImpl extends /** * Signs the signature. + * @param commandContext TODO * * @throws SLCommandException * if signing the signature fails * @throws SLViewerException */ - private void signXMLSignature() throws SLCommandException, SLViewerException { + private void signXMLSignature(SLCommandContext commandContext) throws SLCommandException, SLViewerException { try { - signature.sign(getCmdCtx().getSTAL(), keyboxIdentifier); + signature.sign(commandContext.getSTAL(), keyboxIdentifier); } catch (MarshalException e) { log.error("Failed to marshall XMLSignature.", e); throw new SLCommandException(4000); @@ -181,33 +183,42 @@ public class CreateXMLSignatureCommandImpl extends } @Override - public SLResult execute() { + public SLResult execute(SLCommandContext commandContext) { try { // get certificate in order to select appropriate algorithms for hashing - // and signing - getSigningCertificate(); - - // prepare the XMLSignature for signing - prepareXMLSignature(); + // and signing + log.info("Requesting signing certificate."); + getSigningCertificate(commandContext); + if (log.isDebugEnabled()) { + log.debug("Got signing certificate. {}", signingCertificate); + } else { + log.info("Got signing certificate."); + } - // sign the XMLSignature - signXMLSignature(); + // prepare the XMLSignature for signing + log.info("Preparing XML signature."); + prepareXMLSignature(commandContext); - if (log.isTraceEnabled()) { + // sign the XMLSignature + log.info("Signing XML signature."); + signXMLSignature(commandContext); + if (log.isDebugEnabled()) { DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS(); LSSerializer serializer = domImplLS.createLSSerializer(); String debugString = serializer.writeToString(signature.getDocument()); - log.trace(debugString); + log.debug(debugString); + } else { + log.info("XML signature signed."); } return new CreateXMLSignatureResultImpl(signature.getDocument()); } catch (SLException e) { - return new ErrorResultImpl(e, cmdCtx.getLocale()); + return new ErrorResultImpl(e, commandContext.getLocale()); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java index 19df4334..51b54a37 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java @@ -22,8 +22,8 @@ import javax.xml.bind.Marshaller; import javax.xml.transform.Result; import javax.xml.transform.Templates; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; import org.w3c.dom.Element; @@ -31,6 +31,7 @@ import org.w3c.dom.Node; import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureResponseType; import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; +import at.gv.egiz.bku.slcommands.CreateXMLSignatureResult; import at.gv.egiz.bku.slcommands.SLMarshallerFactory; import at.gv.egiz.bku.slexceptions.SLRuntimeException; @@ -39,18 +40,23 @@ import at.gv.egiz.bku.slexceptions.SLRuntimeException; * * @author mcentner */ -public class CreateXMLSignatureResultImpl extends SLResultImpl { +public class CreateXMLSignatureResultImpl extends SLResultImpl implements CreateXMLSignatureResult { /** * Logging facility. */ - private static Log log = LogFactory.getLog(CreateXMLSignatureResultImpl.class); + private final Logger log = LoggerFactory.getLogger(CreateXMLSignatureResultImpl.class); /** * The document containing the XMLSignature. */ protected Document doc; + /** + * The content of the CreateXMLSignatureResponse. + */ + protected Element content; + /** * Creates a new instance of this CreateXMLSignatureResultImpl with the given * signature document. @@ -67,6 +73,7 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl { } this.doc = document; + this.content = document.getDocumentElement(); marshallCreateXMLSignatureResponse(); } @@ -78,7 +85,7 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl { ObjectFactory factory = new ObjectFactory(); - CreateXMLSignatureResponseType createCreateXMLSignatureResponseType = factory.createCreateXMLSignatureResponseType(); + at.gv.egiz.slbinding.impl.CreateXMLSignatureResponseType createCreateXMLSignatureResponseType = factory.createCreateXMLSignatureResponseType(); JAXBElement createCreateXMLSignatureResponse = factory.createCreateXMLSignatureResponse(createCreateXMLSignatureResponseType); DocumentFragment fragment = doc.createDocumentFragment(); @@ -87,14 +94,13 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl { try { marshaller.marshal(createCreateXMLSignatureResponse, fragment); } catch (JAXBException e) { - log.error("Failed to marshall 'CreateXMLSignatureResponse'", e); + log.error("Failed to marshall 'CreateXMLSignatureResponse'.", e); throw new SLRuntimeException(e); } Node child = fragment.getFirstChild(); if (child instanceof Element) { - Node node = doc.replaceChild(child, doc.getDocumentElement()); - child.appendChild(node); + child.appendChild(doc.replaceChild(child, content)); } } @@ -104,4 +110,9 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl { writeTo(doc, result, templates, fragment); } + @Override + public Element getContent() { + return content; + } + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java new file mode 100644 index 00000000..6d8537d6 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomCreateXMLSignatureResultImpl.java @@ -0,0 +1,47 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import at.gv.egiz.bku.slcommands.CreateXMLSignatureResult; + +public class DomCreateXMLSignatureResultImpl extends DomSLResult implements + CreateXMLSignatureResult { + + public DomCreateXMLSignatureResultImpl(Element resultElement) { + super(resultElement); + } + + @Override + public Element getContent() { + + NodeList children = resultElement.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + return (Element) child; + } + } + + return null; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java new file mode 100644 index 00000000..6bb52a00 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomErrorResultImpl.java @@ -0,0 +1,70 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import at.gv.egiz.bku.slcommands.ErrorResult; +import at.gv.egiz.bku.slcommands.SLCommand; + +public class DomErrorResultImpl extends DomSLResult implements + ErrorResult { + + public DomErrorResultImpl(Element resultElement) { + super(resultElement); + } + + @Override + public int getErrorCode() { + + NodeList childNodes = resultElement.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node n = childNodes.item(i); + if (n.getNodeType() == Node.ELEMENT_NODE + && SLCommand.NAMESPACE_URI.equals(n.getNamespaceURI()) + && "ErrorCode".equals(n.getLocalName())) { + try { + return Integer.parseInt(n.getTextContent()); + } catch (NumberFormatException e) { } + } + } + + return 0; + + } + + @Override + public String getInfo() { + + NodeList childNodes = resultElement.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node n = childNodes.item(i); + if (n.getNodeType() == Node.ELEMENT_NODE + && SLCommand.NAMESPACE_URI.equals(n.getNamespaceURI()) + && "Info".equals(n.getLocalName())) { + return n.getTextContent(); + } + } + + return null; + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java new file mode 100644 index 00000000..ce69c852 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomInfoboxReadResultImpl.java @@ -0,0 +1,105 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import iaik.utils.Base64InputStream; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import at.gv.egiz.bku.slcommands.InfoboxReadResult; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.utils.StreamUtil; + +public class DomInfoboxReadResultImpl extends DomSLResult implements + InfoboxReadResult { + + public DomInfoboxReadResultImpl(Element resultElement) { + super(resultElement); + } + + private List getXMLContent(Node node) { + ArrayList content = new ArrayList(); + NodeList xmlContent = node.getChildNodes(); + for (int i = 0; i < xmlContent.getLength(); i++) { + content.add(xmlContent.item(i)); + } + return content; + } + + private byte[] getBase64Content(Node node) { + String content = node.getTextContent(); + if (content != null) { + try { + byte[] bytes = content.getBytes("ASCII"); + Base64InputStream bis = new Base64InputStream(new ByteArrayInputStream(bytes)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + StreamUtil.copyStream(bis, bos); + return bos.toByteArray(); + } catch (UnsupportedEncodingException e) { + throw new SLRuntimeException(e); + } catch (IOException e) { + throw new SLRuntimeException(e); + } + } else { + return new byte[] {}; + } + } + + private Object getBinaryFileDataContent(Node node) { + NodeList childNodes = node.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node n = childNodes.item(i); + if (n.getNodeType() == Node.ELEMENT_NODE && SLCommand.NAMESPACE_URI.equals(n.getNamespaceURI())) { + if ("XMLContent".equals(n.getLocalName())) { + return getXMLContent(n); + } else if ("Base64Content".equals(n.getLocalName())) { + return getBase64Content(n); + } + } + } + return Collections.EMPTY_LIST; + } + + @Override + public Object getContent() { + + NodeList childNodes = resultElement.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node node = childNodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE + && SLCommand.NAMESPACE_URI.equals(node.getNamespaceURI()) + && "BinaryFileData".equals(node.getLocalName())) { + return getBinaryFileDataContent(node); + } + } + return Collections.EMPTY_LIST; + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java new file mode 100644 index 00000000..ad81b388 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DomSLResult.java @@ -0,0 +1,41 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import javax.xml.transform.Result; +import javax.xml.transform.Templates; + +import org.w3c.dom.Element; + + +public abstract class DomSLResult extends SLResultImpl { + + protected Element resultElement; + + public DomSLResult(Element resultElement) { + this.resultElement= resultElement; + } + + @Override + public void writeTo(Result result, Templates templates, boolean fragment) { + writeTo(resultElement.getOwnerDocument(), result, templates, fragment); + } + + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java index aedde238..4eb01490 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java @@ -63,5 +63,23 @@ public class ErrorResultImpl extends SLResultImpl implements ErrorResult { writeErrorTo(slException, result, templates, locale, fragment); } } + + @Override + public int getErrorCode() { + if (slException != null) { + return slException.getErrorCode(); + } else { + return -1; + } + } + + @Override + public String getInfo() { + if (slException != null) { + return slException.getLocalizedMessage(locale); + } else { + return null; + } + } } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java new file mode 100644 index 00000000..2a29b8da --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandFactory.java @@ -0,0 +1,37 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import javax.xml.bind.JAXBElement; + +import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLCommandException; + +public class GetStatusCommandFactory extends AbstractSLCommandFactory { + + @Override + public SLCommand createSLCommand(JAXBElement element) throws SLCommandException { + + GetStatusCommandImpl command = new GetStatusCommandImpl(); + command.init(element); + return command; + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java index 0c2b96f9..d58141a1 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java @@ -19,6 +19,7 @@ package at.gv.egiz.bku.slcommands.impl; import at.buergerkarte.namespaces.securitylayer._1.GetStatusRequestType; import at.gv.egiz.bku.slcommands.GetStatusCommand; +import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.stal.ErrorResponse; @@ -28,8 +29,8 @@ import at.gv.egiz.stal.StatusRequest; import at.gv.egiz.stal.StatusResponse; import java.util.Collections; import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -37,7 +38,7 @@ import org.apache.commons.logging.LogFactory; */ public class GetStatusCommandImpl extends SLCommandImpl implements GetStatusCommand { - protected static Log log = LogFactory.getLog(GetStatusCommandImpl.class); + protected final Logger log = LoggerFactory.getLogger(GetStatusCommandImpl.class); @Override public String getName() { @@ -45,16 +46,15 @@ public class GetStatusCommandImpl extends SLCommandImpl im } @Override - public SLResult execute() { + public SLResult execute(SLCommandContext commandContext) { //ignore maxDelay and TokenStatus -// GetStatusRequestType req = getRequestValue(); - log.debug("execute GetStatusRequest"); + log.debug("Execute GetStatusRequest."); StatusRequest stalRequest = new StatusRequest(); - STAL stal = cmdCtx.getSTAL(); + STAL stal = commandContext.getSTAL(); List responses = stal.handleRequest(Collections.singletonList(stalRequest)); @@ -62,16 +62,16 @@ public class GetStatusCommandImpl extends SLCommandImpl im STALResponse stalResponse = responses.get(0); if (stalResponse instanceof StatusResponse) { boolean ready = ((StatusResponse) stalResponse).isCardReady(); - log.trace("received status response cardReady: " + ready); + log.trace("Received status response cardReady: {}.", ready); return new GetStatusResultImpl(ready); } else if (stalResponse instanceof ErrorResponse) { - log.debug("received error response"); + log.debug("Received error response."); SLCommandException ex = new SLCommandException(((ErrorResponse) stalResponse).getErrorCode()); - return new ErrorResultImpl(ex, cmdCtx.getLocale()); + return new ErrorResultImpl(ex, commandContext.getLocale()); } } - log.error("received unexpected responses"); - return new ErrorResultImpl(new SLCommandException(4000), cmdCtx.getLocale()); + log.error("Received unexpected responses."); + return new ErrorResultImpl(new SLCommandException(4000), commandContext.getLocale()); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java new file mode 100644 index 00000000..c19f52ac --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxFactory.java @@ -0,0 +1,48 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import at.gv.egiz.idlink.IdentityLinkTransformer; + +public class IdentityLinkInfoboxFactory extends AbstractInfoboxFactory { + + private IdentityLinkTransformer identityLinkTransformer; + + @Override + public Infobox createInfobox() { + IdentityLinkInfoboxImpl infoboxImpl = new IdentityLinkInfoboxImpl(); + infoboxImpl.setIdentityLinkTransformer(identityLinkTransformer); + return infoboxImpl; + } + + /** + * @return the identityLinkTransformer + */ + public IdentityLinkTransformer getIdentityLinkTransformer() { + return identityLinkTransformer; + } + + /** + * @param identityLinkTransformer the identityLinkTransformer to set + */ + public void setIdentityLinkTransformer( + IdentityLinkTransformer identityLinkTransformer) { + this.identityLinkTransformer = identityLinkTransformer; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java index 160e9589..ec873e20 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java @@ -37,8 +37,8 @@ import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; @@ -68,13 +68,30 @@ public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox { /** * Logging facility. */ - private static Log log = LogFactory.getLog(IdentityLinkInfoboxImpl.class); + private final Logger log = LoggerFactory.getLogger(IdentityLinkInfoboxImpl.class); /** * The box specific parameter IdentityLinkDomainIdentifier. */ public static final String BOX_SPECIFIC_PARAMETER_IDENTITY_LINK_DOMAIN_IDENTIFIER = "IdentityLinkDomainIdentifier"; + private IdentityLinkTransformer identityLinkTransformer; + + /** + * @return the identityLinkTransformer + */ + public IdentityLinkTransformer getIdentityLinkTransformer() { + return identityLinkTransformer; + } + + /** + * @param identityLinkTransformer the identityLinkTransformer to set + */ + public void setIdentityLinkTransformer( + IdentityLinkTransformer identityLinkTransformer) { + this.identityLinkTransformer = identityLinkTransformer; + } + /** * The value of the box specific parameter IdentityLinkDomainIdentifier. */ @@ -147,7 +164,6 @@ public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox { JAXBElement compressedIdentityLink = idLinkFactory .createCompressedIdentityLink(identityLink, certificates, getDomainIdentifier()); - IdentityLinkTransformer identityLinkTransformer = IdentityLinkTransformer.getInstance(); String issuerTemplate = identityLink.getIssuerTemplate(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); @@ -262,12 +278,12 @@ public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox { Transformer transformer = transformerFactory.newTransformer(); transformer.transform(xmlSource, new StreamResult(resultBytes)); } catch (TransformerConfigurationException e) { - log.error(e); + log.error("Failed to transform identity link.", e); throw new SLCommandException(4000, SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, new Object[] { issuerTemplate }); } catch (TransformerException e) { - log.error(e); + log.error("Failed to transform identity link.", e); throw new SLCommandException(4000, SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, new Object[] { issuerTemplate }); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java index e9736f6d..5ba06ac4 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java @@ -17,10 +17,9 @@ package at.gv.egiz.bku.slcommands.impl; import java.util.HashMap; -import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLExceptionMessages; @@ -36,71 +35,27 @@ public class InfoboxFactory { /** * Logging facility. */ - private static Log log = LogFactory.getLog(InfoboxFactory.class); + private final Logger log = LoggerFactory.getLogger(InfoboxFactory.class); /** - * The singleton instance of this InfoboxFactory. + * The mapping of Infobox name to concrete Infobox factory. */ - private static InfoboxFactory instance; - - /** - * @return an instance of this InfoboxFactory - */ - public synchronized static InfoboxFactory getInstance() { - if (instance == null) { - instance = new InfoboxFactory(); - } - return instance; - } - - /** - * The mapping of infobox identifier to implementation class. - */ - private HashMap> implementations; - - /** - * Private constructor. - */ - private InfoboxFactory() { - } - - /** - * Sets the mapping of infobox identifier to implementation class name. - * - * @param infoboxImplMap - * a mapping of infobox identifiers to implementation class names - * - * @throws ClassNotFoundException - * if implementation class is not an instance of {@link Infobox} - */ - @SuppressWarnings("unchecked") - public void setInfoboxImpl(Map infoboxImplMap) throws ClassNotFoundException { - HashMap> implMap = new HashMap>(); - ClassLoader cl = getClass().getClassLoader(); - for (String key : infoboxImplMap.keySet()) { - Class impl = (Class) cl.loadClass(infoboxImplMap.get(key)); - log.debug("Registering infobox '" + key + "' implementation '" + impl.getCanonicalName() + "'."); - implMap.put(key, impl); - } - implementations = implMap; - } - + private HashMap infoboxFactories = new HashMap(); + /** - * Returns the configured implementation class for the given - * infoboxIdentifier. - * - * @param infoboxIdentifier - * the infobox identifier - * - * @return the implementation class for the given infobox identifier or - * null if there is no implementation class configured + * @param infoboxFactories the infoboxFactories to set */ - public Class getImplClass(String infoboxIdentifier) { - if (implementations != null) { - return implementations.get(infoboxIdentifier); - } else { - return null; + public void setInfoboxFactories( + HashMap factories) { + if (log.isDebugEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("Registered infobox factories for"); + for (String name : factories.keySet()) { + sb.append("\n " + name + " : " + factories.get(name).getClass()); + } + log.debug(sb.toString()); } + this.infoboxFactories = factories; } /** @@ -119,31 +74,15 @@ public class InfoboxFactory { */ public Infobox createInfobox(String infoboxIdentifier) throws SLCommandException, SLRuntimeException { - Class implClass = getImplClass(infoboxIdentifier); - if (implClass == null) { - // infobox not supported - log.info("Unsupported infobox '" + infoboxIdentifier + "."); + AbstractInfoboxFactory factory = infoboxFactories.get(infoboxIdentifier); + if (factory == null) { + log.info("Unsupported infobox '{}'.", infoboxIdentifier); throw new SLCommandException(4002, SLExceptionMessages.EC4002_INFOBOX_UNKNOWN, new Object[] { infoboxIdentifier }); } - // try to instantiate - Infobox infobox; - try { - infobox = implClass.newInstance(); - log.debug("Infobox '" + infobox.getIdentifier() + "' created."); - } catch (InstantiationException e) { - // unexpected error - log.error("Failed to instantiate infobox implementation.", e); - throw new SLRuntimeException(e); - } catch (IllegalAccessException e) { - // unexpected error - log.error("Failed to instantiate infobox implementation.", e); - throw new SLRuntimeException(e); - } - - return infobox; + return factory.createInfobox(); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java new file mode 100644 index 00000000..a9ba28e4 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandFactory.java @@ -0,0 +1,37 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import javax.xml.bind.JAXBElement; + +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLCommandException; + +public class InfoboxReadCommandFactory extends AbstractInfoboxCommandFactory { + + @Override + public SLCommand createSLCommand(JAXBElement element) throws SLCommandException { + + InfoboxReadCommandImpl command = new InfoboxReadCommandImpl(); + command.setInfoboxFactory(infoboxFactory); + command.init(element); + return command; + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java index 693f444f..736e7cbb 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java @@ -14,50 +14,50 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.bku.slcommands.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +package at.gv.egiz.bku.slcommands.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; import at.gv.egiz.bku.slcommands.InfoboxReadCommand; import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slexceptions.SLCommandException; - -/** - * This class implements the security layer command - * InfoboxReadRequest. - *

- * NOTE: Currently the only supported infobox identifier is ' - * IdentityLink'. - *

- * - * @author mcentner - */ -public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl implements - InfoboxReadCommand { - - /** - * Logging facility. - */ - protected static Log log = LogFactory.getLog(InfoboxReadCommandImpl.class); + +/** + * This class implements the security layer command + * InfoboxReadRequest. + *

+ * NOTE: Currently the only supported infobox identifier is ' + * IdentityLink'. + *

+ * + * @author mcentner + */ +public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl implements + InfoboxReadCommand { + + /** + * Logging facility. + */ + protected final Logger log = LoggerFactory.getLogger(InfoboxReadCommandImpl.class); - @Override - public String getName() { - return "InfoboxReadRequest"; - } - + @Override + public String getName() { + return "InfoboxReadRequest"; + } + @Override protected String getInfoboxIdentifier(InfoboxReadRequestType request) { return request.getInfoboxIdentifier(); } - @Override - public void init(SLCommandContext ctx, Object request) throws SLCommandException { - super.init(ctx, request); - - InfoboxReadRequestType req = getRequestValue(); + @Override + public void init(Object request) throws SLCommandException { + super.init(request); + + InfoboxReadRequestType req = getRequestValue(); if (req.getAssocArrayParameters() != null && !(infobox instanceof AssocArrayInfobox)) { @@ -70,20 +70,20 @@ public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImplnull). + */ + protected byte[] binaryContent; /** * Creates the response document from the given binaryContent. @@ -147,14 +155,34 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements * @param resultBytes */ public void setResultBytes(byte[] resultBytes) { - - xmlDocument = createResponseDocument(resultBytes, false); - + this.binaryContent = resultBytes; } @Override public void writeTo(Result result, Templates templates, boolean fragment) { + if (xmlDocument == null) { + xmlDocument = createResponseDocument(binaryContent, false); + } writeTo(xmlDocument, result, templates, fragment); } + @Override + public Object getContent() { + if (xmlDocument != null) { + NodeList nodes = xmlDocument.getElementsByTagNameNS(SLCommand.NAMESPACE_URI, "XMLContent"); + if (nodes.getLength() > 0) { + NodeList children = nodes.item(0).getChildNodes(); + ArrayList content = new ArrayList(); + for (int i = 0; i < children.getLength(); i++) { + content.add(children.item(i)); + } + return Collections.unmodifiableList(content); + } else { + return null; + } + } else { + return binaryContent; + } + } + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java index 271ec955..3be6c8f8 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java @@ -61,4 +61,22 @@ public class InfoboxReadResultImpl extends SLResultImpl implements InfoboxReadRe writeTo(response, result, templates, fragment); } + @Override + public Object getContent() { + if (infoboxReadResponse != null) { + if (infoboxReadResponse.getAssocArrayData() != null) { + return infoboxReadResponse.getAssocArrayData(); + } else { + Base64XMLContentType binaryFileData = infoboxReadResponse.getBinaryFileData(); + if (binaryFileData.getBase64Content() != null) { + return binaryFileData.getBase64Content(); + } else { + return binaryFileData.getXMLContent().getContent(); + } + } + } else { + return null; + } + } + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java new file mode 100644 index 00000000..0d421b2f --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandFactory.java @@ -0,0 +1,37 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import javax.xml.bind.JAXBElement; + +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLCommandException; + +public class InfoboxUpdateCommandFactory extends AbstractInfoboxCommandFactory { + + @Override + public SLCommand createSLCommand(JAXBElement element) throws SLCommandException { + + InfoboxUpdateCommandImpl command = new InfoboxUpdateCommandImpl(); + command.setInfoboxFactory(infoboxFactory); + command.init(element); + return command; + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java index 1cdeda94..100be13b 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java @@ -16,8 +16,8 @@ */ package at.gv.egiz.bku.slcommands.impl; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.buergerkarte.namespaces.securitylayer._1.InfoboxUpdateRequestType; import at.gv.egiz.bku.slcommands.InfoboxUpdateCommand; @@ -28,7 +28,7 @@ import at.gv.egiz.bku.slexceptions.SLCommandException; public class InfoboxUpdateCommandImpl extends AbstractInfoboxCommandImpl implements InfoboxUpdateCommand { - private static Log log = LogFactory.getLog(InfoboxUpdateCommandImpl.class); + private final Logger log = LoggerFactory.getLogger(InfoboxUpdateCommandImpl.class); @Override public String getName() { @@ -41,8 +41,8 @@ public class InfoboxUpdateCommandImpl extends } @Override - public void init(SLCommandContext ctx, Object request) throws SLCommandException { - super.init(ctx, request); + public void init(Object request) throws SLCommandException { + super.init(request); InfoboxUpdateRequestType req = getRequestValue(); @@ -61,12 +61,12 @@ public class InfoboxUpdateCommandImpl extends } @Override - public SLResult execute() { + public SLResult execute(SLCommandContext commandContext) { try { - return infobox.update(getRequestValue(), getCmdCtx()); + return infobox.update(getRequestValue(), commandContext); } catch (SLCommandException e) { - return new ErrorResultImpl(e, getCmdCtx().getLocale()); + return new ErrorResultImpl(e, commandContext.getLocale()); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java new file mode 100644 index 00000000..4b5ba381 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandFactory.java @@ -0,0 +1,37 @@ +/* +* Copyright 2009 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.slcommands.impl; + +import javax.xml.bind.JAXBElement; + +import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLCommandException; + +public class NullOperationCommandFactory extends AbstractSLCommandFactory { + + @Override + public SLCommand createSLCommand(JAXBElement element) throws SLCommandException { + + NullOperationCommandImpl command = new NullOperationCommandImpl(); + command.init(element); + return command; + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java index 1b6fb237..4d326157 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java @@ -19,6 +19,7 @@ package at.gv.egiz.bku.slcommands.impl; import at.buergerkarte.namespaces.securitylayer._1.NullOperationRequestType; import at.gv.egiz.bku.slcommands.NullOperationCommand; import at.gv.egiz.bku.slcommands.NullOperationResult; +import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slcommands.SLResult; /** @@ -31,7 +32,7 @@ public class NullOperationCommandImpl extends SLCommandImpl implements SLCommand { - /** - * The SLCommandContext for this SLCommand. - */ - protected SLCommandContext cmdCtx; - - /** - * The STAL helper. - */ - protected STALHelper stalHelper; - /** * The request element of this command. */ @@ -50,14 +39,9 @@ public abstract class SLCommandImpl implements SLCommand { @SuppressWarnings("unchecked") @Override - public void init(SLCommandContext ctx, Object request) + public void init(Object request) throws SLCommandException { - this.request = (JAXBElement) request; - - this.cmdCtx = ctx; - stalHelper = new STALHelper(cmdCtx.getSTAL()); - } /** @@ -70,12 +54,13 @@ public abstract class SLCommandImpl implements SLCommand { */ protected T getRequestValue() { return request.getValue(); - } + } + + /** + * @return the request + */ + public JAXBElement getRequest() { + return request; + } - /** - * @return the corresponding SLCommandContext - */ - protected SLCommandContext getCmdCtx() { - return cmdCtx; - } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java index 0077b7b2..1a2dcb52 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java @@ -37,8 +37,8 @@ import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import at.buergerkarte.namespaces.securitylayer._1.ErrorResponseType; @@ -64,7 +64,7 @@ public abstract class SLResultImpl implements SLResult { /** * Logging facility. */ - private static Log log = LogFactory.getLog(SLResult.class); + private final Logger log = LoggerFactory.getLogger(SLResult.class); /** * The security layer result type (default = XML). @@ -158,21 +158,21 @@ public abstract class SLResultImpl implements SLResult { marshaller.marshal(response, result); } } catch (JAXBException e) { - log.info("Failed to marshall " + response.getName() + " result." , e); + log.info("Failed to marshall {} result.", response.getName(), e); SLCommandException commandException = new SLCommandException(4000); writeErrorTo(commandException, result, templates, fragment); } if (ds != null) { try { - log.trace("Marshalled result:\n" + new String(ds.getBufferedBytes(), "UTF-8")); + log.trace("Marshalled result:\n{}", new String(ds.getBufferedBytes(), "UTF-8")); } catch (UnsupportedEncodingException e) { log.trace(e.getMessage()); } } if (dw != null) { - log.trace("Marshalled result:\n" + dw.getBufferedString()); + log.trace("Marshalled result:\n{}", dw.getBufferedString()); } } @@ -226,14 +226,14 @@ public abstract class SLResultImpl implements SLResult { if (ds != null) { try { - log.trace("Marshalled result:\n" + new String(ds.getBufferedBytes(), "UTF-8")); + log.trace("Marshalled result:\n{}", new String(ds.getBufferedBytes(), "UTF-8")); } catch (UnsupportedEncodingException e) { log.trace(e.getMessage()); } } if (dw != null) { - log.trace("Marshalled result:\n" + dw.getBufferedString()); + log.trace("Marshalled result:\n{}", dw.getBufferedString()); } } @@ -288,7 +288,7 @@ public abstract class SLResultImpl implements SLResult { marshaller.marshal(response, result); } } catch (JAXBException e) { - log.fatal("Failed to marshall error result." , e); + log.error("Failed to marshall error result." , e); throw new SLRuntimeException("Failed to marshall error result."); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java index e903c608..fd20acb4 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java @@ -22,11 +22,8 @@ import iaik.utils.Base64OutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; -import java.io.StringWriter; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; @@ -35,8 +32,8 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLExceptionMessages; @@ -59,7 +56,7 @@ public class STALHelper { /** * Logging facility. */ - private static Log log = LogFactory.getLog(STALHelper.class); + private final Logger log = LoggerFactory.getLogger(STALHelper.class); /** * The STAL implementation. @@ -95,11 +92,11 @@ public class STALHelper { public void transmitSTALRequest(List stalRequests) throws SLCommandException { List responses = stal.handleRequest(stalRequests); if (responses == null) { - Log log = LogFactory.getLog(this.getClass()); + Logger log = LoggerFactory.getLogger(this.getClass()); log.info("Received no responses from STAL."); throw new SLCommandException(4000); } else if (responses.size() != stalRequests.size()) { - Log log = LogFactory.getLog(this.getClass()); + Logger log = LoggerFactory.getLogger(this.getClass()); log.info("Received invalid count of responses from STAL. Expected " + stalRequests.size() + ", but got " + responses.size() + "."); // throw new SLCommandException(4000); @@ -144,7 +141,7 @@ public class STALHelper { } if (!(responseClass.isAssignableFrom(response.getClass()))) { - Log log = LogFactory.getLog(this.getClass()); + Logger log = LoggerFactory.getLogger(this.getClass()); log.info("Received " + response.getClass() + " from STAL but expected " + responseClass); throw new SLCommandException(4000); @@ -195,7 +192,7 @@ public class STALHelper { } catch (IOException e1) { log.info("Failed to decode certificate.", e); } - log.debug("Failed to decode certificate.\n" + certDump.toString(), e); + log.debug("Failed to decode certificate.\n{}", certDump.toString(), e); } else { log.info("Failed to decode certificate.", e); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java new file mode 100644 index 00000000..ea892ea9 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxFactory.java @@ -0,0 +1,27 @@ +/* +* Copyright 2009 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.slcommands.impl; + +public class SVPersonendatenInfoboxFactory extends AbstractInfoboxFactory { + + @Override + public Infobox createInfobox() { + return new SVPersonendatenInfoboxImpl(); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java index 7e204632..4a94b627 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java @@ -44,8 +44,8 @@ import java.util.TimeZone; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.buergerkarte.namespaces.cardchannel.AttributeList; import at.buergerkarte.namespaces.cardchannel.AttributeType; @@ -68,7 +68,7 @@ public class SVPersonendatenInfoboxImpl extends AbstractAssocArrayInfobox { /** * Logging facility. */ - private static Log log = LogFactory.getLog(SVPersonendatenInfoboxImpl.class); + private final Logger log = LoggerFactory.getLogger(SVPersonendatenInfoboxImpl.class); public static final String EHIC = "EHIC"; @@ -145,7 +145,7 @@ public class SVPersonendatenInfoboxImpl extends AbstractAssocArrayInfobox { } } catch (CodingException e) { - log.info("Failed to decode '" + getIdentifier() + "' infobox.", e); + log.info("Failed to decode '{}' infobox.", getIdentifier(), e); throw new SLCommandException(4000, SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID, new Object[] { "IdentityLink" }); @@ -256,6 +256,8 @@ public class SVPersonendatenInfoboxImpl extends AbstractAssocArrayInfobox { private static void setAttributeValue(AttributeType attributeType, ASN1Object value) { + Logger log = LoggerFactory.getLogger(SVPersonendatenInfoboxImpl.class); + if (value.isA(ASN.OCTET_STRING)) { try { diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java index 8391e450..f1219a6c 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java @@ -165,8 +165,7 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory { public SignatureMethod createSignatureMethod(SignatureContext signatureContext) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { - return signatureContext.getSignatureFactory().newSignatureMethod( - signatureAlgorithmURI, signatureMethodParameterSpec); + return new STALSignatureMethod(signatureAlgorithmURI, signatureMethodParameterSpec); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java index 2cae41d6..a3f913de 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java @@ -20,11 +20,13 @@ import iaik.xml.crypto.dom.DOMCryptoContext; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.io.StringWriter; import java.io.UnsupportedEncodingException; +import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; import java.security.InvalidAlgorithmParameterException; @@ -36,6 +38,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; import javax.xml.crypto.MarshalException; import javax.xml.crypto.dom.DOMStructure; import javax.xml.crypto.dsig.CanonicalizationMethod; @@ -46,15 +51,17 @@ import javax.xml.crypto.dsig.XMLObject; import javax.xml.crypto.dsig.spec.TransformParameterSpec; import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec; import javax.xml.crypto.dsig.spec.XPathType; +import javax.xml.namespace.QName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; @@ -70,6 +77,7 @@ import at.buergerkarte.namespaces.securitylayer._1.MetaInfoType; import at.buergerkarte.namespaces.securitylayer._1.TransformsInfoType; import at.gv.egiz.bku.binding.HttpUtil; import at.gv.egiz.bku.gui.viewer.MimeTypes; +import at.gv.egiz.bku.slcommands.SLMarshallerFactory; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; @@ -81,10 +89,6 @@ import at.gv.egiz.bku.viewer.Validator; import at.gv.egiz.bku.viewer.ValidatorFactory; import at.gv.egiz.dom.DOMUtils; import at.gv.egiz.slbinding.impl.XMLContentType; -import java.io.File; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; /** * This class represents a DataObject of an XML-Signature @@ -97,7 +101,7 @@ public class DataObject { /** * Logging facility. */ - private static Log log = LogFactory.getLog(DataObject.class); + private final Logger log = LoggerFactory.getLogger(DataObject.class); /** * DOM Implementation. @@ -205,7 +209,7 @@ public class DataObject { domImplLS = (DOMImplementationLS) registry.getDOMImplementation(DOM_LS_3_0); if (domImplLS == null) { - log.error("Failed to get DOMImplementation " + DOM_LS_3_0); + log.error("Failed to get DOMImplementation {}.", DOM_LS_3_0); throw new SLRuntimeException("Failed to get DOMImplementation " + DOM_LS_3_0); } @@ -276,7 +280,7 @@ public class DataObject { try { validator = ValidatorFactory.newValidator(mediaType); } catch (IllegalArgumentException e) { - log.error("No validator found for mime type '" + mediaType + "'."); + log.error("No validator found for mime type '{}'.", mediaType, e); throw new SLViewerException(5000); } @@ -299,7 +303,7 @@ public class DataObject { } } else { - log.debug("MIME media type '" + mediaType + "' is not a s/valid/SUPPORTED digest input, omitting validation."); + log.debug("MIME media type '{}' is not a s/valid/SUPPORTED digest input, omitting validation.", mediaType); } } @@ -359,12 +363,12 @@ public class DataObject { if (reference != null) { if (reference.getURI() != null && !"".equals(reference.getURI())) { try { - log.info("deriving filename from reference URI " + reference.getURI()); + log.info("Deriving filename from reference URI {}.", reference.getURI()); URI refURI = new URI(reference.getURI()); if (refURI.isOpaque()) { // could check scheme component, but also allow other schemes (e.g. testlocal) - log.trace("opaque reference URI, use scheme-specific part as filename"); + log.trace("Opaque reference URI, use scheme-specific part as filename."); filename = refURI.getSchemeSpecificPart(); if (!hasExtension(filename)) { filename += MimeTypes.getExtension(mimeType); @@ -376,34 +380,34 @@ public class DataObject { } else if ("".equals(refURI.getPath()) && refURI.getFragment() != null && refURI.getFragment().indexOf('(') < 0) { // exclude (schemebased) xpointer expressions - log.trace("fragment (shorthand xpointer) URI, use fragment as filename"); + log.trace("Fragment (shorthand xpointer) URI, use fragment as filename."); filename = refURI.getFragment(); if(!hasExtension(filename)) { filename += MimeTypes.getExtension(mimeType); } } else if (!"".equals(refURI.getPath())) { - log.trace("hierarchical URI with path component, use path as filename"); + log.trace("Hierarchical URI with path component, use path as filename."); File refFile = new File(refURI.getPath()); filename = refFile.getName(); if(!hasExtension(filename)) { filename += MimeTypes.getExtension(mimeType); } } else { - log.debug("failed to derive filename from URI '" + refURI + "', derive filename from reference ID"); + log.debug("Failed to derive filename from URI '{}', derive filename from reference ID.", refURI); filename = reference.getId() + MimeTypes.getExtension(mimeType); } } catch (URISyntaxException ex) { - log.error("failed to derive filename from invalid URI " + ex.getMessage()); + log.error("Failed to derive filename from invalid URI {}.", ex.getMessage()); filename = reference.getId() + MimeTypes.getExtension(mimeType); } } else { - log.debug("same-document URI, derive filename from reference ID"); + log.debug("Same-document URI, derive filename from reference ID."); filename = reference.getId() + MimeTypes.getExtension(mimeType); } } else { - log.error("failed to derive filename, no reference created"); + log.error("Failed to derive filename, no reference created."); } - log.debug("derived filename for reference " + reference.getId() + ": " + filename); + log.debug("Derived filename for reference {}: {}.", reference.getId(), filename); return filename; } @@ -413,30 +417,12 @@ public class DataObject { } private byte[] getTransformsBytes(at.gv.egiz.slbinding.impl.TransformsInfoType ti) { - return ti.getRedirectedStream().toByteArray(); -// byte[] transformsBytes = ti.getRedirectedStream().toByteArray(); -// -// if (transformsBytes == null || transformsBytes.length == 0) { -// return null; -// } -// -// String dsigPrefix = ti.getNamespaceContext().getNamespaceURI("http://www.w3.org/2000/09/xmldsig#"); -// byte[] pre, post; -// if (dsigPrefix == null) { -// log.trace("XMLDSig not declared in outside dsig:Transforms"); -// pre = "".getBytes(); -// post = "".getBytes(); -// } else { -// log.trace("XMLDSig bound to prefix " + dsigPrefix); -// pre = ("").getBytes(); -// post = "".getBytes(); -// } -// -// byte[] workaround = new byte[pre.length + transformsBytes.length + post.length]; -// System.arraycopy(pre, 0, workaround, 0, pre.length); -// System.arraycopy(transformsBytes, 0, workaround, pre.length, transformsBytes.length); -// System.arraycopy(post, 0, workaround, pre.length + transformsBytes.length, post.length); -// return workaround; + ByteArrayOutputStream redirectedStream = ti.getRedirectedStream(); + if (redirectedStream != null) { + return redirectedStream.toByteArray(); + } else { + return null; + } } /** @@ -487,9 +473,8 @@ public class DataObject { // create XMLObject DocumentFragment content = parseDataObject((XMLContentType) dataObject.getXMLContent()); - XMLObject xmlObject = createXMLObject(content); - setXMLObjectAndReferenceXML(xmlObject, transforms); + setXMLObjectAndReferenceXML(createXMLObject(content), transforms); } else if (dataObject.getLocRefContent() != null) { @@ -521,7 +506,7 @@ public class DataObject { // The content of sl:DataObject remains empty // - log.debug("Adding DataObject from reference URI '" + reference + "'."); + log.debug("Adding DataObject from reference URI '{}'.", reference); setEnvelopedDataObject(reference, transforms); @@ -564,13 +549,13 @@ public class DataObject { } // dereference URL - URLDereferencer dereferencer = URLDereferencer.getInstance(); + URLDereferencer dereferencer = ctx.getUrlDereferencer(); StreamData streamData; try { - streamData = dereferencer.dereference(reference, ctx.getDereferencerContext()); + streamData = dereferencer.dereference(reference); } catch (IOException e) { - log.info("Failed to dereference XMLObject from '" + reference + "'.", e); + log.info("Failed to dereference XMLObject from '{}'.", reference, e); throw new SLCommandException(4110); } @@ -587,7 +572,7 @@ public class DataObject { childNode = doc.getDocumentElement(); if (childNode == null) { - log.info("Failed to parse XMLObject from '" + reference + "'."); + log.info("Failed to parse XMLObject from '{}'.", reference); throw new SLCommandException(4111); } @@ -666,12 +651,12 @@ public class DataObject { if (dataObject.getLocRefContent() != null) { String locRef = dataObject.getLocRefContent(); try { - this.reference.setDereferencer(new LocRefDereferencer(ctx.getDereferencerContext(), locRef)); + this.reference.setDereferencer(new LocRefDereferencer(ctx.getUrlDereferencer(), locRef)); } catch (URISyntaxException e) { - log.info("Invalid URI '" + locRef + "' in DataObject.", e); + log.info("Invalid URI '{}' in DataObject.", locRef, e); throw new SLCommandException(4003); } catch (IllegalArgumentException e) { - log.info("LocRef URI of '" + locRef + "' not supported in DataObject. ", e); + log.info("LocRef URI of '{}' not supported in DataObject. ", locRef, e); throw new SLCommandException(4003); } } else if (dataObject.getBase64Content() != null) { @@ -734,7 +719,7 @@ public class DataObject { } if (debugString != null) { - log.debug(debugString); + log.debug(debugString.toString()); } // look for preferred transform @@ -778,7 +763,7 @@ public class DataObject { StringBuilder sb = new StringBuilder(); sb.append("Trying to parse transforms:\n"); sb.append(new String(transforms, Charset.forName("UTF-8"))); - log.trace(sb); + log.trace(sb.toString()); } DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS(); @@ -933,8 +918,7 @@ public class DataObject { } catch (MarshalException e) { String mimeType = preferredTransformsInfo.getFinalDataMetaInfo().getMimeType(); - log.info("Failed to unmarshal preferred transformation path (MIME-Type=" - + mimeType + ").", e); + log.info("Failed to unmarshal preferred transformation path (MIME-Type={}).", mimeType, e); } @@ -950,8 +934,7 @@ public class DataObject { } catch (MarshalException e) { String mimeType = transformsInfoType.getFinalDataMetaInfo().getMimeType(); - log.info("Failed to unmarshal transformation path (MIME-Type=" - + mimeType + ").", e); + log.info("Failed to unmarshal transformation path (MIME-Type={}).", mimeType, e); } } @@ -975,7 +958,7 @@ public class DataObject { try { textNode = at.gv.egiz.dom.DOMUtils.createBase64Text(content, ctx.getDocument()); } catch (IOException e) { - log.error(e); + log.error("Failed to create XMLObject.", e); throw new SLRuntimeException(e); } @@ -1170,36 +1153,68 @@ public class DataObject { // content of the redirect stream as the content has already been parsed // and serialized again to the redirect stream. - List inputStreams = new ArrayList(); - try { - // dummy start element - inputStreams.add(new ByteArrayInputStream("".getBytes("UTF-8"))); - - // content - inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray())); - - // dummy end element - inputStreams.add(new ByteArrayInputStream("".getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - throw new SLRuntimeException(e); - } + DocumentFragment fragment; + if (redirectedStream != null) { - SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreams)); - - // parse DataObject - Document doc = parseDataObject(inputStream, "UTF-8"); + List inputStreams = new ArrayList(); + try { + // dummy start element + inputStreams.add(new ByteArrayInputStream("".getBytes("UTF-8"))); - Element documentElement = doc.getDocumentElement(); - - if (documentElement == null || - !"dummy".equals(documentElement.getLocalName())) { - log.info("Failed to parse DataObject XMLContent."); - throw new SLCommandException(4111); - } + // content + inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray())); + + // dummy end element + inputStreams.add(new ByteArrayInputStream("".getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + throw new SLRuntimeException(e); + } + + SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreams)); - DocumentFragment fragment = doc.createDocumentFragment(); - while (documentElement.getFirstChild() != null) { - fragment.appendChild(documentElement.getFirstChild()); + // parse DataObject + Document doc = parseDataObject(inputStream, "UTF-8"); + + Element documentElement = doc.getDocumentElement(); + + if (documentElement == null || + !"dummy".equals(documentElement.getLocalName())) { + log.info("Failed to parse DataObject XMLContent."); + throw new SLCommandException(4111); + } + + fragment = doc.createDocumentFragment(); + while (documentElement.getFirstChild() != null) { + fragment.appendChild(documentElement.getFirstChild()); + } + + } else { + + fragment = ctx.getDocument().createDocumentFragment(); + Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false); + + JAXBElement element = + new JAXBElement( + new QName("dummy"), + at.buergerkarte.namespaces.securitylayer._1.XMLContentType.class, + xmlContent); + + try { + marshaller.marshal(element, fragment); + } catch (JAXBException e) { + log.info("Failed to marshal DataObject (XMLContent).", e); + throw new SLCommandException(4111); + } + + Node dummy = fragment.getFirstChild(); + if (dummy != null) { + NodeList nodes = dummy.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + fragment.appendChild(nodes.item(i)); + } + fragment.removeChild(dummy); + } + } // log parsed document @@ -1256,6 +1271,8 @@ public class DataObject { SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler(); domConfig.setParameter("error-handler", errorHandler); domConfig.setParameter("validate", Boolean.FALSE); + domConfig.setParameter("entities", Boolean.TRUE); + Document doc; try { diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java index f5394157..e513738c 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java @@ -14,99 +14,96 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.bku.slcommands.impl.xsect; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.xml.crypto.Data; -import javax.xml.crypto.OctetStreamData; -import javax.xml.crypto.URIDereferencer; -import javax.xml.crypto.URIReference; -import javax.xml.crypto.URIReferenceException; -import javax.xml.crypto.XMLCryptoContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.utils.urldereferencer.StreamData; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; - -/** - * An URIDereferencer implementation that dereferences LocRef - * references. - * - * @author mcentner - */ -public class LocRefDereferencer implements URIDereferencer { - - /** - * Logging facility. - */ - private static Log log = LogFactory.getLog(LocRefDereferencer.class); - - /** - * The LocRef-reference to be dereferenced by - * {@link #dereference(URIReference, XMLCryptoContext)}. - */ - protected String locRef; - - /** - * The context to be used for dereferencing. - */ - protected URLDereferencerContext dereferencerContext; - - /** - * Creates a new instance of this LocRefDereferencer with the given - * dereferencerContext and locRef reference. - * - * @param dereferencerContext - * the context to be used for dereferencing - * @param locRef - * the LocRef-reference (must be an absolute URI) - * - * @throws URISyntaxException - * if LocRef is not an absolute URI - */ - public LocRefDereferencer(URLDereferencerContext dereferencerContext, - String locRef) throws URISyntaxException { - - this.dereferencerContext = dereferencerContext; - - URI locRefUri = new URI(locRef); - if (locRefUri.isAbsolute()) { - this.locRef = locRef; - } else { - throw new IllegalArgumentException( - "Parameter 'locRef' must be an absolut URI."); - } - } - - /* - * (non-Javadoc) - * - * @see - * javax.xml.crypto.URIDereferencer#dereference(javax.xml.crypto.URIReference, - * javax.xml.crypto.XMLCryptoContext) - */ - @Override - public Data dereference(URIReference uriReference, XMLCryptoContext context) - throws URIReferenceException { - - URLDereferencer dereferencer = URLDereferencer.getInstance(); - StreamData streamData; - try { - streamData = dereferencer.dereference(locRef, dereferencerContext); - } catch (IOException e) { - log.info("Failed to dereference URI'" + locRef + "'. " + e.getMessage(), - e); - throw new URIReferenceException("Failed to dereference URI '" + locRef - + "'. " + e.getMessage(), e); - } - return new OctetStreamData(streamData.getStream(), locRef, streamData - .getContentType()); - } - -} +package at.gv.egiz.bku.slcommands.impl.xsect; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.xml.crypto.Data; +import javax.xml.crypto.OctetStreamData; +import javax.xml.crypto.URIDereferencer; +import javax.xml.crypto.URIReference; +import javax.xml.crypto.URIReferenceException; +import javax.xml.crypto.XMLCryptoContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.utils.urldereferencer.StreamData; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; + +/** + * An URIDereferencer implementation that dereferences LocRef + * references. + * + * @author mcentner + */ +public class LocRefDereferencer implements URIDereferencer { + + /** + * Logging facility. + */ + private final Logger log = LoggerFactory.getLogger(LocRefDereferencer.class); + + /** + * The LocRef-reference to be dereferenced by + * {@link #dereference(URIReference, XMLCryptoContext)}. + */ + protected String locRef; + + /** + * The URLDereferencer to be used for dereferencing. + */ + protected URLDereferencer dereferencer; + + /** + * Creates a new instance of this LocRefDereferencer with the given + * dereferencerContext and locRef reference. + * + * @param dereferencer + * the context to be used for dereferencing + * @param locRef + * the LocRef-reference (must be an absolute URI) + * + * @throws URISyntaxException + * if LocRef is not an absolute URI + */ + public LocRefDereferencer(URLDereferencer dereferencer, + String locRef) throws URISyntaxException { + + this.dereferencer = dereferencer; + + URI locRefUri = new URI(locRef); + if (locRefUri.isAbsolute()) { + this.locRef = locRef; + } else { + throw new IllegalArgumentException( + "Parameter 'locRef' must be an absolut URI."); + } + } + + /* + * (non-Javadoc) + * + * @see + * javax.xml.crypto.URIDereferencer#dereference(javax.xml.crypto.URIReference, + * javax.xml.crypto.XMLCryptoContext) + */ + @Override + public Data dereference(URIReference uriReference, XMLCryptoContext context) + throws URIReferenceException { + + StreamData streamData; + try { + streamData = dereferencer.dereference(locRef); + } catch (IOException e) { + log.info("Failed to dereference URI '{}'.", locRef, e); + throw new URIReferenceException("Failed to dereference URI '" + locRef + + "'. " + e.getMessage(), e); + } + return new OctetStreamData(streamData.getStream(), locRef, streamData + .getContentType()); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java index 25e2d4e5..87a165cf 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java @@ -16,7 +16,6 @@ */ package at.gv.egiz.bku.slcommands.impl.xsect; -import at.gv.egiz.stal.HashDataInput; import java.security.PrivateKey; import at.gv.egiz.stal.STAL; @@ -24,7 +23,7 @@ import at.gv.egiz.stal.STAL; import java.util.List; /** - * This class implements a private key used by the {@link STALSignature} class. + * This class implements a private key used by the {@link STALSignatureMethod} class. * * @author mcentner */ diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java deleted file mode 100644 index 9fb9a3f1..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java +++ /dev/null @@ -1,71 +0,0 @@ -/* -* 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.slcommands.impl.xsect; - -import iaik.xml.crypto.XmldsigMore; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.Provider; -import java.security.Signature; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.crypto.dsig.SignatureMethod; - -/** - * A security provider implementation that provides {@link Signature} implementations - * based on STAL. - * - * @author mcentner - */ -public class STALProvider extends Provider { - - private static final long serialVersionUID = 1L; - - private static String IMPL_PACKAGE_NAME = "at.gv.egiz.bku.slcommands.impl.xsect"; - - public STALProvider() { - - super("STAL", 1.0, "Security Token Abstraction Layer Provider"); - - final Map map = new HashMap(); - - // TODO: register further algorithms - map.put("Signature." + SignatureMethod.RSA_SHA1, - IMPL_PACKAGE_NAME + ".STALSignature"); - map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA1, - IMPL_PACKAGE_NAME + ".STALSignature"); - map.put("Signature." + XmldsigMore.SIGNATURE_RSA_SHA256, - IMPL_PACKAGE_NAME + ".STALSignature"); - map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA256, - IMPL_PACKAGE_NAME + ".STALSignature"); - map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA512, - IMPL_PACKAGE_NAME + ".STALSignature"); - - - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - putAll(map); - return null; - } - }); - - } - -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java deleted file mode 100644 index dd7c7d8a..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java +++ /dev/null @@ -1,184 +0,0 @@ -/* -* 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.slcommands.impl.xsect; - -import at.gv.egiz.bku.slcommands.impl.DataObjectHashDataInput; -import at.gv.egiz.bku.slexceptions.SLViewerException; - -import java.io.ByteArrayOutputStream; -import java.security.InvalidKeyException; -import java.security.InvalidParameterException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SignatureException; -import java.security.SignatureSpi; -import java.util.Collections; -import java.util.List; - -import at.gv.egiz.stal.ErrorResponse; -import at.gv.egiz.stal.HashDataInput; -import at.gv.egiz.stal.STAL; -import at.gv.egiz.stal.STALRequest; -import at.gv.egiz.stal.STALResponse; -import at.gv.egiz.stal.SignRequest; -import at.gv.egiz.stal.SignResponse; -//import at.gv.egiz.stal.HashDataInputCallback; -import java.util.ArrayList; - -/** - * A signature service provider implementation that uses STAL to sign. - * - * @author mcentner - */ -public class STALSignature extends SignatureSpi { - -// private static final Log log = LogFactory.getLog(STALSignature.class); - - /** - * The private key. - */ - protected STALPrivateKey privateKey; - - /** - * The to-be signed data. - */ - protected ByteArrayOutputStream data = new ByteArrayOutputStream(); - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineGetParameter(java.lang.String) - */ - @Override - protected Object engineGetParameter(String param) - throws InvalidParameterException { - throw new InvalidParameterException(); - } - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineInitSign(java.security.PrivateKey) - */ - @Override - protected void engineInitSign(PrivateKey privateKey) - throws InvalidKeyException { - - if (!(privateKey instanceof STALPrivateKey)) { - throw new InvalidKeyException("STALSignature supports STALKeys only."); - } - - this.privateKey = (STALPrivateKey) privateKey; - - } - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineInitVerify(java.security.PublicKey) - */ - @Override - protected void engineInitVerify(PublicKey publicKey) - throws InvalidKeyException { - - throw new UnsupportedOperationException("STALSignature does not support signature verification."); - } - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineSetParameter(java.lang.String, java.lang.Object) - */ - @Override - protected void engineSetParameter(String param, Object value) - throws InvalidParameterException { - } - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineSign() - */ - @Override - protected byte[] engineSign() throws SignatureException { - - STAL stal = privateKey.getStal(); - - if (stal == null) { - throw new SignatureException("STALSignature requires the STALPrivateKey " + - "to provide a STAL implementation reference."); - } - - String keyboxIdentifier = privateKey.getKeyboxIdentifier(); - - if (keyboxIdentifier == null) { - throw new SignatureException("STALSignature requires the STALPrivateKey " + - "to provide a KeyboxIdentifier."); - } - - // get hashDataInputs (DigestInputStreams) once slcommands.impl.xsect.Signature::sign() was called - List dataObjects = privateKey.getDataObjects(); -// log.debug("got " + dataObjects.size() + " DataObjects, passing HashDataInputs to STAL SignRequest"); - - List hashDataInputs = new ArrayList(); - for (DataObject dataObject : dataObjects) { - try { - dataObject.validateHashDataInput(); - } catch (SLViewerException e) { - throw new STALSignatureException(e); - } - hashDataInputs.add(new DataObjectHashDataInput(dataObject)); - } - - SignRequest signRequest = new SignRequest(); - signRequest.setKeyIdentifier(keyboxIdentifier); - signRequest.setSignedInfo(data.toByteArray()); - signRequest.setHashDataInput(hashDataInputs); - - List responses = stal.handleRequest(Collections.singletonList((STALRequest) signRequest)); - - if (responses == null || responses.size() != 1) { - throw new SignatureException("Failed to access STAL."); - } - - STALResponse response = responses.get(0); - if (response instanceof SignResponse) { - return ((SignResponse) response).getSignatureValue(); - } else if (response instanceof ErrorResponse) { - throw new STALSignatureException(((ErrorResponse) response).getErrorCode()); - } else { - throw new SignatureException("Failed to access STAL."); - } - - } - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineUpdate(byte) - */ - @Override - protected void engineUpdate(byte b) throws SignatureException { - data.write(b); - } - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineUpdate(byte[], int, int) - */ - @Override - protected void engineUpdate(byte[] b, int off, int len) - throws SignatureException { - data.write(b, off, len); - } - - /* (non-Javadoc) - * @see java.security.SignatureSpi#engineVerify(byte[]) - */ - @Override - protected boolean engineVerify(byte[] sigBytes) throws SignatureException { - throw new UnsupportedOperationException("STALSignature des not support signature verification."); - } - -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java index 4e86b07c..b727600f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java @@ -19,7 +19,7 @@ package at.gv.egiz.bku.slcommands.impl.xsect; import java.security.SignatureException; /** - * A SignatureException thrown by the {@link STALSignature}. + * A SignatureException thrown by the {@link STALSignatureMethod}. * * @author mcentner */ diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java new file mode 100644 index 00000000..a9bb8e04 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureMethod.java @@ -0,0 +1,127 @@ +/* +* Copyright 2009 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.slcommands.impl.xsect; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.xml.crypto.XMLCryptoContext; +import javax.xml.crypto.dsig.XMLSignatureException; +import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec; + +import at.gv.egiz.bku.slcommands.impl.DataObjectHashDataInput; +import at.gv.egiz.bku.slexceptions.SLViewerException; +import at.gv.egiz.bku.utils.StreamUtil; +import at.gv.egiz.stal.ErrorResponse; +import at.gv.egiz.stal.HashDataInput; +import at.gv.egiz.stal.STAL; +import at.gv.egiz.stal.STALRequest; +import at.gv.egiz.stal.STALResponse; +import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.SignResponse; + +import iaik.xml.crypto.dsig.AbstractSignatureMethodImpl; + +public class STALSignatureMethod extends AbstractSignatureMethodImpl { + + /** + * Creates a new instance of this STALSignatureMethod + * with the given algorithm and params. + * + * @param algorithm the algorithm URI + * @param params optional algorithm parameters + * @throws InvalidAlgorithmParameterException if the specified parameters + * are inappropriate for the requested algorithm + * @throws NoSuchAlgorithmException if an implementation of the specified + * algorithm cannot be found + * @throws NullPointerException if algorithm is null + */ + public STALSignatureMethod(String algorithm, + SignatureMethodParameterSpec params) + throws InvalidAlgorithmParameterException, NoSuchAlgorithmException { + super(algorithm, params); + } + + @Override + public byte[] calculateSignatureValue(XMLCryptoContext context, Key key, InputStream message) + throws XMLSignatureException, IOException { + + if (!(key instanceof STALPrivateKey)) { + throw new XMLSignatureException("STALSignatureMethod expects STALPrivateKey."); + } + + STAL stal = ((STALPrivateKey) key).getStal(); + String keyboxIdentifier = ((STALPrivateKey) key).getKeyboxIdentifier(); + List dataObjects = ((STALPrivateKey) key).getDataObjects(); + + List hashDataInputs = new ArrayList(); + for (DataObject dataObject : dataObjects) { + try { + dataObject.validateHashDataInput(); + } catch (SLViewerException e) { + throw new XMLSignatureException(e); + } + hashDataInputs.add(new DataObjectHashDataInput(dataObject)); + } + + ByteArrayOutputStream m = new ByteArrayOutputStream(); + StreamUtil.copyStream(message, m); + + SignRequest signRequest = new SignRequest(); + signRequest.setKeyIdentifier(keyboxIdentifier); + signRequest.setSignedInfo(m.toByteArray()); + signRequest.setHashDataInput(hashDataInputs); + + List responses = + stal.handleRequest(Collections.singletonList((STALRequest) signRequest)); + + if (responses == null || responses.size() != 1) { + throw new XMLSignatureException("Failed to access STAL."); + } + + STALResponse response = responses.get(0); + if (response instanceof SignResponse) { + return ((SignResponse) response).getSignatureValue(); + } else if (response instanceof ErrorResponse) { + STALSignatureException se = new STALSignatureException(((ErrorResponse) response).getErrorCode()); + throw new XMLSignatureException(se); + } else { + throw new XMLSignatureException("Failed to access STAL."); + } + + } + + @Override + public boolean validateSignatureValue(XMLCryptoContext context, Key key, byte[] value, + InputStream message) throws XMLSignatureException, IOException { + throw new XMLSignatureException("The STALSignatureMethod does not support validation."); + } + + @Override + protected Class getParameterSpecClass() { + return null; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java index 3cebb6a3..b4ce0e79 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java @@ -51,8 +51,8 @@ import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; import javax.xml.crypto.dsig.keyinfo.X509Data; import javax.xml.stream.XMLStreamException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.etsi.uri._01903.v1_1.DataObjectFormatType; import org.etsi.uri._01903.v1_1.QualifyingPropertiesType; import org.w3c.dom.DOMConfiguration; @@ -82,7 +82,6 @@ import at.gv.egiz.bku.slexceptions.SLViewerException; import at.gv.egiz.bku.utils.HexDump; import at.gv.egiz.bku.utils.urldereferencer.StreamData; import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; import at.gv.egiz.dom.DOMUtils; import at.gv.egiz.slbinding.impl.XMLContentType; import at.gv.egiz.stal.STAL; @@ -101,7 +100,7 @@ public class Signature { /** * Logging facility. */ - private static Log log = LogFactory.getLog(Signature.class); + private final Logger log = LoggerFactory.getLogger(Signature.class); /** * The DOM implementation used. @@ -151,8 +150,9 @@ public class Signature { /** * Creates a new SLXMLSignature instance. + * @param urlDereferencer TODO */ - public Signature(URLDereferencerContext dereferencerContext, + public Signature(URLDereferencer urlDereferencer, IdValueFactory idValueFactory, AlgorithmMethodFactory algorithmMethodFactory) { @@ -162,7 +162,7 @@ public class Signature { ctx.setSignatureFactory(XMLSignatureFactory.getInstance()); - ctx.setDereferencerContext(dereferencerContext); + ctx.setUrlDereferencer(urlDereferencer); ctx.setIdValueFactory(idValueFactory); ctx.setAlgorithmMethodFactory(algorithmMethodFactory); @@ -408,7 +408,7 @@ public class Signature { signContext.putNamespacePrefix(XMLSignature.XMLNS,XMLDSIG_PREFIX); - signContext.setURIDereferencer(new URIDereferncerAdapter(ctx.getDereferencerContext())); + signContext.setURIDereferencer(new URIDereferncerAdapter(ctx.getUrlDereferencer())); try { xmlSignature.sign(signContext); @@ -455,7 +455,7 @@ public class Signature { sb.append(HexDump.hexDump(digestInputStream)); } } catch (IOException e) { - log.error(e); + log.error("Failed to log DigestInput.", e); } log.trace(sb.toString()); } else { @@ -478,7 +478,7 @@ public class Signature { sb.append(new String(b, 0, l)); } } catch (IOException e) { - log.error(e); + log.error("Failed to log DigestInput.", e); } log.trace(sb.toString()); } else { @@ -735,7 +735,7 @@ public class Signature { LSInput input; try { if (signatureEnvironment.getReference() != null) { - log.debug("SignatureEnvironment contains Reference " + signatureEnvironment.getReference() + "."); + log.debug("SignatureEnvironment contains Reference '{}'.", signatureEnvironment.getReference()); input = createLSInput(signatureEnvironment.getReference()); } else if (signatureEnvironment.getBase64Content() != null) { log.debug("SignatureEnvironment contains Base64Content."); @@ -784,11 +784,12 @@ public class Signature { if (log.isInfoEnabled()) { List errorMessages = errorHandler.getErrorMessages(); StringBuffer sb = new StringBuffer(); + sb.append("XML document in which the signature is to be integrated cannot be parsed."); for (String errorMessage : errorMessages) { sb.append(" "); sb.append(errorMessage); } - log.info("XML document in which the signature is to be integrated cannot be parsed." + sb.toString()); + log.info(sb.toString()); } throw new SLCommandException(4101); } @@ -826,8 +827,8 @@ public class Signature { */ private LSInput createLSInput(String reference) throws IOException { - URLDereferencer urlDereferencer = URLDereferencer.getInstance(); - StreamData streamData = urlDereferencer.dereference(reference, ctx.getDereferencerContext()); + URLDereferencer urlDereferencer = ctx.getUrlDereferencer(); + StreamData streamData = urlDereferencer.dereference(reference); String contentType = streamData.getContentType(); String charset = HttpUtil.getCharset(contentType, true); @@ -835,7 +836,7 @@ public class Signature { try { streamReader = new InputStreamReader(streamData.getStream(), charset); } catch (UnsupportedEncodingException e) { - log.info("Charset " + charset + " not supported. Using default."); + log.info("Charset {} not supported. Using default.", charset); streamReader = new InputStreamReader(streamData.getStream()); } @@ -942,7 +943,7 @@ public class Signature { if (systemId != null) { - log.debug("Resolve resource '" + systemId + "'."); + log.debug("Resolve resource '{}'.", systemId); for (DataObjectAssociationType supplement : supplements) { @@ -954,23 +955,23 @@ public class Signature { try { if (content.getLocRefContent() != null) { - log.trace("Resolved resource '" + reference + "' to supplement with LocRefContent."); + log.trace("Resolved resource '{}' to supplement with LocRefContent.", reference); return createLSInput(content.getLocRefContent()); } else if (content.getBase64Content() != null) { - log.trace("Resolved resource '" + reference + "' to supplement with Base64Content."); + log.trace("Resolved resource '{}' to supplement with Base64Content.", reference); return createLSInput(content.getBase64Content()); } else if (content.getXMLContent() != null) { - log.trace("Resolved resource '" + reference + "' to supplement with XMLContent."); + log.trace("Resolved resource '{}' to supplement with XMLContent.", reference); return createLSInput((XMLContentType) content.getXMLContent()); } else { return null; } } catch (IOException e) { - log.info("Failed to resolve resource '" + systemId + "' to supplement.", e); + log.info("Failed to resolve resource '{}' to supplement.", systemId, e); error = e; return null; } catch (XMLStreamException e) { - log.info("Failed to resolve resource '" + systemId + "' to supplement.", e); + log.info("Failed to resolve resource '{}' to supplement.", systemId, e); error = e; return null; } @@ -981,7 +982,7 @@ public class Signature { } - log.info("Failed to resolve resource '" + systemId + "' to supplement. No such supplement."); + log.info("Failed to resolve resource '{}' to supplement. No such supplement.", systemId); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java index 0925f2fd..48c82bd5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java @@ -16,12 +16,12 @@ */ package at.gv.egiz.bku.slcommands.impl.xsect; -import javax.xml.crypto.dsig.DigestMethod; +import javax.xml.crypto.AlgorithmMethod; import javax.xml.crypto.dsig.XMLSignatureFactory; import org.w3c.dom.Document; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; /** * An instance of this class carries context information for a XML-Signature @@ -45,16 +45,16 @@ public class SignatureContext { * The XMLSignatureFactory to create XML signature objects. */ private XMLSignatureFactory signatureFactory; + + /** + * The URLDereferencer to dereference URLs with. + */ + private URLDereferencer urlDereferencer; /** - * The URLDereferencerContext for dereferencing URLs. + * The AlgorithmMethodFactory to create {@link AlgorithmMethod} objects. */ - private URLDereferencerContext dereferencerContext; - - /** - * The DigestMethodFactory to create {@link DigestMethod} objects. - */ - private AlgorithmMethodFactory digestMethodFactory; + private AlgorithmMethodFactory algorithmMethodFactory; /** * @return the document @@ -98,32 +98,32 @@ public class SignatureContext { this.signatureFactory = signatureFactory; } - /** - * @return the dereferencerContext - */ - public URLDereferencerContext getDereferencerContext() { - return dereferencerContext; - } - - /** - * @param dereferencerContext the dereferencerContext to set - */ - public void setDereferencerContext(URLDereferencerContext dereferencerContext) { - this.dereferencerContext = dereferencerContext; - } - /** * @return the digestMethodFactory */ public AlgorithmMethodFactory getAlgorithmMethodFactory() { - return digestMethodFactory; + return algorithmMethodFactory; } /** * @param digestMethodFactory the digestMethodFactory to set */ public void setAlgorithmMethodFactory(AlgorithmMethodFactory digestMethodFactory) { - this.digestMethodFactory = digestMethodFactory; + this.algorithmMethodFactory = digestMethodFactory; + } + + /** + * @return the urlDereferencer + */ + public URLDereferencer getUrlDereferencer() { + return urlDereferencer; + } + + /** + * @param urlDereferencer the urlDereferencer to set + */ + public void setUrlDereferencer(URLDereferencer urlDereferencer) { + this.urlDereferencer = urlDereferencer; } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java index ebe50b3f..26a4aa4e 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java @@ -14,212 +14,212 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.bku.slcommands.impl.xsect; - -import java.util.Iterator; - -import javax.xml.XMLConstants; -import javax.xml.namespace.NamespaceContext; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Node; - -import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType; -import at.gv.egiz.bku.slexceptions.SLCommandException; -import at.gv.egiz.slbinding.impl.SignatureLocationType; - -/** - * This class implements the SignatureLocation of an XML-Signature - * to be created by the security layer command CreateXMLSignature. - * - * @author mcentner - */ -public class SignatureLocation { - - /** - * Logging facility. - */ - private static Log log = LogFactory.getLog(SignatureLocation.class); - - /** - * The SignatureContext for the XML signature - */ - private SignatureContext ctx; - - /** - * The parent node for the XML signature. - */ - private Node parent; - - /** - * The next sibling node for the XML signature. - */ - private Node nextSibling; - - /** - * Creates a new SignatureLocation with the given signatureContext - * - * @param signatureContext the context for the XML signature creation - */ - public SignatureLocation(SignatureContext signatureContext) { - this.ctx = signatureContext; - } - - /** - * @return the parent node for the XML signature - */ - public Node getParent() { - return parent; - } - - /** - * @param parent the parent for the XML signature - */ - public void setParent(Node parent) { - this.parent = parent; - } - - /** - * @return the next sibling node for the XML signature - */ - public Node getNextSibling() { - return nextSibling; - } - - /** - * @param nextSibling the next sibling node for the XML signature - */ - public void setNextSibling(Node nextSibling) { - this.nextSibling = nextSibling; - } - - /** - * Configures this SignatureLocation with the information provided by the - * given SignatureInfo element. - * - * @param signatureInfo - * the SignatureInfo element - * - * @throws SLCommandException - * if configuring this SignatureLocation with given - * signatureInfofails - */ - public void setSignatureInfo(SignatureInfoCreationType signatureInfo) - throws SLCommandException { - - // evaluate signature location XPath ... - SignatureLocationType signatureLocation = (SignatureLocationType) signatureInfo - .getSignatureLocation(); - - NamespaceContext namespaceContext = new MOAIDWorkaroundNamespaceContext( - signatureLocation.getNamespaceContext()); - - parent = evaluateSignatureLocation(signatureInfo.getSignatureLocation() - .getValue(), namespaceContext, ctx.getDocument().getDocumentElement()); - - // ... and index - nextSibling = findNextSibling(parent, signatureInfo.getSignatureLocation() - .getIndex().intValue()); - - } - - /** - * Evaluates the given xpath with the document element as context node - * and returns the resulting node. - * - * @param xpath the XPath expression - * @param nsContext the namespace context of the XPath expression - * @param contextNode the context node for the XPath evaluation - * - * @return the result of evaluating the XPath expression - * - * @throws SLCommandException - */ - private Node evaluateSignatureLocation(String xpath, NamespaceContext nsContext, Node contextNode) throws SLCommandException { - - Node node = null; - try { - XPathFactory xpathFactory = XPathFactory.newInstance(); - XPath xPath = xpathFactory.newXPath(); - xPath.setNamespaceContext(nsContext); - XPathExpression xpathExpr = xPath.compile(xpath); - node = (Node) xpathExpr.evaluate(contextNode, XPathConstants.NODE); - } catch (XPathExpressionException e) { - log.info("Failed to evaluate SignatureLocation XPath expression '" + xpath + "' on context node.", e); - throw new SLCommandException(4102); - } - - if (node == null) { - log.info("Failed to evaluate SignatureLocation XPath expression '" + xpath + "'. Result is empty."); - throw new SLCommandException(4102); - } - - return node; - - } - - /** - * Finds the next sibling node of the parent's n-th child node - * or null if there is no next sibling. - * - * @param parent the parent node - * @param n the index of the child node - * - * @return the next sibling node of the node specified by parent and index n, - * or null if there is no next sibling node. - * - * @throws SLCommandException if the n-th child of parent does not exist - */ - private Node findNextSibling(Node parent, int n) throws SLCommandException { - return parent.getChildNodes().item(n); - } - - /** - * Workaround for a missing namespace prefix declaration in MOA-ID. - * - * @author mcentner - */ - private class MOAIDWorkaroundNamespaceContext implements NamespaceContext { - - private NamespaceContext namespaceContext; - - public MOAIDWorkaroundNamespaceContext(NamespaceContext namespaceContext) { - super(); - this.namespaceContext = namespaceContext; - } - - @Override - public String getNamespaceURI(String prefix) { - - String namespaceURI = namespaceContext.getNamespaceURI(prefix); - - if ((namespaceURI == null || XMLConstants.NULL_NS_URI.equals(namespaceURI)) && "saml".equals(prefix)) { - namespaceURI = "urn:oasis:names:tc:SAML:1.0:assertion"; - log.debug("Namespace prefix '" + prefix + "' resolved to '" + namespaceURI + "' (MOA-ID Workaround)."); - } else { - log.trace("Namespace prefix '" + prefix + "' resolved to '" + namespaceURI + "'."); - } - - return namespaceURI; - } - - @Override - public String getPrefix(String namespaceURI) { - return namespaceContext.getPrefix(namespaceURI); - } - - @SuppressWarnings("unchecked") - @Override - public Iterator getPrefixes(String namespaceURI) { - return namespaceContext.getPrefixes(namespaceURI); - } - - } - -} +package at.gv.egiz.bku.slcommands.impl.xsect; + +import java.util.Iterator; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Node; + +import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType; +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.slbinding.impl.SignatureLocationType; + +/** + * This class implements the SignatureLocation of an XML-Signature + * to be created by the security layer command CreateXMLSignature. + * + * @author mcentner + */ +public class SignatureLocation { + + /** + * Logging facility. + */ + private final Logger log = LoggerFactory.getLogger(SignatureLocation.class); + + /** + * The SignatureContext for the XML signature + */ + private SignatureContext ctx; + + /** + * The parent node for the XML signature. + */ + private Node parent; + + /** + * The next sibling node for the XML signature. + */ + private Node nextSibling; + + /** + * Creates a new SignatureLocation with the given signatureContext + * + * @param signatureContext the context for the XML signature creation + */ + public SignatureLocation(SignatureContext signatureContext) { + this.ctx = signatureContext; + } + + /** + * @return the parent node for the XML signature + */ + public Node getParent() { + return parent; + } + + /** + * @param parent the parent for the XML signature + */ + public void setParent(Node parent) { + this.parent = parent; + } + + /** + * @return the next sibling node for the XML signature + */ + public Node getNextSibling() { + return nextSibling; + } + + /** + * @param nextSibling the next sibling node for the XML signature + */ + public void setNextSibling(Node nextSibling) { + this.nextSibling = nextSibling; + } + + /** + * Configures this SignatureLocation with the information provided by the + * given SignatureInfo element. + * + * @param signatureInfo + * the SignatureInfo element + * + * @throws SLCommandException + * if configuring this SignatureLocation with given + * signatureInfofails + */ + public void setSignatureInfo(SignatureInfoCreationType signatureInfo) + throws SLCommandException { + + // evaluate signature location XPath ... + SignatureLocationType signatureLocation = (SignatureLocationType) signatureInfo + .getSignatureLocation(); + + NamespaceContext namespaceContext = new MOAIDWorkaroundNamespaceContext( + signatureLocation.getNamespaceContext()); + + parent = evaluateSignatureLocation(signatureInfo.getSignatureLocation() + .getValue(), namespaceContext, ctx.getDocument().getDocumentElement()); + + // ... and index + nextSibling = findNextSibling(parent, signatureInfo.getSignatureLocation() + .getIndex().intValue()); + + } + + /** + * Evaluates the given xpath with the document element as context node + * and returns the resulting node. + * + * @param xpath the XPath expression + * @param nsContext the namespace context of the XPath expression + * @param contextNode the context node for the XPath evaluation + * + * @return the result of evaluating the XPath expression + * + * @throws SLCommandException + */ + private Node evaluateSignatureLocation(String xpath, NamespaceContext nsContext, Node contextNode) throws SLCommandException { + + Node node = null; + try { + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xPath = xpathFactory.newXPath(); + xPath.setNamespaceContext(nsContext); + XPathExpression xpathExpr = xPath.compile(xpath); + node = (Node) xpathExpr.evaluate(contextNode, XPathConstants.NODE); + } catch (XPathExpressionException e) { + log.info("Failed to evaluate SignatureLocation XPath expression '{}' on context node.", xpath, e); + throw new SLCommandException(4102); + } + + if (node == null) { + log.info("Failed to evaluate SignatureLocation XPath expression '{}'. Result is empty.", xpath); + throw new SLCommandException(4102); + } + + return node; + + } + + /** + * Finds the next sibling node of the parent's n-th child node + * or null if there is no next sibling. + * + * @param parent the parent node + * @param n the index of the child node + * + * @return the next sibling node of the node specified by parent and index n, + * or null if there is no next sibling node. + * + * @throws SLCommandException if the n-th child of parent does not exist + */ + private Node findNextSibling(Node parent, int n) throws SLCommandException { + return parent.getChildNodes().item(n); + } + + /** + * Workaround for a missing namespace prefix declaration in MOA-ID. + * + * @author mcentner + */ + private class MOAIDWorkaroundNamespaceContext implements NamespaceContext { + + private NamespaceContext namespaceContext; + + public MOAIDWorkaroundNamespaceContext(NamespaceContext namespaceContext) { + super(); + this.namespaceContext = namespaceContext; + } + + @Override + public String getNamespaceURI(String prefix) { + + String namespaceURI = namespaceContext.getNamespaceURI(prefix); + + if ((namespaceURI == null || XMLConstants.NULL_NS_URI.equals(namespaceURI)) && "saml".equals(prefix)) { + namespaceURI = "urn:oasis:names:tc:SAML:1.0:assertion"; + log.debug("Namespace prefix '{}' resolved to '{}' (MOA-ID Workaround).", prefix, namespaceURI); + } else { + log.trace("Namespace prefix '{}' resolved to '{}'.", prefix, namespaceURI); + } + + return namespaceURI; + } + + @Override + public String getPrefix(String namespaceURI) { + return namespaceContext.getPrefix(namespaceURI); + } + + @SuppressWarnings("unchecked") + @Override + public Iterator getPrefixes(String namespaceURI) { + return namespaceContext.getPrefixes(namespaceURI); + } + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java index c94937be..5ae728b3 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java @@ -30,8 +30,7 @@ import javax.xml.crypto.URIReferenceException; import javax.xml.crypto.XMLCryptoContext; import at.gv.egiz.bku.utils.urldereferencer.StreamData; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; /** * An URIDereferencer implementation that uses an {@link URLDereferencer} to @@ -44,17 +43,17 @@ public class URIDereferncerAdapter implements URIDereferencer { /** * The context for dereferencing. */ - protected URLDereferencerContext urlDereferencerContext; + protected URLDereferencer dereferencer; /** * Creates a new URIDereferencerAdapter instance with the given * urlDereferencerContext. * - * @param urlDereferencerContext the context to be used for dereferencing + * @param urlDereferencer the context to be used for dereferencing */ - public URIDereferncerAdapter(URLDereferencerContext urlDereferencerContext) { + public URIDereferncerAdapter(URLDereferencer urlDereferencer) { super(); - this.urlDereferencerContext = urlDereferencerContext; + this.dereferencer = urlDereferencer; } /* (non-Javadoc) @@ -78,10 +77,9 @@ public class URIDereferncerAdapter implements URIDereferencer { if (uri.isAbsolute()) { - URLDereferencer dereferencer = URLDereferencer.getInstance(); StreamData streamData; try { - streamData = dereferencer.dereference(uriString, urlDereferencerContext); + streamData = dereferencer.dereference(uriString); } catch (IOException e) { throw new URIReferenceException(e.getMessage(), e); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java index 3f1732ba..eff9aec5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java @@ -21,6 +21,8 @@ package at.gv.egiz.bku.slexceptions; */ public class SLBindingException extends SLException { + private static final long serialVersionUID = 1L; + public SLBindingException(int errorCode) { super(errorCode); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java index 8136a093..801526dc 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java @@ -19,6 +19,8 @@ package at.gv.egiz.bku.slexceptions; public class SLCanceledException extends at.gv.egiz.bku.slexceptions.SLException { + private static final long serialVersionUID = 1L; + public SLCanceledException(int errorCode, String msg, Object[] args) { super(errorCode, msg, args); // TODO Auto-generated constructor stub diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java index 4b541deb..854c1658 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java @@ -82,7 +82,14 @@ public class SLException extends Exception { return localizedMessage; + } + + /* (non-Javadoc) + * @see java.lang.Throwable#getMessage() + */ + @Override + public String getMessage() { + return getLocalizedMessage(); } - } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java index 548732e6..fd02cff7 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java @@ -18,6 +18,8 @@ package at.gv.egiz.bku.slexceptions; public class SLRequestException extends SLException { + private static final long serialVersionUID = 1L; + public SLRequestException(int errorCode) { super(errorCode); // TODO Auto-generated constructor stub diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java index d09ca418..aa8cd5b5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java @@ -18,6 +18,8 @@ package at.gv.egiz.bku.slexceptions; public class SLRuntimeException extends RuntimeException { + private static final long serialVersionUID = 1L; + public SLRuntimeException(String message, Throwable cause) { super(message, cause); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java index 853328d5..1bfad289 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java @@ -18,6 +18,8 @@ package at.gv.egiz.bku.slexceptions; public class SLViewerException extends SLException { + private static final long serialVersionUID = 1L; + public SLViewerException(int errorCode) { super(errorCode); } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java new file mode 100644 index 00000000..c2f64994 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurableHostnameVerifier.java @@ -0,0 +1,77 @@ +/* +* Copyright 2009 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.spring; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; + +import org.apache.commons.configuration.Configuration; + +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; + +public class ConfigurableHostnameVerifier implements HostnameVerifier { + + /** + * The configuration facade. + */ + protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade implements MoccaConfigurationFacade { + + private Configuration configuration; + + public static final String SSL_DISSABLE_HOSTNAME_VERIFICATION = "SSL.disableHostnameVerification"; + + public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks"; + + public boolean disableSslHostnameVerification() { + return configuration.getBoolean(SSL_DISSABLE_HOSTNAME_VERIFICATION, false); + } + + public boolean disableAllSslChecks() { + return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false); + } + + } + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configurationFacade.configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + configurationFacade.configuration = configuration; + } + + + @Override + public boolean verify(String hostname, SSLSession session) { + if (configurationFacade.disableAllSslChecks() || configurationFacade.disableSslHostnameVerification()) { + return true; + } else { + return HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session); + } + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java new file mode 100644 index 00000000..a6a7c346 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/ConfigurationFactoryBean.java @@ -0,0 +1,172 @@ +/* +* Copyright 2009 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.spring; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.MapConfiguration; +import org.apache.commons.configuration.XMLConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +import at.gv.egiz.bku.slcommands.impl.CreateXMLSignatureCommandImpl; + +/** + * This is a {@link FactoryBean} for the creation of a {@link Configuration}. + * + * @author mcentner + */ +public class ConfigurationFactoryBean implements FactoryBean, ResourceLoaderAware { + + protected static final Logger log = LoggerFactory.getLogger(ConfigurationFactoryBean.class); + + public static final String DEFAULT_CONFIG = "/WEB-INF/conf/configuration.xml"; + + public static final String MOCCA_IMPLEMENTATIONNAME_PROPERTY = "ProductName"; + + public static final String MOCCA_IMPLEMENTATIONVERSION_PROPERTY = "ProductVersion"; + + public static final String SIGNATURE_LAYOUT_PROPERTY = "SignatureLayout"; + + /** + * The URL of the configuration file. + */ + protected Resource configurationResource; + + /** + * The ResourceLoader. + */ + protected ResourceLoader resourceLoader; + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + /** + * @return the configurationURL + */ + public Resource getConfigurationResource() { + return configurationResource; + } + + /** + * @param configurationResource the configurationURL to set + */ + public void setConfigurationResource(Resource configurationResource) { + this.configurationResource = configurationResource; + } + + protected Configuration getDefaultConfiguration() + throws ConfigurationException, IOException { + Resource resource = resourceLoader.getResource(DEFAULT_CONFIG); + XMLConfiguration xmlConfiguration = new XMLConfiguration(); + xmlConfiguration.load(resource.getInputStream()); + xmlConfiguration.setURL(resource.getURL()); + return xmlConfiguration; + } + + protected Configuration getVersionConfiguration() throws IOException { + + Map map = new HashMap(); + map.put(MOCCA_IMPLEMENTATIONNAME_PROPERTY, "MOCCA"); + + // implementation version + String version = null; + try { + Resource resource = resourceLoader.getResource("META-INF/MANIFEST.MF"); + Manifest properties = new Manifest(resource.getInputStream()); + Attributes attributes = properties.getMainAttributes(); + // TODO: replace by Implementation-Version ? + version = attributes.getValue("Implementation-Build"); + } catch (Exception e) { + log.warn("Failed to get implemenation version from manifest. {}", e.getMessage()); + } + + if (version == null) { + version="UNKNOWN"; + } + map.put(MOCCA_IMPLEMENTATIONVERSION_PROPERTY, version); + + // signature layout + try { + String classContainer = CreateXMLSignatureCommandImpl.class.getProtectionDomain() + .getCodeSource().getLocation().toString(); + URL manifestUrl = new URL("jar:" + classContainer + + "!/META-INF/MANIFEST.MF"); + Manifest manifest = new Manifest(manifestUrl.openStream()); + Attributes attributes = manifest.getMainAttributes(); + String signatureLayout = attributes.getValue("SignatureLayout"); + if (signatureLayout != null) { + map.put(SIGNATURE_LAYOUT_PROPERTY, signatureLayout); + } + } catch (Exception e) { + log.warn("Failed to get signature layout from manifest.", e); + } + + + return new MapConfiguration(map); + + } + + @Override + public Object getObject() throws Exception { + + log.info("Configuration resource is {}.", configurationResource); + + CompositeConfiguration configuration; + if (configurationResource == null) { + // initialize default configuration + log.warn("Initializing with default configuration."); + configuration = new CompositeConfiguration(); + } else { + // initialize with writable configuration + URL url = configurationResource.getURL(); + XMLConfiguration writableConfiguration = new XMLConfiguration(url); + configuration = new CompositeConfiguration(writableConfiguration); + log.info("Initialized with configuration from '{}'.", url); + } + configuration.addConfiguration(getDefaultConfiguration()); + configuration.addConfiguration(getVersionConfiguration()); + return configuration; + } + + @Override + public Class getObjectType() { + return Configuration.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java new file mode 100644 index 00000000..97a0d872 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java @@ -0,0 +1,235 @@ +/* +* Copyright 2009 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.spring; + +import iaik.logging.LogConfigurationException; +import iaik.logging.LoggerConfig; +import iaik.logging.impl.TransactionIdImpl; +import iaik.pki.DefaultPKIConfiguration; +import iaik.pki.DefaultPKIProfile; +import iaik.pki.PKIException; +import iaik.pki.PKIFactory; +import iaik.pki.PKIProfile; +import iaik.pki.revocation.RevocationSourceTypes; +import iaik.pki.store.certstore.CertStoreParameters; +import iaik.pki.store.certstore.directory.DefaultDirectoryCertStoreParameters; +import iaik.pki.store.truststore.DefaultTrustStoreProfile; +import iaik.pki.store.truststore.TrustStoreProfile; +import iaik.pki.store.truststore.TrustStoreTypes; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Properties; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.FileConfiguration; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +import at.gv.egiz.bku.conf.IAIKLogAdapterFactory; +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; + +public class PKIProfileFactoryBean implements FactoryBean, ResourceLoaderAware { + + /** + * The configuration facade. + */ + protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade implements MoccaConfigurationFacade { + + private Configuration configuration; + + public static final String SSL_CERT_DIRECTORY = "SSL.certDirectory"; + + public static final String SSL_CERT_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/certStore"; + + public static final String SSL_CA_DIRECTORY = "SSL.caDirectory"; + + public static final String SSL_CA_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/trustStore"; + + public URL getCertDirectory() throws MalformedURLException { + return getURL(SSL_CERT_DIRECTORY); + } + + public URL getCaDirectory() throws MalformedURLException { + return getURL(SSL_CA_DIRECTORY); + } + + private URL getURL(String key) throws MalformedURLException { + String url = configuration.getString(key); + if (url == null || url.isEmpty()) { + return null; + } + return new URL(getBasePath(key), configuration.getString(key)); + } + + private URL getBasePath(String key) { + Configuration configuration = this.configuration; + if (configuration instanceof CompositeConfiguration) { + CompositeConfiguration compositeConfiguration = (CompositeConfiguration) configuration; + for (int i = 0; i < compositeConfiguration.getNumberOfConfigurations(); i++) { + if (compositeConfiguration.getConfiguration(i).containsKey(key)) { + configuration = compositeConfiguration.getConfiguration(i); + break; + } + } + } + if (configuration instanceof FileConfiguration) { + return ((FileConfiguration) configuration).getURL(); + } + return null; + } + + } + + + private ResourceLoader resourceLoader; + + protected String trustProfileId; + + @Override + public void setResourceLoader(ResourceLoader loader) { + this.resourceLoader = loader; + } + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configurationFacade.configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + configurationFacade.configuration = configuration; + } + + /** + * @return the trustProfileId + */ + public String getTrustProfileId() { + return trustProfileId; + } + + /** + * @param trustProfileId the trustProfileId to set + */ + public void setTrustProfileId(String trustProfileId) { + this.trustProfileId = trustProfileId; + } + + protected File getDirectory(String url) throws IOException { + Resource resource = resourceLoader.getResource(url); + File path = resource.getFile(); + if (!path.exists() && !path.isDirectory()) { + throw new IOException("URL '" + url + "' is not a directory."); + } + return path; + } + + protected void configureIAIKLogging() { + // initialize IAIK logging for PKI module + iaik.logging.LogFactory.configure(new LoggerConfig() { + + @Override + public Properties getProperties() throws LogConfigurationException { + return null; + } + + @Override + public String getNodeId() { + return "pki"; + } + + @Override + public String getFactory() { + return IAIKLogAdapterFactory.class.getName(); + } + }); + } + + protected void configurePkiFactory() throws MalformedURLException, PKIException, IOException { + + URL url = configurationFacade.getCertDirectory(); + File certDirectory = (url != null) + ? getDirectory(url.toString()) + : getDirectory(ConfigurationFacade.SSL_CERT_DIRECTORY_DEFAULT); + + CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters( + "CS", certDirectory.getAbsolutePath(), true, false) }; + + DefaultPKIConfiguration pkiConfiguration = new DefaultPKIConfiguration(certStoreParameters); + + + PKIFactory pkiFactory = PKIFactory.getInstance(); + pkiFactory.configure(pkiConfiguration, new TransactionIdImpl("Configure-PKI")); + } + + protected TrustStoreProfile createDirectoryTrustStoreProfile() throws MalformedURLException, IOException { + + URL url = configurationFacade.getCaDirectory(); + File caDirectory = (url != null) + ? getDirectory(url.toString()) + : getDirectory(ConfigurationFacade.SSL_CA_DIRECTORY_DEFAULT); + + return new DefaultTrustStoreProfile(trustProfileId, + TrustStoreTypes.DIRECTORY, caDirectory.getAbsolutePath()); + + } + + @Override + public Object getObject() throws Exception { + + configureIAIKLogging(); + + PKIFactory pkiFactory = PKIFactory.getInstance(); + + if (!pkiFactory.isAlreadyConfigured()) { + configurePkiFactory(); + } + + TrustStoreProfile trustProfile = createDirectoryTrustStoreProfile(); + + DefaultPKIProfile pkiProfile = new DefaultPKIProfile(trustProfile); + + pkiProfile.setAutoAddCertificates(true); + pkiProfile.setPreferredServiceOrder(new String[] { + RevocationSourceTypes.OCSP, RevocationSourceTypes.CRL }); + + return pkiProfile; + } + + @Override + public Class getObjectType() { + return PKIProfile.class; + } + + @Override + public boolean isSingleton() { + return false; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java new file mode 100644 index 00000000..36fdcd06 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java @@ -0,0 +1,173 @@ +/* +* Copyright 2009 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.spring; + +import iaik.logging.TransactionId; +import iaik.pki.PKIException; +import iaik.pki.PKIFactory; +import iaik.pki.PKIModule; +import iaik.pki.PKIProfile; +import iaik.pki.store.truststore.TrustStore; +import iaik.pki.store.truststore.TrustStoreException; +import iaik.pki.store.truststore.TrustStoreFactory; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Date; + +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.configuration.Configuration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; + +public class PKITrustManager implements X509TrustManager { + + Logger log = LoggerFactory.getLogger(PKITrustManager.class); + + protected PKIProfile pkiProfile; + + /** + * The configuration facade. + */ + protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade implements MoccaConfigurationFacade { + + private Configuration configuration; + + public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks"; + + public boolean disableAllSslChecks() { + return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false); + } + + } + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configurationFacade.configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + configurationFacade.configuration = configuration; + } + + /** + * @return the pkiProfile + */ + public PKIProfile getPkiProfile() { + return pkiProfile; + } + + /** + * @param pkiProfile the pkiProfile to set + */ + public void setPkiProfile(PKIProfile pkiProfile) { + this.pkiProfile = pkiProfile; + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + checkServerTrusted(chain, authType); + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + + if (pkiProfile == null) { + throw new CertificateException("No PKI profile set. Configuration error."); + } + + if (configurationFacade.disableAllSslChecks()) { + log.warn("SSL certificate validation disabled. " + + "Accepted certificate {}.", chain[0].getSubjectDN()); + } else { + + iaik.x509.X509Certificate[] certs = convertCerts(chain); + + TransactionId tid = new MDCTransactionId(); + try { + PKIModule pkiModule = PKIFactory.getInstance().getPKIModule(pkiProfile); + if (!pkiModule.validateCertificate(new Date(), certs[0], certs, null, + tid).isCertificateValid()) { + throw new CertificateException("Certificate not valid."); + } + } catch (PKIException e) { + log.warn("Failed to validate certificate.", e); + throw new CertificateException("Failed to validate certificate. " + e.getMessage()); + } + + } + + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + + if (pkiProfile == null) { + log.warn("No PKI profile set. Configuration error."); + return new X509Certificate[] {}; + } + + TransactionId tid = new MDCTransactionId(); + + try { + + TrustStore trustStore = TrustStoreFactory.getInstance(pkiProfile.getTrustStoreProfile(), tid); + return (X509Certificate[]) trustStore.getTrustedCertificates(tid).toArray(); + + } catch (TrustStoreException e) { + log.warn("Failed to get list of accepted issuers.", e); + return new X509Certificate[] {}; + } + + } + + private static iaik.x509.X509Certificate[] convertCerts( + X509Certificate[] certs) throws CertificateException { + iaik.x509.X509Certificate[] retVal = new iaik.x509.X509Certificate[certs.length]; + int i = 0; + for (X509Certificate cert : certs) { + if (cert instanceof iaik.x509.X509Certificate) { + retVal[i++] = (iaik.x509.X509Certificate) cert; + } else { + retVal[i++] = new iaik.x509.X509Certificate(cert.getEncoded()); + } + } + return retVal; + } + + private static class MDCTransactionId implements TransactionId { + @Override + public String getLogID() { + String sessionId = MDC.get("SessionId"); + return (sessionId != null) ? sessionId : "PKITrustManager"; + } + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java new file mode 100644 index 00000000..f6dbddd6 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SSLSocketFactoryBean.java @@ -0,0 +1,109 @@ +/* +* Copyright 2009 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.spring; + +import iaik.pki.PKIProfile; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + +import org.apache.commons.configuration.Configuration; +import org.springframework.beans.factory.FactoryBean; + +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; + +public class SSLSocketFactoryBean implements FactoryBean { + + protected PKIProfile pkiProfile; + + /** + * The configuration facade. + */ + protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade implements MoccaConfigurationFacade { + + private Configuration configuration; + + public static final String SSL_PROTOCOL = "SSL.sslProtocol"; + + public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks"; + + public String getSslProtocol() { + return configuration.getString(SSL_PROTOCOL, "TLS"); + } + + public boolean disableAllSslChecks() { + return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false); + } + + } + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configurationFacade.configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + configurationFacade.configuration = configuration; + } + + /** + * @return the pkiProfile + */ + public PKIProfile getPkiProfile() { + return pkiProfile; + } + + /** + * @param pkiProfile the pkiProfile to set + */ + public void setPkiProfile(PKIProfile pkiProfile) { + this.pkiProfile = pkiProfile; + } + + @Override + public Object getObject() throws Exception { + + PKITrustManager pkiTrustManager = new PKITrustManager(); + pkiTrustManager.setConfiguration(configurationFacade.configuration); + pkiTrustManager.setPkiProfile(pkiProfile); + + SSLContext sslContext = SSLContext.getInstance(configurationFacade.getSslProtocol()); + sslContext.init(null, new TrustManager[] {pkiTrustManager}, null); + + return sslContext.getSocketFactory(); + } + + @Override + public Class getObjectType() { + return SSLSocketFactory.class; + } + + @Override + public boolean isSingleton() { + return false; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java new file mode 100644 index 00000000..4e9e4d76 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/SecurityManagerFactoryBean.java @@ -0,0 +1,102 @@ +/* +* Copyright 2009 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.spring; + +import org.apache.commons.configuration.Configuration; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +import at.gv.egiz.bku.accesscontroller.SecurityManagerFacade; + +public class SecurityManagerFactoryBean implements ResourceLoaderAware, + FactoryBean { + + protected ResourceLoader resourceLoader; + + protected ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade { + + protected ConfigurationFacade() { + } + + public static final String ACCESSCONTROLLER_POLICYRESOURCE = "AccessController.PolicyResource"; + + public static final String ACCESSCONTROLLER_DEFAULT_POLICYRESOURCE = "classpath:/at/gv/egiz/bku/accesscontrol/config/accessControlConfig.xml"; + + public static final String ACCESSCONTROLLER_ACCEPTNOMATCH = "AccessController.AcceptNoMatch"; + + public static final boolean ACCESSCONTROLLER_DEFAULT_ACCEPTNOMATCH = false; + + protected String getPolicyResource() { + return configuration.getString(ACCESSCONTROLLER_POLICYRESOURCE, ACCESSCONTROLLER_DEFAULT_POLICYRESOURCE); + } + + protected boolean getAcceptNoMatch() { + return configuration.getBoolean(ACCESSCONTROLLER_ACCEPTNOMATCH, ACCESSCONTROLLER_DEFAULT_ACCEPTNOMATCH); + } + + } + + protected Configuration configuration; + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + @Override + public Object getObject() throws Exception { + + SecurityManagerFacade sm = new SecurityManagerFacade(); + sm.setAllowUnmatched(configurationFacade.getAcceptNoMatch()); + + Resource policyResource = resourceLoader.getResource(configurationFacade.getPolicyResource()); + sm.init(policyResource.getInputStream()); + + return sm; + + } + + @Override + public Class getObjectType() { + return SecurityManagerFacade.class; + } + + @Override + public boolean isSingleton() { + return true; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java index 8cab581d..91dfc9da 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ResourceFontLoader.java @@ -19,8 +19,8 @@ package at.gv.egiz.bku.viewer; import at.gv.egiz.bku.gui.viewer.FontProviderException; import at.gv.egiz.bku.gui.viewer.FontProvider; import java.awt.Font; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Loads font(s) as classpath resource. @@ -31,7 +31,7 @@ public class ResourceFontLoader implements FontProvider { public static final String FONT_RESOURCE = "DejaVuLGCSansMono.ttf"; - protected final static Log log = LogFactory.getLog(ResourceFontLoader.class); + private final Logger log = LoggerFactory.getLogger(ResourceFontLoader.class); /** TextValidator and (local) SecureViewerDialog (see LocalStalFactory) use ResourceFontLoader, load resource only once */ protected static Font font; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java index ad9bf6bb..c5a90a61 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/viewer/ValidatorFactory.java @@ -26,15 +26,15 @@ import java.util.Iterator; import java.util.List; import java.util.Properties; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ValidatorFactory { /** * Logging facility. */ - protected static Log log = LogFactory.getLog(ValidatorFactory.class); + private final Logger log = LoggerFactory.getLogger(ValidatorFactory.class); private static final Class VALIDATOR_CLASS = Validator.class; @@ -93,7 +93,7 @@ public class ValidatorFactory { try { properties.load(url.openStream()); } catch (IOException e) { - log.error("Failed to load service properties " + url.toExternalForm()); + log.error("Failed to load service properties {}.", url.toExternalForm()); continue; } String className = properties.getProperty(mimeType); @@ -124,22 +124,22 @@ public class ValidatorFactory { return (Validator) implConstructor.newInstance((Object[])null); } catch (InvocationTargetException ex) { //ex from constructor - log.error("Failed to initialize validator class '" + className + "': " + ex.getCause().getMessage(), ex.getCause()); + log.error("Failed to initialize validator class '{}'.", className, ex.getCause()); throw ex; } catch (NoSuchMethodException ex) { - log.error("Validator class '" + className + "' has no nullary constructor", ex); + log.error("Validator class '{}' has no nullary constructor.", className, ex); throw ex; } catch (ClassNotFoundException e) { - log.error("Validator class '" + className + "' not found.", e); + log.error("Validator class '{}' not found.", className, e); throw e; } catch (InstantiationException e) { - log.error("Faild to initialize validator class '" + className + "'.", e); + log.error("Faild to initialize validator class '{}'.", className, e); throw e; } catch (IllegalAccessException e) { - log.error("Faild to initialize validator class '" + className + "'.", e); + log.error("Faild to initialize validator class '{}'.", className, e); throw e; } catch (ClassCastException e) { - log.error("Class '" + className + "' is not a validator implementation.", e); + log.error("Class '{}' is not a validator implementation.", className, e); throw e; } @@ -168,7 +168,7 @@ public class ValidatorFactory { }; } catch (IOException e) { - log.error("Failed to enumerate resources " + SERVICE_ID); + log.error("Failed to enumerate resources {}.", SERVICE_ID); List list = Collections.emptyList(); return list.iterator(); } -- cgit v1.2.3