Repository: karaf
Updated Branches:
  refs/heads/KARAF-5427 [created] 103f33105


[KARAF-5427] Add RBAC support for reflection invocation and redirections in the 
console


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/103f3310
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/103f3310
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/103f3310

Branch: refs/heads/KARAF-5427
Commit: 103f33105a58c899706a0687bb334678e2fa1ee7
Parents: 066d28a
Author: Guillaume Nodet <[email protected]>
Authored: Mon Oct 16 15:59:45 2017 +0200
Committer: Guillaume Nodet <[email protected]>
Committed: Mon Oct 16 15:59:45 2017 +0200

----------------------------------------------------------------------
 pom.xml                                         |  4 +-
 .../shell/impl/console/SessionFactoryImpl.java  | 22 +++++++++-
 .../console/osgi/secured/SecuredCommand.java    |  2 +-
 .../osgi/secured/SecuredSessionFactoryImpl.java | 42 ++++++++++++++------
 4 files changed, 54 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/103f3310/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2e7778b..d0cced3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -192,8 +192,8 @@
         <felix.fileinstall.version>3.6.2</felix.fileinstall.version>
         <felix.framework.version>5.6.8</felix.framework.version>
         
<felix.framework.security.version>2.6.0</felix.framework.security.version>
-        <felix.gogo.runtime.version>1.0.8</felix.gogo.runtime.version>
-        <felix.gogo.jline.version>1.0.8</felix.gogo.jline.version>
+        <felix.gogo.runtime.version>1.0.9-SNAPSHOT</felix.gogo.runtime.version>
+        <felix.gogo.jline.version>1.0.9-SNAPSHOT</felix.gogo.jline.version>
         <felix.httplite.version>0.1.6</felix.httplite.version>
         <felix.inventory.version>1.0.4</felix.inventory.version>
         <felix.plugin.version>3.3.0</felix.plugin.version>

http://git-wip-us.apache.org/repos/asf/karaf/blob/103f3310/shell/core/src/main/java/org/apache/karaf/shell/impl/console/SessionFactoryImpl.java
----------------------------------------------------------------------
diff --git 
a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/SessionFactoryImpl.java
 
b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/SessionFactoryImpl.java
index d351753..13e27ac 100644
--- 
a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/SessionFactoryImpl.java
+++ 
b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/SessionFactoryImpl.java
@@ -20,6 +20,7 @@ package org.apache.karaf.shell.impl.console;
 
 import java.io.InputStream;
 import java.io.PrintStream;
+import java.nio.file.Path;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -29,6 +30,7 @@ import org.apache.felix.gogo.jline.Builtin;
 import org.apache.felix.gogo.jline.Posix;
 import org.apache.felix.gogo.jline.Procedural;
 import org.apache.felix.gogo.runtime.CommandProcessorImpl;
+import org.apache.felix.gogo.runtime.CommandSessionImpl;
 import org.apache.felix.gogo.runtime.Reflective;
 import org.apache.felix.service.command.CommandSession;
 import org.apache.felix.service.command.Function;
@@ -54,7 +56,17 @@ public class SessionFactoryImpl extends RegistryImpl 
implements SessionFactory,
     public SessionFactoryImpl(ThreadIO threadIO) {
         super(null);
         this.threadIO = threadIO;
-        commandProcessor = new CommandProcessorImpl(threadIO);
+        commandProcessor = new CommandProcessorImpl(threadIO) {
+            @Override
+            public Object invoke(CommandSessionImpl session, Object target, 
String name, List<Object> args) throws Exception {
+                return SessionFactoryImpl.this.invoke(session, target, name, 
args);
+            }
+
+            @Override
+            public Path redirect(CommandSessionImpl session, Path path, int 
mode) {
+                return SessionFactoryImpl.this.redirect(session, path, mode);
+            }
+        };
         register(new ExitCommand());
         new HelpCommand(this);
         register(new ShellCommand("addCommand", "Add a command", 
commandProcessor, "addCommand"));
@@ -77,6 +89,14 @@ public class SessionFactoryImpl extends RegistryImpl 
implements SessionFactory,
         }
     }
 
+    protected Object invoke(CommandSessionImpl session, Object target, String 
name, List<Object> args) throws Exception {
+        return Reflective.invoke(session, target, name, args);
+    }
+
+    protected Path redirect(CommandSessionImpl session, Path path, int mode) {
+        return session.currentDir().resolve(path);
+    }
+
     public CommandProcessorImpl getCommandProcessor() {
         return commandProcessor;
     }

http://git-wip-us.apache.org/repos/asf/karaf/blob/103f3310/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java
----------------------------------------------------------------------
diff --git 
a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java
 
b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java
index e6e8ef7..2df6e09 100644
--- 
a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java
+++ 
b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java
@@ -64,7 +64,7 @@ public class SecuredCommand implements Command, Function {
 
     @Override
     public Object execute(Session session, List<Object> arguments) throws 
Exception {
-        factory.checkSecurity(this, session, arguments);
+        factory.checkSecurity(getScope(), getName(), arguments);
         return command.execute(session, arguments);
     }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/103f3310/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java
----------------------------------------------------------------------
diff --git 
a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java
 
b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java
index cf12f18..7fe015c 100644
--- 
a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java
+++ 
b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java
@@ -18,10 +18,12 @@
  */
 package org.apache.karaf.shell.impl.console.osgi.secured;
 
+import java.nio.file.Path;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.Principal;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.List;
@@ -30,12 +32,12 @@ import java.util.Map;
 import javax.security.auth.Subject;
 
 import org.apache.felix.gogo.runtime.CommandNotFoundException;
+import org.apache.felix.gogo.runtime.CommandSessionImpl;
 import org.apache.felix.service.command.Function;
 import org.apache.felix.service.threadio.ThreadIO;
 import org.apache.karaf.jaas.boot.principal.RolePrincipal;
 import org.apache.karaf.service.guard.tools.ACLConfigurationParser;
 import org.apache.karaf.shell.api.console.Command;
-import org.apache.karaf.shell.api.console.Session;
 import org.apache.karaf.shell.impl.console.SessionFactoryImpl;
 import org.apache.karaf.util.tracker.SingleServiceTracker;
 import org.osgi.framework.BundleContext;
@@ -52,8 +54,11 @@ import org.slf4j.LoggerFactory;
 public class SecuredSessionFactoryImpl extends SessionFactoryImpl implements 
ConfigurationListener {
 
     private static final String PROXY_COMMAND_ACL_PID_PREFIX = 
"org.apache.karaf.command.acl.";
-    private static final String CONFIGURATION_FILTER =
-            "(" + Constants.SERVICE_PID + "=" + PROXY_COMMAND_ACL_PID_PREFIX + 
"*)";
+    private static final String CONFIGURATION_FILTER = "(" + 
Constants.SERVICE_PID + "=" + PROXY_COMMAND_ACL_PID_PREFIX + "*)";
+
+    private static final String SHELL_SCOPE = "shell";
+    private static final String SHELL_INVOKE = ".invoke";
+    private static final String SHELL_REDIRECT = ".redirect";
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(SecuredSessionFactoryImpl.class);
 
@@ -77,6 +82,18 @@ public class SecuredSessionFactoryImpl extends 
SessionFactoryImpl implements Con
     }
 
     @Override
+    protected Object invoke(CommandSessionImpl session, Object target, String 
name, List<Object> args) throws Exception {
+        checkSecurity(SHELL_SCOPE, SHELL_INVOKE, Arrays.asList(target, name, 
args));
+        return super.invoke(session, target, name, args);
+    }
+
+    @Override
+    protected Path redirect(CommandSessionImpl session, Path path, int mode) {
+        checkSecurity(SHELL_SCOPE, SHELL_REDIRECT, Arrays.asList(path, mode));
+        return super.redirect(session, path, mode);
+    }
+
+    @Override
     protected Function wrap(Command command) {
         return new SecuredCommand(this, command);
     }
@@ -84,17 +101,18 @@ public class SecuredSessionFactoryImpl extends 
SessionFactoryImpl implements Con
     @Override
     protected boolean isVisible(Object service) {
         if (service instanceof Command) {
-            return isVisible((Command) service);
+            Command cmd = (Command) service;
+            return isVisible(cmd.getScope(), cmd.getName());
         } else {
             return super.isVisible(service);
         }
     }
 
-    protected boolean isVisible(Command command) {
-        Dictionary<String, Object> config = getScopeConfig(command.getScope());
+    protected boolean isVisible(String scope, String name) {
+        Dictionary<String, Object> config = getScopeConfig(scope);
         if (config != null) {
             List<String> roles = new ArrayList<>();
-            ACLConfigurationParser.getRolesForInvocation(command.getName(), 
null, null, config, roles);
+            ACLConfigurationParser.getRolesForInvocation(name, null, null, 
config, roles);
             if (roles.isEmpty()) {
                 return true;
             } else {
@@ -109,14 +127,14 @@ public class SecuredSessionFactoryImpl extends 
SessionFactoryImpl implements Con
         return true;
     }
 
-    void checkSecurity(SecuredCommand command, Session session, List<Object> 
arguments) {
-        Dictionary<String, Object> config = getScopeConfig(command.getScope());
+    void checkSecurity(String scope, String name, List<Object> arguments) {
+        Dictionary<String, Object> config = getScopeConfig(scope);
         if (config != null) {
-            if (!isVisible(command)) {
-                throw new CommandNotFoundException(command.getScope() + ":" + 
command.getName());
+            if (!isVisible(scope, name)) {
+                throw new CommandNotFoundException(scope + ":" + name);
             }
             List<String> roles = new ArrayList<>();
-            ACLConfigurationParser.Specificity s = 
ACLConfigurationParser.getRolesForInvocation(command.getName(), new Object[] { 
arguments.toString() }, null, config, roles);
+            ACLConfigurationParser.Specificity s = 
ACLConfigurationParser.getRolesForInvocation(name, new Object[] { 
arguments.toString() }, null, config, roles);
             if (s == ACLConfigurationParser.Specificity.NO_MATCH) {
                 return;
             }

Reply via email to