From e0f2c64ad6360e2ecec983cb5e0a60f812672106 Mon Sep 17 00:00:00 2001 From: wbauer Date: Thu, 4 Sep 2008 14:56:54 +0000 Subject: finished access controller, accessed it from command invoker and configured everything within onlinebku git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@14 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../accesscontroller/AccessControllerFactory.java | 76 ++++++++++----- .../gv/egiz/bku/accesscontroller/ChainChecker.java | 6 +- .../bku/accesscontroller/CommandParamChecker.java | 52 +++++++++++ .../bku/accesscontroller/InfoboxParamChecker.java | 58 ++++++++++++ .../bku/accesscontroller/InfoboxRuleChecker.java | 14 --- .../gv/egiz/bku/accesscontroller/RuleChecker.java | 72 +++++++++++---- .../accesscontroller/SecurityManagerFacade.java | 102 +++++++++++++++++++++ 7 files changed, 325 insertions(+), 55 deletions(-) create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxRuleChecker.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java (limited to 'bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller') 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 3b75a5f2..cd837cd7 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 @@ -15,8 +15,9 @@ 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.slcommands.impl.InfoboxReadCommandImpl; +import at.gv.egiz.bku.accesscontroller.RuleChecker.PEER_TYPE; import at.gv.egiz.bku.slexceptions.SLRuntimeException; public class AccessControllerFactory { @@ -24,6 +25,8 @@ 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 { @@ -63,43 +66,72 @@ public class AccessControllerFactory { 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) { - if ((cmd.getParam() != null) && (cmd.getParam().size()>0)) { - if (cmd.getName().startsWith("Infobox")) { - rc = new InfoboxRuleChecker(rule.getId()); - } else { - throw new SLRuntimeException("Cannot handle parameters for command "+cmd.getName()); - } - } else { - rc = new RuleChecker(rule.getId()); + rc.setCommandName(cmd.getName()); + for (Param p : cmd.getParam()) { + rc.addParameter(p.getName(), p.getValue()); } - } else { - rc = new RuleChecker(rule.getId()); } - // FIXME TODO cont. here - - - return rc; + rc.setAuthenticationClass(rule.getAuthClass()); + if (rule.getIPv4Address() != null) { + rc.setPeerId(rule.getIPv4Address(), PEER_TYPE.IP); + } else if (rule.getDomainName() != null) { + rc.setPeerId(rule.getDomainName(), PEER_TYPE.HOST); + } else if (rule.getURL() != null) { + rc.setPeerId(rule.getURL(), PEER_TYPE.URL); + } + rc.setAction(rule.getAction().getRuleAction()); + rc.setChainId(rule.getAction().getChainRef()); + rc.setUserAction(rule.getUserInteraction()); + return rc; } - - + public void init(InputStream is) throws JAXBException { + chainTable.clear(); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); AccessControl ac = (AccessControl) unmarshaller.unmarshal(is); List chainList = ac.getChains().getChain(); - log.debug("Found "+chainList.size()+" chains in config"); + log.debug("Found " + chainList.size() + " chains in config"); for (Chain chain : chainList) { + log.trace("Creating chain: " + chain.getId()); + ChainChecker cc = createChainChecker(chain.getId(), false); List ruleList = chain.getRules().getRule(); - log.debug("Found "+ruleList.size()+" rules in chain "+chain.getId()); + log + .debug("Found " + ruleList.size() + " rules in chain " + + chain.getId()); for (Rule rule : ruleList) { - //rule.g + 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/ChainChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java index 242d9b02..a290fe8d 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,5 +1,6 @@ package at.gv.egiz.bku.accesscontroller; +import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -35,6 +36,10 @@ public class ChainChecker implements AccessChecker { rules.add(rule); } } + + public List getRules() { + return Collections.unmodifiableList(rules); + } @Override public ChainResult check(AccessCheckerContext checkCtx) throws SLException { @@ -43,7 +48,6 @@ public class ChainChecker implements AccessChecker { log.trace("Checking rule: "+rule.getId()); RuleResult result = rule.check(checkCtx); if (result.matchFound()) { - log.debug("Found matching rule: "+rule.getId()); if (result.getDelegateChainId() != null) { // process chain ChainChecker cc = AccessControllerFactory.getInstance().getChainChecker(result.getDelegateChainId()); 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..3927c3c9 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java @@ -0,0 +1,52 @@ +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> paramList = new LinkedList>(); + + public static class Tupel { + 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(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..33689ae0 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java @@ -0,0 +1,58 @@ +package at.gv.egiz.bku.accesscontroller; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.slcommands.InfoboxReadCommand; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; + +public class InfoboxParamChecker extends CommandParamChecker { + private static Log log = LogFactory.getLog(InfoboxParamChecker.class); + + public final static String INFOBOX_ID = "InfoboxIdentifier"; + public final static String PERSON_ID = "PersonIdentifier"; + public final static String DERIVED = "derived"; + + @Override + public boolean checkParameter(SLCommand cmd) { + if (paramList.size() == 0) { + return true; + } + + if (cmd instanceof InfoboxReadCommand) { + InfoboxReadCommand irc = (InfoboxReadCommand) cmd; + for (Tupel param : paramList) { + if (param.getKey().equals(INFOBOX_ID)) { + if (!param.getVal().equals(irc.getInfoboxIdentifier())) { + return false; + } + } else if (param.getKey().equals(PERSON_ID)) { + if (param.getVal().equals(DERIVED)) { + if (irc.getIdentityLinkDomainId() == null) { + return false; + } + } else { + Pattern p = Pattern.compile(param.getVal()); + Matcher m = p.matcher(irc.getIdentityLinkDomainId()); + if (!m.matches()) { + return false; + } + } + + } else { + throw new SLRuntimeException("Cannot handle parameter " + + param.getKey()); + } + } + return true; + } else { + log.error("Cannot handle parameter for command: " + cmd.getName()); + throw new SLRuntimeException("Cannot handle parameters for command: " + + cmd.getName()); + } + } +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxRuleChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxRuleChecker.java deleted file mode 100644 index 2981d24e..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxRuleChecker.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.gv.egiz.bku.accesscontroller; - -/** - * Adds infobox parameter checks - * @author wbauer - * - */ -public class InfoboxRuleChecker extends RuleChecker { - - public InfoboxRuleChecker(String id) { - super(id); - } - -} 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 c59f5b70..b0bf7fac 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 @@ -31,6 +31,7 @@ public class RuleChecker implements AccessChecker { protected Action action; protected UserAction userAction; protected String chainId; + protected CommandParamChecker paramChecker; public RuleChecker(String id) { if (id == null) { @@ -40,27 +41,33 @@ public class RuleChecker implements AccessChecker { } public void setAuthenticationClass(String ac) { - AuthenticationClass tmp = AuthenticationClass.fromString(ac); - if (tmp == null) { - throw new SLRuntimeException("Unknown authentication class " + ac); + if (ac != null) { + AuthenticationClass tmp = AuthenticationClass.fromString(ac); + if (tmp == null) { + throw new SLRuntimeException("Unknown authentication class " + ac); + } + authenticationClass = tmp; } - authenticationClass = tmp; } public void setAction(String ac) { - Action tmp = Action.fromString(ac); - if (tmp == null) { - throw new SLRuntimeException("Unknown action " + ac); + if (ac != null) { + Action tmp = Action.fromString(ac); + if (tmp == null) { + throw new SLRuntimeException("Unknown action " + ac); + } + action = tmp; } - action = tmp; } public void setUserAction(String uac) { - UserAction tmp = UserAction.fromString(uac); - if (tmp == null) { - throw new SLRuntimeException("Unknown user action " + uac); + if (uac != null) { + UserAction tmp = UserAction.fromString(uac); + if (tmp == null) { + throw new SLRuntimeException("Unknown user action " + uac); + } + userAction = tmp; } - userAction = tmp; } public void setChainId(String chainId) { @@ -76,6 +83,22 @@ public class RuleChecker implements AccessChecker { 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() { @@ -83,22 +106,30 @@ public class RuleChecker implements AccessChecker { } protected boolean matchAuthenticationClass(AuthenticationClass cls) { - if (this.authenticationClass == null) { + if ((this.authenticationClass == null) || (cls == null)) { return true; } return this.authenticationClass.compareTo(cls) <= 0; } protected boolean matchCommandName(SLCommand cmd) { - if (commandName == null) { + if ((commandName == null) || (cmd == null)) { return true; } Matcher matcher = commandNamePattern.matcher(cmd.getName()); - return matcher.matches(); + if (matcher.matches()) { + if (paramChecker != null) { + return paramChecker.checkParameter(cmd); + } else { + return true; + } + } else { + return false; + } } protected boolean matchPeerId(String peerUrl) { - if (peerId == null) { + if ((peerId == null) || (peerUrl == null)) { return true; } if (peerType == PEER_TYPE.URL) { @@ -110,7 +141,8 @@ public class RuleChecker implements AccessChecker { if (peerType == PEER_TYPE.HOST) { try { String host = url.getHost(); - String hostName = InetAddress.getByName(host).getCanonicalHostName(); + String hostName = InetAddress.getByName(host) + .getCanonicalHostName(); Matcher matcher = peerIdPattern.matcher(hostName); return matcher.matches(); } catch (UnknownHostException e) { @@ -143,9 +175,13 @@ public class RuleChecker implements AccessChecker { && 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 new file mode 100644 index 00000000..32242772 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java @@ -0,0 +1,102 @@ +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); + } +} -- cgit v1.2.3