diff options
| author | mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2010-05-05 15:29:01 +0000 | 
|---|---|---|
| committer | mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2010-05-05 15:29:01 +0000 | 
| commit | b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd (patch) | |
| tree | 0883f08a408f89f758e9a1be629232e3dd055c3a /bkucommon/src/main/java/at | |
| parent | 83a9b613836910f7edc370c2fe60fa2268dc4461 (diff) | |
| download | mocca-b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd.tar.gz mocca-b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd.tar.bz2 mocca-b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd.zip | |
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
Diffstat (limited to 'bkucommon/src/main/java/at')
117 files changed, 6100 insertions, 4934 deletions
| 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<String, ChainChecker> chainTable = new Hashtable<String, ChainChecker>();
 -
 -	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<Chain> 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<Rule> 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<String, ChainChecker> chainTable = new Hashtable<String, ChainChecker>(); + +	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<Chain> 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<Rule> 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<List<?>> sanList = cert.getSubjectAlternativeNames();
 -			if (sanList != null) {
 -				for (List<?> san : sanList) {
 -					log.trace("Analyzing subj. alt name: " + san);
 -					if ((Integer) san.get(0) == 2) {
 -						String dns = (String) san.get(1);
 -						if (dns.endsWith(GOV_DOMAIN)) {
 -							return true;
 -						}
 -					}
 -				}
 -			}
 -		} catch (CertificateParsingException e) {
 -			log.error(e);
 -		}
 -		if ((cert.getExtensionValue("1.2.40.0.10.1.1.1") != null)
 -        || (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<List<?>> sanList = cert.getSubjectAlternativeNames(); +			if (sanList != null) { +				for (List<?> san : sanList) { +					log.trace("Analyzing subj. alt name: " + san); +					if ((Integer) san.get(0) == 2) { +						String dns = (String) san.get(1); +						if (dns.endsWith(GOV_DOMAIN)) { +							return true; +						} +					} +				} +			} +		} catch (CertificateParsingException e) { +			log.error("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<RuleChecker> rules = new LinkedList<RuleChecker>();
 -	
 -	/**
 -	 * 
 -	 * @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<RuleChecker> 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<RuleChecker> rules = new LinkedList<RuleChecker>(); +	 +	/** +	 *  +	 * @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<RuleChecker> 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<String, String> 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<String, String> 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<Protocol> supportedProtocols; +  protected SLCommandFactory slCommandFactory; +  protected Configuration configuration; +  protected URLDereferencer urlDereferencer; + +  @Override +  public Set<Protocol> 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 +   * <code>inputStream</code>. +   * <p> +   * Implementing classes are assumed to read the entire provided +   * <code>inputStream</code> +   * </p> +   * <p> +   * Any errors are reported via the result produced by this BindingProcessor. +   * </p>     *  -   * 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 <code>null</code>     */ -  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 <code>null</code> 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 <code>null</code> if not yet +   *         assigned.     */    public STAL getSTAL(); +  /** +   * Returns the CommandInvoker used for processing. +   *  +   * @return the CommandInvoker used for processing or <code>null</code> if not +   *         yet assigned. +   */    public SLCommandInvoker getCommandInvoker(); -  public Date getLastAccessTime(); -   -  public void updateLastAccessTime(); -   +  /** +   * Returns the <code>ContentType</code> of the processing result. +   *  +   * @return the <code>ContentType</code> type of the processing result or +   *         <code>null</code> 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 <code>outputStream</code> using +   * the given character <code>encoding</code>. +   *  +   * @param outputStream +   *          the OutputStream to write the result to +   * @param encoding +   *          the character encoding to be used +   * @throws IOException +   *           if writing to <code>outputStream</code> 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<Protocol> 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<Object> { + +  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 <code>BindingProcessorManager</code> provides factory methods for creating + * <code>BindingProcessor</code>s 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 <code>protocol</code>.     *  -   * @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 +   *          <code>null</code>     */ -  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 <code>protocol</code>.     *  -   * @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 <code>id</code>. +   *  +   * @param id +   *          the processing id of the requested BindingProcessor +   *  +   * @return the BindingProcessor which has been scheduled for processing with +   *         the given <code>id</code>, or <code>null</code> if no +   *         BindingProcessor has been scheduled with the given <code>id</code>.     */ -  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. +   * <p> +   * <ol> +   * <li>Creates a processing context with the given <code>id</code>.</li> +   * <li>Schedules the given BindingProcessor for processing, and</li> +   * <li>Immediately returns the processing context.</li> +   * </ol> +   * </p> +   *  +   * @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 <code>Id</code>s of currently managed BindingProcessor.     *  -   * @param aBindingProcessor +   * @return the set of <code>Id</code>s of currently managed BindingProcessor.     */ -  public ProcessingContext process(BindingProcessor aBindingProcessor); -   +  public Set<Id> 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<Id> 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<BindingProcessorFactory> 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<Id, ProcessingContext> contextMap = Collections.synchronizedMap(new HashMap<Id, ProcessingContext>()); -//  private Map<Id, MapEntityWrapper> bindingProcessorMap = Collections -//      .synchronizedMap(new HashMap<Id, MapEntityWrapper>()); +  private ExecutorService executorService = Executors.newCachedThreadPool(); +  private Map<Id, BindingProcessorFuture> submittedFutures = Collections +      .synchronizedMap(new HashMap<Id, BindingProcessorFuture>()); +   +  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<BindingProcessorFactory> 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<BindingProcessorFactory> 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<MapEntityWrapper> 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<Id> getManagedIds() { +    return Collections.unmodifiableSet(new HashSet<Id>(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<Id> getManagedIds() { -    Set<Id> result = new HashSet<Id>(); -    synchronized (contextMap) { -      for (Id id : contextMap.keySet()) { -        result.add(id); +   +  public class CleanUpTask implements Runnable { +     +    @Override +    public void run() { +      Collection<BindingProcessorFuture> futures = submittedFutures.values(); +      List<Id> toBeRemoved = new ArrayList<Id>(); +      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<Id> 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 <em>citizen-card-environment/1.2 BKU2 1.0</em>. - * The form-parameter ResponseType is set to <em>HTTP-Security-Layer-RESPONSE</em>. - * 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 + * <em>citizen-card-environment/1.2 BKU2 1.0</em>. The form-parameter + * ResponseType is set to <em>HTTP-Security-Layer-RESPONSE</em>. 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 <code>SLResult</code> to the resource identified by this +   * URL. +   *  +   * @param slResult the <code>SLResult</code> +   * @throws IOException if an I/O exception occurs +   */ +  public abstract void transmit(SLResult slResult) throws IOException; -    public DataUrlResponse getResponse() throws IOException; +  /** +   * Returns the <code>DataUrlResponse</code> 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 <code>application/x-www-form-urlencoded</code> instead of -   * standard conform <code>application/x-www-form-urlencoded</code>. +   * Use <code>application/x-www-form-urlencoded</code> instead of standard +   * conform <code>application/x-www-form-urlencoded</code>.     */    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<String, String> requestHttpHeaders; -   +    /**     * The HTTP form parameters.     */ -  protected ArrayList<HTTPFormParameter> httpFormParameter; -   +  protected List<HTTPFormParameter> httpFormParameter = new ArrayList<HTTPFormParameter>(); +    /**     * 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<String> headers = requestHttpHeaders.keySet(); -    Iterator<String> 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<String, String> responseHttpHeaders = new HashMap<String, String>();      Map<String, List<String>> 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<String, String>(); -     -    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<HTTPFormParameter>(); - -  } - -  @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<Id> managedIds = bindingProcessorManager.getManagedIds();
 -    for (Iterator<Id> 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/RemovalStrategy.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java index 6c2dcb9f..a248e683 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormDataURLSupplier.java @@ -16,11 +16,12 @@  */  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);
 +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<String> 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<String, String> headerMap = Collections.EMPTY_MAP; -	protected SLCommand slCommand; -	protected Map<String, FormParameter> formParameterMap = new HashMap<String, FormParameter>(); -	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<String, String> 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<STALRequest> quit = new ArrayList<STALRequest>(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<FormParameter> getFormParameters(String parameterNamePostfix) { -		List<FormParameter> resultList = new ArrayList<FormParameter>(); -		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi -				.hasNext();) { -			String paramName = fpi.next(); -			if (paramName.endsWith(parameterNamePostfix)) { -				resultList.add(formParameterMap.get(paramName)); -			} -		} -		return resultList; -	} - -	protected List<FormParameter> getTransferHeaders() { -		return getFormParameters("__"); -	} - -	protected List<FormParameter> getTransferForms() { -		List<FormParameter> resultList = new ArrayList<FormParameter>(); -		for (Iterator<String> 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<String> 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 <ok/> 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 != <ok/>"); -						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<String, String> aHeaderMap) { -		headerMap = new HashMap<String, String>(); -		// 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<FormParameter> 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<String> 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("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"); -      writer.write("<?xml-stylesheet type=\"text/css\" href=\"errorresponse.css\"?>\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<String, String> 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<String, String> 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<String, String> 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<Protocol> sp = new HashSet<Protocol>(); +    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<String> 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 <code>Server</code> and +   * <code>UserAgent</code> 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<String, String> headerMap = Collections.EMPTY_MAP; +	protected SLCommand slCommand; +	protected Map<String, FormParameter> formParameterMap = new HashMap<String, FormParameter>(); +	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<String, String> 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<STALRequest> quit = new ArrayList<STALRequest>(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<FormParameter> getFormParameters(String parameterNamePostfix) { +		List<FormParameter> resultList = new ArrayList<FormParameter>(); +		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi +				.hasNext();) { +			String paramName = fpi.next(); +			if (paramName.endsWith(parameterNamePostfix)) { +				resultList.add(formParameterMap.get(paramName)); +			} +		} +		return resultList; +	} + +	protected List<FormParameter> getTransferHeaders() { +		return getFormParameters("__"); +	} + +	protected List<FormParameter> getTransferForms() { +		List<FormParameter> resultList = new ArrayList<FormParameter>(); +		for (Iterator<String> 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<String> 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 <ok/> 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 != <ok/>"); +						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<String, String> aHeaderMap) { +		headerMap = new HashMap<String, String>(); +		// 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<FormParameter> 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<String> 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("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"); +      writer.write("<?xml-stylesheet type=\"text/css\" href=\"errorresponse.css\"?>\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<String, String> getResponseHeaders() { +	  LinkedHashMap<String, String> headers = new LinkedHashMap<String, String>(); +	  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 <code>null</code>) +   * @param charSet +   *          the character set (may be <code>null</code>) +   * @param transferEncoding +   *          the transfer encoding (may be <code>null</code>) +   */ +  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 <code>SSLSocketFactory</code> 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 <code>HostnameVerifier</code> 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<String, Class<? extends InputDecoder>> decoderMap = new HashMap<String, Class<? extends InputDecoder>>();
 -
 -  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<? extends InputDecoder> 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<? extends InputDecoder> 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<String, Class<? extends InputDecoder>> decoderMap = new HashMap<String, Class<? extends InputDecoder>>(); + +  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<? extends InputDecoder> 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<? extends InputDecoder> 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<FormParameter> 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<FormParameter> {
 -
 -    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<FormParameter> 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<FormParameter> { + +    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 <clemens.orthacker@iaik.tugraz.at> - */ -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<String, Object> properties = new Hashtable<String, Object>(); - -  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/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<FormParameter> {            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 <clemens.orthacker@iaik.tugraz.at> - */ -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<X509Certificate> caCerts = new ArrayList<X509Certificate>();
 -    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<CertStore> getCertstore() throws IOException,
 -      CertificateException, InvalidAlgorithmParameterException,
 -      NoSuchAlgorithmException {
 -    List<CertStore> resultList = new ArrayList<CertStore>();
 -    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<X509Certificate> certCollection = new LinkedList<X509Certificate>();
 -      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<Service> 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/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/IAIKCommonsLog.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java index 1b7dd189..b04509a0 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKLogAdapter.java @@ -3,6 +3,8 @@   */  package at.gv.egiz.bku.conf; +import org.slf4j.Logger; +  import iaik.logging.Log;  import iaik.logging.TransactionId; @@ -10,19 +12,19 @@ import iaik.logging.TransactionId;   * @author mcentner   *   */ -public class IAIKCommonsLog implements Log { +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 org.apache.commons.logging.Log commonsLog; +  protected Logger log;    protected String nodeId; -  public IAIKCommonsLog(org.apache.commons.logging.Log log) { -    this.commonsLog = log; +  public IAIKLogAdapter(Logger logger) { +    this.log = logger;    }    /* (non-Javadoc) @@ -30,8 +32,8 @@ public class IAIKCommonsLog implements Log {     */    @Override    public void debug(TransactionId transactionId, Object message, Throwable t) { -    if (commonsLog.isDebugEnabled()) { -      commonsLog.debug(nodeId + ": " +    if (log.isDebugEnabled()) { +      log.debug(nodeId + ": "            + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "            + message, t);      } @@ -42,8 +44,8 @@ public class IAIKCommonsLog implements Log {     */    @Override    public void info(TransactionId transactionId, Object message, Throwable t) { -    if (commonsLog.isInfoEnabled()) { -      commonsLog.info(nodeId + ": " +    if (log.isInfoEnabled()) { +      log.info(nodeId + ": "            + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "            + message, t);      } @@ -54,8 +56,8 @@ public class IAIKCommonsLog implements Log {     */    @Override    public void warn(TransactionId transactionId, Object message, Throwable t) { -    if (commonsLog.isWarnEnabled()) { -      commonsLog.warn(nodeId + ": " +    if (log.isWarnEnabled()) { +      log.warn(nodeId + ": "            + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "            + message, t);      } @@ -66,8 +68,8 @@ public class IAIKCommonsLog implements Log {     */    @Override    public void error(TransactionId transactionId, Object message, Throwable t) { -    if (commonsLog.isErrorEnabled()) { -      commonsLog.error(nodeId + ": " +    if (log.isErrorEnabled()) { +      log.error(nodeId + ": "            + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "            + message, t);      } @@ -78,8 +80,8 @@ public class IAIKCommonsLog implements Log {     */    @Override    public void fatal(TransactionId transactionId, Object message, Throwable t) { -    if (commonsLog.isFatalEnabled()) { -      commonsLog.fatal(nodeId + ": " +    if (log.isErrorEnabled()) { +      log.error(nodeId + ": "            + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "            + message, t);      } @@ -106,7 +108,7 @@ public class IAIKCommonsLog implements Log {     */    @Override    public boolean isDebugEnabled() { -    return commonsLog.isDebugEnabled(); +    return log.isDebugEnabled();    }    /* (non-Javadoc) @@ -114,7 +116,7 @@ public class IAIKCommonsLog implements Log {     */    @Override    public boolean isInfoEnabled() { -    return commonsLog.isInfoEnabled(); +    return log.isInfoEnabled();    }    /* (non-Javadoc) @@ -122,7 +124,7 @@ public class IAIKCommonsLog implements Log {     */    @Override    public boolean isWarnEnabled() { -    return commonsLog.isWarnEnabled(); +    return log.isWarnEnabled();    }    /* (non-Javadoc) @@ -130,7 +132,7 @@ public class IAIKCommonsLog implements Log {     */    @Override    public boolean isErrorEnabled() { -    return commonsLog.isErrorEnabled(); +    return log.isErrorEnabled();    }    /* (non-Javadoc) @@ -138,7 +140,7 @@ public class IAIKCommonsLog implements Log {     */    @Override    public boolean isFatalEnabled() { -    return commonsLog.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<Logger, Log> instances = new WeakHashMap<Logger, Log>(); +   +  /* (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 <namespaceURI>:<localName> to implementation class of the -     * corresponding {@link SLCommand}. -     */ -    private Map<String, Class<? extends SLCommand>> slRequestTypeMap = new HashMap<String, Class<? extends SLCommand>>(); -     -    /** -     * Configures the singleton instance with command implementations -     * @param commandImplMap -     * @throws ClassNotFoundException  -     */ -    @SuppressWarnings("unchecked") -    public void setCommandImpl(Map<String, String> commandImplMap) throws ClassNotFoundException { -      ClassLoader cl = getClass().getClassLoader(); -      for (String key : commandImplMap.keySet()) { -        Class<? extends SLCommand> impl =  (Class<? extends SLCommand>) 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<QName, AbstractSLCommandFactory> slCommandFactories = new HashMap<QName, AbstractSLCommandFactory>(); + +  public void setConcreteFactories( +      Map<QName, AbstractSLCommandFactory> 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 <code>namespaceUri</code> and <code>localname</code> -     * . -     *  -     * @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 <code>null</code> to deregister a -     *          currently registered class -     */ -    public  void setImplClass(String namespaceUri, String localname, -      Class<? extends SLCommand> 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 -     * <code>name</code>, or <code>null</code> if no such class is registered. -     *  -     * @param name -     *          the <code>QName</code> of the Security Layer command -     * @return the implementation class, or <code>null</code> if no class is -     *         registered for the given <code>name</code> -     */ -    public Class<? extends SLCommand> 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 <code>SLCommandFactory</code>. +   */ +  public synchronized static SLCommandFactory getInstance() { +    return SLCommandFactoryInstance.INSTANCE; +  } + +  /** +   * Private constructor used by {@link #getInstance()}. +   */ +  private SLCommandFactory() { +    super(); +  } + +  /** +   * Creates a new <code>SLCommand</code> from the given <code>source</code> and +   * <code>context</code>. +   *  +   * @param source +   *          the <code>Source</code> to unmarshall from +   * @return the <code>SLCommand</code> unmarshalled from the given +   *         <code>source</code> +   * @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 <code>SLCommand</code> 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 <code>SLCommandFactory</code>. -     */ -    public synchronized static SLCommandFactory getInstance() { -        if (instance == null) { -          instance = new SLCommandFactory(); -          instance.ensureJaxbContext(); -          instance.ensureSchema(); -        } -        return instance; +    return createSLCommand((JAXBElement<?>) object); + +  } + +  /** +   * Creates a new <code>SLCommand</code> from the given <code>element</code> +   * and <code>context</code>. +   *  +   * @param element +   *          the request element +   * @return the <code>SLCommand</code> for for the given <code>element</code> +   * @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 <code>source</code>. -     *  -     * @see Unmarshaller#unmarshal(Source) -     *  -     * <em>Note:</em>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 <code>source</code>. +   *  +   * @see Unmarshaller#unmarshal(Source) +   *  +   *      <em>Note:</em>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 <code>SLCommand</code> from the given <code>source</code> and -     * <code>context</code>. -     *  -     * @param source -     *          the <code>Source</code> to unmarshall from -     * @param context -     *          the context for the created <code>SLCommand</code> -     * @return the <code>SLCommand</code> unmarshalled from the given -     *         <code>source</code> -     * @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 <code>SLCommand</code> 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<? extends SLCommand> 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<String> 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<T> extends SLCommandImpl<T> {     * 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<STAL, JAXBElement<ResponseType>> scriptResults = new WeakHashMap<STAL, JAXBElement<ResponseType>>(); @@ -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<X509Certificate> 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,12 +40,12 @@ 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. @@ -52,6 +53,11 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl {    protected Document doc;    /** +   * The content of the CreateXMLSignatureResponse. +   */ +  protected Element content; +   +  /**     * Creates a new instance of this CreateXMLSignatureResultImpl with the given     * signature <code>document</code>.     *  @@ -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<CreateXMLSignatureResponseType> 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<Node> getXMLContent(Node node) { +    ArrayList<Node> content = new ArrayList<Node>(); +    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<GetStatusRequestType> 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<GetStatusRequestType> 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<STALResponse> responses = stal.handleRequest(Collections.singletonList(stalRequest)); @@ -62,16 +62,16 @@ public class GetStatusCommandImpl extends SLCommandImpl<GetStatusRequestType> 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 <code>IdentityLinkDomainIdentifier</code>.     */    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 <code>IdentityLinkDomainIdentifier</code>.     */ @@ -147,7 +164,6 @@ public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox {      JAXBElement<CompressedIdentityLinkType> 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<String, Class<? extends Infobox>> 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<String, String> infoboxImplMap) throws ClassNotFoundException { -    HashMap<String, Class<? extends Infobox>> implMap = new HashMap<String, Class<? extends Infobox>>(); -    ClassLoader cl = getClass().getClassLoader(); -    for (String key : infoboxImplMap.keySet()) { -      Class<? extends Infobox> impl = (Class<? extends Infobox>) cl.loadClass(infoboxImplMap.get(key)); -      log.debug("Registering infobox '" + key + "' implementation '" + impl.getCanonicalName() + "'."); -      implMap.put(key, impl); -    } -    implementations = implMap; -  } - +  private HashMap<String, AbstractInfoboxFactory> infoboxFactories = new HashMap<String, AbstractInfoboxFactory>(); +      /** -   * Returns the configured implementation class for the given -   * <code>infoboxIdentifier</code>. -   *  -   * @param infoboxIdentifier -   *          the infobox identifier -   *  -   * @return the implementation class for the given infobox identifier or -   *         <code>null</code> if there is no implementation class configured +   * @param infoboxFactories the infoboxFactories to set     */ -  public Class<? extends Infobox> getImplClass(String infoboxIdentifier) { -    if (implementations != null) { -      return implementations.get(infoboxIdentifier); -    } else { -      return null; +  public void setInfoboxFactories( +      HashMap<String, AbstractInfoboxFactory> 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<? extends Infobox> 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
 - * <code>InfoboxReadRequest</code>.
 - * <p>
 - * <b>NOTE:</b> Currently the only supported infobox identifier is '
 - * <code>IdentityLink</code>'.
 - * </p>
 - * 
 - * @author mcentner
 - */
 -public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxReadRequestType> implements
 -    InfoboxReadCommand {
 -  
 -  /**
 -   * Logging facility.
 -   */
 -  protected static Log log = LogFactory.getLog(InfoboxReadCommandImpl.class); + +/** + * This class implements the security layer command + * <code>InfoboxReadRequest</code>. + * <p> + * <b>NOTE:</b> Currently the only supported infobox identifier is ' + * <code>IdentityLink</code>'. + * </p> + *  + * @author mcentner + */ +public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxReadRequestType> 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 AbstractInfoboxCommandImpl<InfoboxRe        log.info("Got BinaryFileParameters but Infobox type is not BinaryFile.");        throw new SLCommandException(4010);      } -    
 -  }
 -
 -  @Override
 -  public SLResult execute() { +     +  } + +  @Override +  public SLResult execute(SLCommandContext commandContext) {      try { -      return infobox.read(getRequestValue(), getCmdCtx()); +      return infobox.read(getRequestValue(), commandContext);      } catch (SLCommandException e) { -      return new ErrorResultImpl(e, getCmdCtx().getLocale()); +      return new ErrorResultImpl(e, commandContext.getLocale());      } -  }
 -
 +  } +    @Override    public String getIdentityLinkDomainId() {      if (infobox instanceof IdentityLinkInfoboxImpl) { @@ -93,4 +93,4 @@ public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxRe      }    } -}
 +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java index 422b424f..ddbbcadc 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java @@ -16,6 +16,9 @@  */  package at.gv.egiz.bku.slcommands.impl; +import java.util.ArrayList; +import java.util.Collections; +  import javax.xml.bind.JAXBElement;  import javax.xml.bind.JAXBException;  import javax.xml.bind.Marshaller; @@ -25,8 +28,8 @@ import javax.xml.transform.Result;  import javax.xml.transform.Templates;  import javax.xml.transform.dom.DOMResult; -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;  import org.w3c.dom.NodeList; @@ -51,12 +54,17 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements    /**     * Logging facility.     */ -  protected static Log log = LogFactory.getLog(InfoboxReadResultFileImpl.class); +  protected final Logger log = LoggerFactory.getLogger(InfoboxReadResultFileImpl.class);    /**     * The XML document containing the infobox content.     */    protected Document xmlDocument; +   +  /** +   * Binary content of the infobox (may be <code>null</code>).  +   */ +  protected byte[] binaryContent;    /**     * Creates the response document from the given <code>binaryContent</code>. @@ -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<Node> content = new ArrayList<Node>(); +        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<InfoboxUpdateRequestType> 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<NullOperationRequest    protected static NullOperationResult RESULT = new NullOperationResultImpl();    @Override -  public SLResult execute() { +  public SLResult execute(SLCommandContext commandContext) {      return RESULT;    } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java index ed055b69..41783c34 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java @@ -19,7 +19,6 @@ package at.gv.egiz.bku.slcommands.impl;  import javax.xml.bind.JAXBElement;  import at.gv.egiz.bku.slcommands.SLCommand; -import at.gv.egiz.bku.slcommands.SLCommandContext;  import at.gv.egiz.bku.slexceptions.SLCommandException;  /**
 @@ -34,30 +33,15 @@ import at.gv.egiz.bku.slexceptions.SLCommandException;  public abstract class SLCommandImpl<T> implements SLCommand {
    /**
 -   * The <code>SLCommandContext</code> for this <code>SLCommand</code>.
 -   */
 -  protected SLCommandContext cmdCtx; -   -  /** -   * The STAL helper. -   */ -  protected STALHelper stalHelper;
 -
 -  /**
     * The request element of this command.
     */
    protected JAXBElement<T> request;
    @SuppressWarnings("unchecked")
    @Override
 -  public void init(SLCommandContext ctx, Object request)
 +  public void init(Object request)
        throws SLCommandException {
 -
      this.request = (JAXBElement<T>) request;
 -
 -    this.cmdCtx = ctx; -    stalHelper = new STALHelper(cmdCtx.getSTAL());
 -
    }
    /**
 @@ -70,12 +54,13 @@ public abstract class SLCommandImpl<T> implements SLCommand {     */
    protected T getRequestValue() {
      return request.getValue();
 -  }
 +  } + +  /** +   * @return the request +   */ +  public JAXBElement<T> getRequest() { +    return request; +  } -  /**
 -   * @return the corresponding <code>SLCommandContext</code>
 -   */
 -  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<? extends STALRequest> stalRequests) throws SLCommandException {      List<STALResponse> 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 <code>DataObject</code> 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 = "<AssureDSigNS>".getBytes(); -//      post = "</AssureDSigNS>".getBytes(); -//    } else { -//      log.trace("XMLDSig bound to prefix " + dsigPrefix); -//       pre = ("<AssureDSigNS xmlns:" + dsigPrefix + "=\"http://www.w3.org/2000/09/xmldsig#\">").getBytes(); -//       post = "</AssureDSigNS>".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<InputStream> inputStreams = new ArrayList<InputStream>(); -    try { -      // dummy start element -      inputStreams.add(new ByteArrayInputStream("<dummy>".getBytes("UTF-8"))); -   -      // content -      inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray())); -       -      // dummy end element -      inputStreams.add(new ByteArrayInputStream("</dummy>".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<InputStream> inputStreams = new ArrayList<InputStream>(); +      try { +        // dummy start element +        inputStreams.add(new ByteArrayInputStream("<dummy>".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("</dummy>".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<at.buergerkarte.namespaces.securitylayer._1.XMLContentType> element =  +        new JAXBElement<at.buergerkarte.namespaces.securitylayer._1.XMLContentType>( +          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 <code>LocRef</code>
 - * references.
 - * 
 - * @author mcentner
 - */
 -public class LocRefDereferencer implements URIDereferencer {
 -
 -  /**
 -   * Logging facility.
 -   */
 -  private static Log log = LogFactory.getLog(LocRefDereferencer.class);
 -
 -  /**
 -   * The <code>LocRef</code>-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
 -   * <code>dereferencerContext</code> and <code>locRef</code> reference.
 -   * 
 -   * @param dereferencerContext
 -   *          the context to be used for dereferencing
 -   * @param locRef
 -   *          the <code>LocRef</code>-reference (must be an absolute URI)
 -   * 
 -   * @throws URISyntaxException
 -   *           if <code>LocRef</code> 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 <code>LocRef</code> + * references. + *  + * @author mcentner + */ +public class LocRefDereferencer implements URIDereferencer { + +  /** +   * Logging facility. +   */ +  private final Logger log = LoggerFactory.getLogger(LocRefDereferencer.class); + +  /** +   * The <code>LocRef</code>-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 +   * <code>dereferencerContext</code> and <code>locRef</code> reference. +   *  +   * @param dereferencer +   *          the context to be used for dereferencing +   * @param locRef +   *          the <code>LocRef</code>-reference (must be an absolute URI) +   *  +   * @throws URISyntaxException +   *           if <code>LocRef</code> 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<String, String> map = new HashMap<String, String>();
 -
 -    // 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<Void>() {
 -      @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<DataObject> dataObjects = privateKey.getDataObjects(); -//    log.debug("got " + dataObjects.size() + " DataObjects, passing HashDataInputs to STAL SignRequest"); -     -    List<HashDataInput> hashDataInputs = new ArrayList<HashDataInput>(); -    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<STALResponse> 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 <code>STALSignatureMethod</code> +   * with the given <code>algorithm</code> and <code>params</code>. +   *  +   * @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 <code>algorithm</code> is <code>null</code>   +   */ +  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<DataObject> dataObjects = ((STALPrivateKey) key).getDataObjects(); +     +    List<HashDataInput> hashDataInputs = new ArrayList<HashDataInput>(); +    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<STALResponse> 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<String> 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
 @@ -99,31 +99,31 @@ public class SignatureContext {    }
    /**
 -   * @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 <code>SignatureLocation</code> of an XML-Signature
 - * to be created by the security layer command <code>CreateXMLSignature</code>.
 - * 
 - * @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 <code>signatureContext</code>
 -   * 
 -   * @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 <code>SignatureInfo</code> element.
 -   * 
 -   * @param signatureInfo
 -   *          the <code>SignatureInfo</code> element
 -   * 
 -   * @throws SLCommandException
 -   *           if configuring this SignatureLocation with given
 -   *           <code>signatureInfo</code>fails
 -   */
 -  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 <code>xpath</code> 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 <code>parent</code>'s <code>n</code>-th child node
 -   * or <code>null</code> 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 <code>parent</code> and index <code>n</code>,
 -   * or <code>null</code> if there is no next sibling node.
 -   * 
 -   * @throws SLCommandException if the <code>n</code>-th child of <code>parent</code> 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 <code>SignatureLocation</code> of an XML-Signature + * to be created by the security layer command <code>CreateXMLSignature</code>. + *  + * @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 <code>signatureContext</code> +   *  +   * @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 <code>SignatureInfo</code> element. +   *  +   * @param signatureInfo +   *          the <code>SignatureInfo</code> element +   *  +   * @throws SLCommandException +   *           if configuring this SignatureLocation with given +   *           <code>signatureInfo</code>fails +   */ +  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 <code>xpath</code> 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 <code>parent</code>'s <code>n</code>-th child node +   * or <code>null</code> 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 <code>parent</code> and index <code>n</code>, +   * or <code>null</code> if there is no next sibling node. +   *  +   * @throws SLCommandException if the <code>n</code>-th child of <code>parent</code> 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
     * <code>urlDereferencerContext</code>.
     * 
 -   * @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<String, String> map = new HashMap<String, String>(); +    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> 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<URL> list = Collections.emptyList();         return list.iterator();      } | 
