diff options
Diffstat (limited to 'bkucommon/src/main/java/at/gv')
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(); } |