summaryrefslogtreecommitdiff
path: root/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller
diff options
context:
space:
mode:
Diffstat (limited to 'bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller')
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessChecker.java23
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessCheckerContext.java43
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java153
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/Action.java35
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClass.java37
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java110
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java91
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainResult.java49
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java68
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java74
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java203
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleResult.java32
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java118
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/UserAction.java36
14 files changed, 1072 insertions, 0 deletions
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessChecker.java
new file mode 100644
index 00000000..d930c74e
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessChecker.java
@@ -0,0 +1,23 @@
+/*
+* 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 at.gv.egiz.bku.slexceptions.SLException;
+
+public interface AccessChecker {
+ public ChainResult check(AccessCheckerContext checkCtx) throws SLException;
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessCheckerContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessCheckerContext.java
new file mode 100644
index 00000000..60935678
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessCheckerContext.java
@@ -0,0 +1,43 @@
+/*
+* 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 at.gv.egiz.bku.slcommands.SLCommand;
+
+public class AccessCheckerContext {
+ private SLCommand command;
+ private AuthenticationClass authenticationClass;
+ private String peerUrl;
+
+ public AccessCheckerContext(SLCommand cmd, AuthenticationClass ac, String url) {
+ this.command = cmd;
+ this.authenticationClass = ac;
+ this.peerUrl = url;
+ }
+
+ public SLCommand getCommand() {
+ return command;
+ }
+
+ public AuthenticationClass getAuthenticationClass() {
+ return authenticationClass;
+ }
+
+ public String getPeerUrl() {
+ return peerUrl;
+ }
+}
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
new file mode 100644
index 00000000..19fec084
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java
@@ -0,0 +1,153 @@
+/*
+* 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());
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/Action.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/Action.java
new file mode 100644
index 00000000..f3d15ad6
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/Action.java
@@ -0,0 +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.accesscontroller;
+
+public enum Action {
+ ALLOW("allow"), DENY("deny");
+ private String name;
+
+ Action(String name) {
+ this.name = name;
+ }
+
+ public static Action fromString(String s) {
+ for (Action ac : values()) {
+ if (ac.name.equals(s)) {
+ return ac;
+ }
+ }
+ return null;
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClass.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClass.java
new file mode 100644
index 00000000..3c442a6d
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClass.java
@@ -0,0 +1,37 @@
+/*
+* 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;
+
+public enum AuthenticationClass {
+ ANONYMOUS("anonymous"), PSEUDO_ANONYMOUS("pseudoanonymous"), CERTIFIED(
+ "certified"), CERTIFIED_GOV_AGENCY("certifiedGovAgency");
+
+ private String name;
+
+ AuthenticationClass(String name) {
+ this.name = name;
+ }
+
+ public static AuthenticationClass fromString(String s) {
+ for (AuthenticationClass ac : values()) {
+ if (ac.name.equals(s)) {
+ return ac;
+ }
+ }
+ return null;
+ }
+}
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
new file mode 100644
index 00000000..61d3d7a5
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java
@@ -0,0 +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);
+ }
+}
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
new file mode 100644
index 00000000..716f81e4
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java
@@ -0,0 +1,91 @@
+/*
+* 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);
+ }
+
+
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainResult.java
new file mode 100644
index 00000000..a5547cab
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainResult.java
@@ -0,0 +1,49 @@
+/*
+* 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;
+
+/**
+ * Result of the access controller
+ *
+ */
+public class ChainResult {
+ private UserAction userAction;
+ private Action action;
+ private boolean matchFound;
+
+ public ChainResult(Action action, UserAction userAction, boolean matchFound) {
+ this.action = action;
+ this.userAction = userAction;
+ this.matchFound = matchFound;
+ }
+
+ public Action getAction() {
+ return action;
+ }
+
+ public UserAction getUserAction() {
+ return userAction;
+ }
+
+ /**
+ *
+ * @return true if a matching rule has been found
+ */
+ public boolean matchFound() {
+ return matchFound;
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java
new file mode 100644
index 00000000..003eb2f7
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java
@@ -0,0 +1,68 @@
+/*
+* 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.LinkedList;
+import java.util.List;
+
+import at.gv.egiz.bku.slcommands.SLCommand;
+
+public abstract class CommandParamChecker {
+
+ protected List<Tupel<String, String>> paramList = new LinkedList<Tupel<String, String>>();
+
+ public static class Tupel<T, Q> {
+ private T key;
+ private Q val;
+
+ public Tupel(T key, Q val) {
+ if ((key == null) || (val == null)) {
+ throw new NullPointerException("Tupel key and value must not be null");
+ }
+ this.key = key;
+ this.val = val;
+ }
+
+ public T getKey() {
+ return key;
+ }
+
+ public Q getVal() {
+ return val;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean equals(Object other) {
+ if (other instanceof Tupel) {
+ Tupel ot = (Tupel) other;
+ return (key.equals(ot.key) && val.equals(ot.val));
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return key.hashCode();
+ }
+ }
+
+ public void addParameter(String key, String value) {
+ paramList.add(new Tupel<String, String>(key, value));
+ }
+
+ public abstract boolean checkParameter(SLCommand cmd);
+
+}
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
new file mode 100644
index 00000000..8fa328de
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java
@@ -0,0 +1,74 @@
+/*
+* 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());
+ }
+ }
+}
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
new file mode 100644
index 00000000..1cba89ef
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java
@@ -0,0 +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;
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleResult.java
new file mode 100644
index 00000000..706615c2
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleResult.java
@@ -0,0 +1,32 @@
+/*
+* 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;
+
+
+public class RuleResult extends ChainResult {
+ private String chainId;
+
+ public RuleResult(Action action, UserAction userAction, boolean matchFound, String chainId) {
+ super(action, userAction, matchFound);
+ this.chainId = chainId;
+ }
+
+ public String getDelegateChainId() {
+ 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
new file mode 100644
index 00000000..482d3ecb
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java
@@ -0,0 +1,118 @@
+/*
+* 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);
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/UserAction.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/UserAction.java
new file mode 100644
index 00000000..c1f7028b
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/UserAction.java
@@ -0,0 +1,36 @@
+/*
+* 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;
+
+public enum UserAction {
+ NONE("none"), INFO("info"), CONFIRM("confirm"), CONFIRM_WITH_SECRET("confirmWithSecret");
+
+ private String name;
+
+ UserAction(String name) {
+ this.name = name;
+ }
+
+ public static UserAction fromString(String s) {
+ for (UserAction ac : values()) {
+ if (ac.name.equals(s)) {
+ return ac;
+ }
+ }
+ return null;
+ }
+}