You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2013/12/18 15:58:37 UTC

[2/2] git commit: [KARAF-2636] Improve security mechanism

[KARAF-2636] Improve security mechanism

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

Branch: refs/heads/karaf-2.x
Commit: bdfbcd137d34f0820e66fef68844da0b8f85fd62
Parents: ee68cbe
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Dec 18 15:58:00 2013 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Dec 18 15:58:00 2013 +0100

----------------------------------------------------------------------
 assemblies/apache-karaf/pom.xml                 |   4 +
 .../src/main/distribution/text/etc/all.policy   |  22 +++
 .../distribution/text/etc/system.properties     |   7 +
 .../filtered-resources/etc/startup.properties   |   5 +
 .../apache/karaf/jaas/modules/JaasHelper.java   | 137 +++++++++++++++++++
 pom.xml                                         |   5 +
 .../shell/console/jline/ConsoleFactory.java     |  11 +-
 .../karaf/shell/ssh/ShellCommandFactory.java    |   9 +-
 .../karaf/shell/ssh/ShellFactoryImpl.java       |   9 +-
 webconsole/console/pom.xml                      |   5 +
 .../webconsole/internal/KarafOsgiManager.java   |   9 +-
 11 files changed, 218 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/assemblies/apache-karaf/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml
index 5021567..022d37b 100644
--- a/assemblies/apache-karaf/pom.xml
+++ b/assemblies/apache-karaf/pom.xml
@@ -291,6 +291,10 @@
             <artifactId>org.apache.felix.framework</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.framework.security</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.aries.blueprint</groupId>
             <artifactId>org.apache.aries.blueprint.api</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/assemblies/apache-karaf/src/main/distribution/text/etc/all.policy
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/src/main/distribution/text/etc/all.policy b/assemblies/apache-karaf/src/main/distribution/text/etc/all.policy
new file mode 100644
index 0000000..7585f22
--- /dev/null
+++ b/assemblies/apache-karaf/src/main/distribution/text/etc/all.policy
@@ -0,0 +1,22 @@
+//===========================================================================
+//
+//   Licensed to the Apache Software Foundation (ASF) under one or more
+//   contributor license agreements.  See the NOTICE file distributed with
+//   this work for additional information regarding copyright ownership.
+//   The ASF licenses this file to You 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.
+//
+//===========================================================================
+
+grant {
+   permission java.security.AllPermission;
+};

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/assemblies/apache-karaf/src/main/distribution/text/etc/system.properties
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/src/main/distribution/text/etc/system.properties b/assemblies/apache-karaf/src/main/distribution/text/etc/system.properties
index 24e3862..3023cf2 100644
--- a/assemblies/apache-karaf/src/main/distribution/text/etc/system.properties
+++ b/assemblies/apache-karaf/src/main/distribution/text/etc/system.properties
@@ -104,3 +104,10 @@ org.apache.servicemix.specs.timeout = 100
 org.apache.aries.proxy.weaving.enabled = none
 # Classes not to weave - Aries default + Xerces which is known to have issues.
 org.apache.aries.proxy.weaving.disabled = org.objectweb.asm.*,org.slf4j.*,org.apache.log4j.*,javax.*,org.apache.xerces.*
+
+#
+# Security properties
+#
+#java.security.policy=${karaf.home}/etc/all.policy
+#org.osgi.framework.security=osgi
+#org.osgi.framework.trust.repositories=${karaf.home}/etc/trustStore.ks

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties b/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties
index 630a9a2..2abc48a 100644
--- a/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties
+++ b/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties
@@ -21,6 +21,11 @@
 #
 
 #
+# Security
+#
+#org/apache/felix/org.apache.felix.framework.security/${felix.framework.security.version}/org.apache.felix.framework.security-${felix.framework.security.version}.jar=1
+
+#
 # Startup core services like logging
 #
 org/ops4j/pax/url/pax-url-mvn/${pax.url.version}/pax-url-mvn-${pax.url.version}.jar=5

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java
----------------------------------------------------------------------
diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java
new file mode 100644
index 0000000..111df95
--- /dev/null
+++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/JaasHelper.java
@@ -0,0 +1,137 @@
+/*
+ *  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.
+ *  under the License.
+ */
+package org.apache.karaf.jaas.modules;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import javax.security.auth.Subject;
+import javax.security.auth.SubjectDomainCombiner;
+
+public class JaasHelper {
+
+    public static <T> T doAs(final Subject subject,
+                             final PrivilegedAction<T> action) {
+        if (action == null) {
+            throw new NullPointerException();
+        }
+        // set up the new Subject-based AccessControlContext for doPrivileged
+        final AccessControlContext currentAcc = AccessController.getContext();
+        final AccessControlContext newAcc = AccessController.doPrivileged
+                (new PrivilegedAction<AccessControlContext>() {
+                    public AccessControlContext run() {
+                        if (subject == null)
+                            return new AccessControlContext(currentAcc, null);
+                        else
+                            return new AccessControlContext(currentAcc, new OsgiSubjectDomainCombiner(subject));
+                    }
+                });
+        // call doPrivileged and push this new context on the stack
+        return AccessController.doPrivileged(action, newAcc);
+    }
+
+    public static <T> T doAs(final Subject subject,
+                             final PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
+        if (action == null) {
+            throw new NullPointerException();
+        }
+        // set up the new Subject-based AccessControlContext for doPrivileged
+        final AccessControlContext currentAcc = AccessController.getContext();
+        final AccessControlContext newAcc = AccessController.doPrivileged
+                (new PrivilegedAction<AccessControlContext>() {
+                    public AccessControlContext run() {
+                        if (subject == null)
+                            return new AccessControlContext(currentAcc, null);
+                        else
+                            return new AccessControlContext(currentAcc, new OsgiSubjectDomainCombiner(subject));
+                    }
+                });
+        // call doPrivileged and push this new context on the stack
+        return AccessController.doPrivileged(action, newAcc);
+    }
+
+    public static class OsgiSubjectDomainCombiner extends SubjectDomainCombiner {
+
+        private final Subject subject;
+
+        public OsgiSubjectDomainCombiner(Subject subject) {
+            super(subject);
+            this.subject = subject;
+        }
+
+        public ProtectionDomain[] combine(ProtectionDomain[] currentDomains,
+                                          ProtectionDomain[] assignedDomains) {
+            int cLen = (currentDomains == null ? 0 : currentDomains.length);
+            int aLen = (assignedDomains == null ? 0 : assignedDomains.length);
+            ProtectionDomain[] newDomains = new ProtectionDomain[cLen + aLen];
+            Principal[] principals = subject.getPrincipals().toArray(new Principal[0]);
+            for (int i = 0; i < cLen; i++) {
+                newDomains[i] = new DelegatingProtectionDomain(currentDomains[i], principals);
+            }
+            for (int i = 0; i < aLen; i++) {
+                newDomains[cLen + i] = assignedDomains[i];
+            }
+            newDomains = optimize(newDomains);
+            return newDomains;
+        }
+
+        private ProtectionDomain[] optimize(ProtectionDomain[] domains) {
+            if (domains == null || domains.length == 0) {
+                return null;
+            }
+            ProtectionDomain[] optimized = new ProtectionDomain[domains.length];
+            ProtectionDomain pd;
+            int num = 0;
+            for (int i = 0; i < domains.length; i++) {
+                if ((pd = domains[i]) != null) {
+                    boolean found = false;
+                    for (int j = 0; j < num && !found; j++) {
+                        found = (optimized[j] == pd);
+                    }
+                    if (!found) {
+                        optimized[num++] = pd;
+                    }
+                }
+            }
+            if (num > 0 && num < domains.length) {
+                ProtectionDomain[] downSize = new ProtectionDomain[num];
+                System.arraycopy(optimized, 0, downSize, 0, downSize.length);
+                optimized = downSize;
+            }
+            return ((num == 0 || optimized.length == 0) ? null : optimized);
+        }
+    }
+
+    public static class DelegatingProtectionDomain extends ProtectionDomain {
+
+        private final ProtectionDomain delegate;
+
+        DelegatingProtectionDomain(ProtectionDomain delegate, Principal[] principals) {
+            super(delegate.getCodeSource(), delegate.getPermissions(), delegate.getClassLoader(), principals);
+            this.delegate = delegate;
+        }
+
+        @Override
+        public boolean implies(Permission permission) {
+            return delegate.implies(permission);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 0769a9f..73a0719 100644
--- a/pom.xml
+++ b/pom.xml
@@ -514,6 +514,11 @@
                 </exclusions>
             </dependency>
             <dependency>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>org.apache.felix.framework.security</artifactId>
+                <version>${felix.framework.security.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.osgi</groupId>
                 <artifactId>org.osgi.core</artifactId>
                 <version>${osgi.version}</version>

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
----------------------------------------------------------------------
diff --git a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
index a6565ab..9ab6182 100644
--- a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
+++ b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
@@ -38,6 +38,7 @@ import org.apache.felix.service.threadio.ThreadIO;
 import org.apache.karaf.jaas.boot.principal.UserPrincipal;
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.local.AgentImpl;
+import org.apache.karaf.jaas.modules.JaasHelper;
 import org.fusesource.jansi.AnsiConsole;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
@@ -48,7 +49,13 @@ public class ConsoleFactory {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleFactory.class);
 
-    BundleContext bundleContext;
+    private static final Class[] SECURITY_BUGFIX = {
+            JaasHelper.class,
+            JaasHelper.OsgiSubjectDomainCombiner.class,
+            JaasHelper.DelegatingProtectionDomain.class,
+    };
+
+    private BundleContext bundleContext;
     private CommandProcessor commandProcessor;
     private ThreadIO threadIO;
     private TerminalFactory terminalFactory;
@@ -87,7 +94,7 @@ public class ConsoleFactory {
             Subject subject = new Subject();
             final String user = "karaf";
             subject.getPrincipals().add(new UserPrincipal(user));
-            Subject.doAs(subject, new PrivilegedExceptionAction<Object>() {
+            JaasHelper.doAs(subject, new PrivilegedExceptionAction<Object>() {
                 public Object run() throws Exception {
                     doStart(user);
                     return null;

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java
----------------------------------------------------------------------
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java
index a7ff019..7ffca91 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommandFactory.java
@@ -30,6 +30,7 @@ import org.apache.felix.service.command.CommandProcessor;
 import org.apache.felix.service.command.CommandSession;
 import org.apache.felix.service.command.Converter;
 import org.apache.karaf.shell.console.jline.Console;
+import org.apache.karaf.jaas.modules.JaasHelper;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.CommandFactory;
 import org.apache.sshd.server.Environment;
@@ -46,6 +47,12 @@ public class ShellCommandFactory implements CommandFactory {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ShellCommandFactory.class);
 
+    private static final Class[] SECURITY_BUGFIX = {
+            JaasHelper.class,
+            JaasHelper.OsgiSubjectDomainCombiner.class,
+            JaasHelper.DelegatingProtectionDomain.class,
+    };
+
     private CommandProcessor commandProcessor;
 
     public void setCommandProcessor(CommandProcessor commandProcessor) {
@@ -104,7 +111,7 @@ public class ShellCommandFactory implements CommandFactory {
                         try {
                             String scriptFileName = System.getProperty(SHELL_INIT_SCRIPT);
                             executeScript(scriptFileName, session);
-                            result = Subject.doAs(subject, new PrivilegedExceptionAction<Object>() {
+                            result = JaasHelper.doAs(subject, new PrivilegedExceptionAction<Object>() {
                                 public Object run() throws Exception {
                                     return session.execute(command);
                                 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
----------------------------------------------------------------------
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
index f1d37a2..b4d3ad8 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
@@ -34,6 +34,7 @@ import org.apache.felix.service.command.CommandProcessor;
 import org.apache.felix.service.command.CommandSession;
 import org.apache.felix.service.command.Function;
 import org.apache.felix.service.threadio.ThreadIO;
+import org.apache.karaf.jaas.modules.JaasHelper;
 import org.apache.karaf.shell.console.jline.Console;
 import org.apache.sshd.common.Factory;
 import org.apache.sshd.server.Command;
@@ -48,6 +49,12 @@ import org.osgi.service.blueprint.container.ReifiedType;
  */
 public class ShellFactoryImpl implements Factory<Command> {
 
+    private static final Class[] SECURITY_BUGFIX = {
+            JaasHelper.class,
+            JaasHelper.OsgiSubjectDomainCombiner.class,
+            JaasHelper.DelegatingProtectionDomain.class,
+    };
+
     private CommandProcessor commandProcessor;
     private ThreadIO threadIO;
 
@@ -137,7 +144,7 @@ public class ShellFactoryImpl implements Factory<Command> {
                     public void run() {
                         Subject subject = ShellImpl.this.session != null ? ShellImpl.this.session.getAttribute(KarafJaasAuthenticator.SUBJECT_ATTRIBUTE_KEY) : null;
                         if (subject != null) {
-                            Subject.doAs(subject, new PrivilegedAction<Object>() {
+                            JaasHelper.doAs(subject, new PrivilegedAction<Object>() {
                                 public Object run() {
                                     doRun();
                                     return null;

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/webconsole/console/pom.xml
----------------------------------------------------------------------
diff --git a/webconsole/console/pom.xml b/webconsole/console/pom.xml
index a04d3c0..0555340 100644
--- a/webconsole/console/pom.xml
+++ b/webconsole/console/pom.xml
@@ -57,6 +57,11 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.karaf.jaas</groupId>
+            <artifactId>org.apache.karaf.jaas.modules</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <scope>provided</scope>

http://git-wip-us.apache.org/repos/asf/karaf/blob/bdfbcd13/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/KarafOsgiManager.java
----------------------------------------------------------------------
diff --git a/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/KarafOsgiManager.java b/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/KarafOsgiManager.java
index 5b40d56..7cd8425 100644
--- a/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/KarafOsgiManager.java
+++ b/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/KarafOsgiManager.java
@@ -27,10 +27,17 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 
 import org.apache.felix.webconsole.internal.servlet.OsgiManager;
+import org.apache.karaf.jaas.modules.JaasHelper;
 import org.osgi.framework.BundleContext;
 
 public class KarafOsgiManager extends OsgiManager {
 
+    private static final Class[] SECURITY_BUGFIX = {
+            JaasHelper.class,
+            JaasHelper.OsgiSubjectDomainCombiner.class,
+            JaasHelper.DelegatingProtectionDomain.class,
+    };
+
     public static final String SUBJECT_RUN_AS = "karaf.subject.runas";
 
     public KarafOsgiManager(BundleContext bundleContext) {
@@ -42,7 +49,7 @@ public class KarafOsgiManager extends OsgiManager {
         Object obj = req.getAttribute(SUBJECT_RUN_AS);
         if (obj instanceof Subject) {
             try {
-                Subject.doAs((Subject) obj, new PrivilegedExceptionAction<Object>() {
+                JaasHelper.doAs((Subject) obj, new PrivilegedExceptionAction<Object>() {
                     public Object run() throws Exception {
                         doService(req, res);
                         return null;