diff --git a/.github/workflows/maven-ci.yml b/.github/workflows/maven-ci.yml
index c9599684d1..e501beb07c 100644
--- a/.github/workflows/maven-ci.yml
+++ b/.github/workflows/maven-ci.yml
@@ -11,8 +11,11 @@ on:
- 'log/**'
- 'webconsole/**'
- 'framework/**'
+ - 'gogo/**'
+ - 'framework.tck/**'
+ - 'main/**'
pull_request:
- branches: [ "master" ]
+ branches: [ "master", "feature/**", "maintenance/**" ]
paths:
- 'scr/**'
- 'http/**'
@@ -22,6 +25,15 @@ on:
- 'log/**'
- 'framework/**'
- 'gogo/**'
+ - 'framework.tck/**'
+ - 'main/**'
+
+# Cancel superseded runs when a branch is pushed again. github.head_ref is only set
+# for pull_request events, so pushes to master fall back to the unique run_id and are
+# never cancelled.
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
permissions: {}
@@ -31,7 +43,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- java: [17,21,23]
+ java: [17,21,23,25]
steps:
- uses: actions/checkout@v6
- name: Set up JDK ${{ matrix.java }}
@@ -63,9 +75,11 @@ jobs:
- 'log/**'
framework:
- 'framework/**'
+ - 'framework.tck/**'
gogo:
- 'gogo/**'
-
+ main:
+ - 'main/**'
- name: Felix SCR
if: steps.changes.outputs.scr == 'true'
run: mvn -B -V -Dstyle.color=always --file scr/pom.xml clean verify
@@ -86,10 +100,17 @@ jobs:
run: mvn -B -V -Dstyle.color=always --file webconsole/pom.xml clean install verify
- name: Felix Framework
if: steps.changes.outputs.framework == 'true'
- run: mvn -B -V -Dstyle.color=always --file framework/pom.xml clean verify
+ # install, not verify: the TCK below is a separate Maven invocation and resolves
+ # the framework from the repository, so without installing it would silently test
+ # whatever org.apache.felix.framework happens to be published rather than the
+ # build under test.
+ run: mvn -B -V -Dstyle.color=always --file framework/pom.xml clean install
- name: OSGi-TCK Framework
if: steps.changes.outputs.framework == 'true'
run: mvn -B -V -Dstyle.color=always --file framework.tck/pom.xml clean verify
+ - name: Felix Main
+ if: steps.changes.outputs.main == 'true'
+ run: mvn -B -V -Dstyle.color=always --file main/pom.xml clean verify
- name: Felix Gogo Shell
if: steps.changes.outputs.gogo == 'true'
run: mvn -B -V -Dstyle.color=always --file gogo/pom.xml clean verify
diff --git a/.gitignore b/.gitignore
index 7692143cb7..bcee930369 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,11 @@ dependency-reduced-pom.xml
/.metadata/
/workspace/
.vscode
+
+# Generated by the main and main.distribution builds. Note that
+# main.distribution/conf is tracked and must not be ignored.
+main/bundle/
+main/bin/
+main/conf/
+main.distribution/bundle/
+main.distribution/bin/
diff --git a/README.md b/README.md
index bc69ae4388..67d94116cb 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,32 @@
The **Apache Felix** project is a collection of semi-related **OSGi** sub-projects that build and release individually.
+## Java support
+
+Sub-projects build and release individually and each declares its own minimum Java
+version, so there is no single repository-wide baseline. The CI build
+(`.github/workflows/maven-ci.yml`) compiles and tests the covered sub-projects on
+**Java 17, 21, 23 and 25**.
+
+### Security Manager
+
+The **Apache Felix Framework** no longer supports the OSGi security layer. Java SE 24
+permanently disabled the Security Manager
+([JEP 486](https://openjdk.org/jeps/486)), so permission checks can no longer be
+enforced and `System.setSecurityManager` throws. Accordingly:
+
+- Launching the framework with the `org.osgi.framework.security` property now fails
+ with a `SecurityException` rather than silently starting without the requested
+ security.
+- `Bundle.hasPermission(...)` returns `true` unless a `SecurityProvider` is installed.
+- The OSGi permission API (`AdminPermission`, `ServicePermission`, `PackagePermission`,
+ and friends) is still exported, so bundles referring to those types keep compiling
+ and resolving.
+- The `org.apache.felix.framework.security` sub-project has been removed.
+
+If you need the security layer, stay on a release that predates this change and run it
+on Java 21 or earlier.
+
## Felix Framework
The flagship project is the **Apache Felix Framework** which implements the [**OSGi Core R7**](https://osgi.org/specification/osgi.core/7.0.0/) specification. The `/framework` directory contains the source and build tree for the **OSGi**-compliant
diff --git a/framework.security/doc/changelog.txt b/framework.security/doc/changelog.txt
deleted file mode 100644
index 75b33f0303..0000000000
--- a/framework.security/doc/changelog.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-Changes from 2.8.3 to 2.8.4
----------------------------
-
-** Bug
- * [FELIX-6591] - Fix a memory leak in Felix Framework Security extension
-
-Changes from 2.8.1 to 2.8.3
----------------------------
-
-** Bug
- * [FELIX-3351] - Permissions.createPermission(String name, String action, Class target) Fails for action == null
- * [FELIX-6467] - `AllPermission` not checked when updating `ConditionalPermissionAdmin`
-
-Changes from 2.8.0 to 2.8.1
----------------------------
-
-** Improvement
- * [FELIX-6398] - Update packages to osgi.core 8
-
-Changes from 2.6.1 to 2.8.0
----------------------------
-
-** Improvement
- * [FELIX-6369] - Implement R8 core spec
-
-Changes from 2.6.0 to 2.6.1
----------------------------
-
-** Bug
- * [FELIX-5906] - Installing Manifest only bundles causes ArrayIndexOutOfBoundsException
-
-Changes from 2.4.0 to 2.6.0
----------------------------
-
-** Improvement
- * Update to latest framework version 5.6.0
-
-Changes from 2.2.0 to 2.4.0
----------------------------
-** Improvement
- * Update to latest framework version 4.4.0
-
-Changes form 2.0.1 to 2.2.0
----------------------------
-** Bug
- * [FELIX-3498] - BundleInputStream is not able to handle bundles that only have a MANIFEST.MF entry
- * [FELIX-3603] - Resources in META-INF/xxx/ fodlers in a signed bundle should be checked
- * [FELIX-3604] - No error log if the certificate is not valid
- * [FELIX-3893] - Bundle in cache doesn't pass security check anymore.
-
-Changes from 2.0.0 to 2.0.1
----------------------------
-
-** Bug
- * [FELIX-3196] - Security Problem: Getting full file access within the cache directory from one Bundle
- * [FELIX-3221] - NPE when uninstall a bundle on enabled OSGi security
-
-Changes from 1.4.2 to 2.0.0
----------------------------
-** Bug
- * [FELIX-2648] - Incompatible security provider state when switching from 2.0.4 to 3.0.3
- * [FELIX-2922] - ArrayIndexOutOfBoundsException when specifying no name
- * [FELIX-3004] - felix.security does not work with exploded jars
- * [FELIX-3101] - ClassCastException in Permissions class
-
-** Improvement
- * Update to latest framework version 4.0.0
-
-Changes from 1.4.1 to 1.4.2
----------------------------
-
-** Improvement
- * Update to latest framework version 3.2.0
-
-Changes from 1.4.0 to 1.4.1
----------------------------
-
-** Bug
- * [FELIX-2739] - [Security] Recent framework changes have broken the security provider.
-
-Changes from 1.2.0 to 1.4.0
----------------------------
-
-** Improvement
- * [FELIX-2547] - Implement conditionalpermissioninfo encoding/decoding to match the spec.
-
-
-Changes from 1.0.0 to 1.2.0
----------------------------
-
-** Task
- * [FELIX-2294] - Patch Framework Security for compatibility
-
-1.0.0
------
-
-** Initial Release
diff --git a/framework.security/pom.xml b/framework.security/pom.xml
deleted file mode 100644
index 14555e06be..0000000000
--- a/framework.security/pom.xml
+++ /dev/null
@@ -1,103 +0,0 @@
-
-
-
- org.apache.felix
- felix-parent
- 6
- ../pom/pom.xml
-
- 4.0.0
- bundle
- Apache Felix Security Provider
- org.apache.felix.framework.security
- 2.9.0-SNAPSHOT
-
- This bundle provides an implementation of the OSGi security for Apache Felix.
-
-
- scm:git:https://github.com/apache/felix-dev.git
- scm:git:https://github.com/apache/felix-dev.git
- https://gitbox.apache.org/repos/asf?p=felix-dev.git
- HEAD
-
-
-
- org.osgi
- osgi.core
- 8.0.0
-
-
- ${pom.groupId}
- org.apache.felix.framework
- 7.1.0-SNAPSHOT
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- 1.3
- 1.3
-
-
-
- org.apache.felix
- maven-bundle-plugin
- 5.1.2
- true
-
-
- ${pom.artifactId}
- The Apache Software Foundation
- org.osgi.service.permissionadmin, org.osgi.service.condpermadmin
- org.apache.felix.framework.*
- !*
- system.bundle; extension:=framework
- org.apache.felix.framework.SecurityActivator
-
-
- org.apache.felix.framework
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
- false
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
-
-
- attach-sources
-
- jar
-
-
-
-
-
-
-
diff --git a/framework.security/src/main/appended-resources/META-INF/DEPENDENCIES b/framework.security/src/main/appended-resources/META-INF/DEPENDENCIES
deleted file mode 100644
index cce7c0b20e..0000000000
--- a/framework.security/src/main/appended-resources/META-INF/DEPENDENCIES
+++ /dev/null
@@ -1,16 +0,0 @@
-I. Included Third-Party Software
-
-This product includes software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
-Licensed under the Apache License 2.0.
-
-II. Used Third-Party Software
-
-This product uses software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
-Licensed under the Apache License 2.0.
-
-III. License Summary
-- Apache License 2.0
diff --git a/framework.security/src/main/appended-resources/META-INF/LICENSE b/framework.security/src/main/appended-resources/META-INF/LICENSE
deleted file mode 100644
index d645695673..0000000000
--- a/framework.security/src/main/appended-resources/META-INF/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/framework.security/src/main/appended-resources/META-INF/NOTICE b/framework.security/src/main/appended-resources/META-INF/NOTICE
deleted file mode 100644
index 3db2e431ed..0000000000
--- a/framework.security/src/main/appended-resources/META-INF/NOTICE
+++ /dev/null
@@ -1,4 +0,0 @@
-This product includes software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
-Licensed under the Apache License 2.0.
diff --git a/framework.security/src/main/java/org/apache/felix/framework/FakeBundle.java b/framework.security/src/main/java/org/apache/felix/framework/FakeBundle.java
deleted file mode 100644
index 19a050675a..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/FakeBundle.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Map;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-
-/**
- *
- */
-public class FakeBundle extends BundleImpl implements Bundle
-{
- private final Map m_certs;
-
- public FakeBundle(Map certs)
- {
- m_certs = Collections.unmodifiableMap(certs);
- }
-
- public Enumeration findEntries(String arg0, String arg1, boolean arg2)
- {
- return null;
- }
-
- public BundleContext getBundleContext()
- {
- return null;
- }
-
- public long getBundleId()
- {
- return -1;
- }
-
- public URL getEntry(String arg0)
- {
- return null;
- }
-
- public Enumeration getEntryPaths(String arg0)
- {
- return null;
- }
-
- public Dictionary getHeaders()
- {
- return new Hashtable();
- }
-
- public Dictionary getHeaders(String arg0)
- {
- return new Hashtable();
- }
-
- public long getLastModified()
- {
- return 0;
- }
-
- public String getLocation()
- {
- return "";
- }
-
- public ServiceReference[] getRegisteredServices()
- {
- return null;
- }
-
- public URL getResource(String arg0)
- {
- return null;
- }
-
- public Enumeration getResources(String arg0) throws IOException
- {
- return null;
- }
-
- public ServiceReference[] getServicesInUse()
- {
- return null;
- }
-
- public Map getSignerCertificates(int arg0)
- {
- return m_certs;
- }
-
- public int getState()
- {
- return Bundle.UNINSTALLED;
- }
-
- public String getSymbolicName()
- {
- return null;
- }
-
- public Version getVersion()
- {
- return Version.emptyVersion;
- }
-
- public boolean hasPermission(Object arg0)
- {
- return false;
- }
-
- public Class loadClass(String arg0) throws ClassNotFoundException
- {
- return null;
- }
-
- public void start() throws BundleException
- {
- throw new IllegalStateException();
- }
-
- public void start(int arg0) throws BundleException
- {
- throw new IllegalStateException();
- }
-
- public void stop() throws BundleException
- {
- throw new IllegalStateException();
- }
-
- public void stop(int arg0) throws BundleException
- {
- throw new IllegalStateException();
- }
-
- public void uninstall() throws BundleException
- {
- throw new IllegalStateException();
- }
-
- public void update() throws BundleException
- {
- throw new IllegalStateException();
- }
-
- public void update(InputStream arg0) throws BundleException
- {
- throw new IllegalStateException();
- }
-
- public boolean equals(Object o)
- {
- return this == o;
- }
-
- public int hashCode()
- {
- return System.identityHashCode(this);
- }
-
- public Object adapt(Class arg0) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public File getDataFile(String arg0) {
- // TODO Auto-generated method stub
- return null;
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/SecurityActivator.java b/framework.security/src/main/java/org/apache/felix/framework/SecurityActivator.java
deleted file mode 100644
index fd762644bd..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/SecurityActivator.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import org.apache.felix.framework.ext.SecurityProvider;
-import org.apache.felix.framework.security.SecurityConstants;
-import org.apache.felix.framework.security.condpermadmin.ConditionalPermissionAdminImpl;
-import org.apache.felix.framework.security.permissionadmin.PermissionAdminImpl;
-import org.apache.felix.framework.security.util.Conditions;
-import org.apache.felix.framework.security.util.LocalPermissions;
-import org.apache.felix.framework.security.util.Permissions;
-import org.apache.felix.framework.security.util.PropertiesCache;
-import org.apache.felix.framework.util.SecureAction;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleRevisions;
-import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
-import org.osgi.service.permissionadmin.PermissionAdmin;
-
-/**
- *
- * This Felix specific activator installs a security provider with the Felix
- * framework. The security settings can be changed via the
- * {@link PermissionAdmin} and/or the {@link ConditionalPermissionAdmin}
- * services that may be published by this class.
- *
- *
- * Permission informations as well as caching data will be stored in several
- * files in a directory called security obtained by a call to
- * {@link BundleContext#getDataFile(String))}.
- *
- *
- * The following properties are recognized:
- *
- * {@link SecurityConstants#ENABLE_PERMISSIONADMIN_PROP} - Whether or not (
- * true|false) to publish a{@link ConditionalPermissionAdmin}
- * service. The default is
- * {@link SecurityConstants#ENABLE_PERMISSIONADMIN_VALUE}.
- *
- *
- * {@link SecurityConstants#ENABLE_CONDPERMADMIN_PROP} - Whether or not (
- * true|false) to publish a{@link ConditionalPermissionAdmin}
- * service. The default is {@link SecurityConstants#ENABLE_CONDPERMADMIN_VALUE}.
- *
- *
- * {@link SecurityConstants#KEYSTORE_FILE_PROP} - The keystore URL(s) to use as
- * trusted CA stores. The urls must be separated by a guard (i.e., |).
- * The default is {@link SecurityConstants#KEYSTORE_FILE_VALUE}.
- *
- *
- * {@link SecurityConstants#KEYSTORE_PASS_PROP} - The keystore password(s) to
- * use for the given keystores. The passwords must be separated by a guard
- * (i.e., |).The default is
- * {@link SecurityConstants#KEYSTORE_PASS_VALUE}.
- *
- *
- * {@link SecurityConstants#KEYSTORE_TYPE_PROP} - The keystore type(s) to use
- * for the given keystores. The types must be separated by a guard (i.e.,
- * |).The default is {@link SecurityConstants#KEYSTORE_TYPE_VALUE}.
- *
- *
- * {@link SecurityConstants#CRL_FILE_PROP} - The CRL URL(s) to use for revoked
- * certificates. The urls must be separated by a guard (i.e., |). The
- * default is {@link SecurityConstants#CRL_FILE_VALUE}.
- *
- *
- */
-/*
- * TODO: using a string for passwords is bad. We need to investigate
- * alternatives.
- *
- * TODO: we might want to allow for the recognized properties to change without
- * a restart. This is trick because we can not publish a managed service due to
- * not being able to import as we are an extension bundle.
- */
-public final class SecurityActivator implements BundleActivator
-{
- public synchronized void start(BundleContext context) throws Exception
- {
- PermissionAdminImpl pai = null;
-
- SecureAction action = new SecureAction();
-
- Permissions permissions = new Permissions(context, action);
-
- File tmp = context.getDataFile("security" + File.separator + "tmp");
- if ((tmp == null) || (!tmp.isDirectory() && !tmp.mkdirs()))
- {
- throw new IOException("Can't create tmp dir.");
- }
- // TODO: log something if we can not clean-up the tmp dir
- File[] old = tmp.listFiles();
- if (old != null)
- {
- for (int i = 0; i < old.length; i++)
- {
- old[i].delete();
- }
- }
-
- if ("TRUE".equalsIgnoreCase(getProperty(context,
- SecurityConstants.ENABLE_PERMISSIONADMIN_PROP,
- SecurityConstants.ENABLE_PERMISSIONADMIN_VALUE)))
- {
- File cache = context.getDataFile("security" + File.separator
- + "pa.txt");
- if ((cache == null) || (!cache.isFile() && !cache.createNewFile()))
- {
- throw new IOException("Can't create cache file");
- }
- pai = new PermissionAdminImpl(permissions, new PropertiesCache(
- cache, tmp, action));
- }
-
- ConditionalPermissionAdminImpl cpai = null;
-
- if ("TRUE".equalsIgnoreCase(getProperty(context,
- SecurityConstants.ENABLE_CONDPERMADMIN_PROP,
- SecurityConstants.ENABLE_CONDPERMADMIN_VALUE)))
- {
- File cpaCache = context.getDataFile("security" + File.separator
- + "cpa.txt");
- if ((cpaCache == null)
- || (!cpaCache.isFile() && !cpaCache.createNewFile()))
- {
- throw new IOException("Can't create cache file");
- }
-
- LocalPermissions localPermissions = new LocalPermissions(
- permissions);
-
- final Conditions conditions = new Conditions(action);
- cpai = new ConditionalPermissionAdminImpl(permissions,
- conditions, localPermissions, new PropertiesCache(
- cpaCache, tmp, action), pai);
-
- context.addBundleListener(new UninstallListener(conditions));
- }
-
- if ((pai != null) || (cpai != null))
- {
- String crlList = getProperty(context,
- SecurityConstants.CRL_FILE_PROP,
- SecurityConstants.CRL_FILE_VALUE);
- String storeList = getProperty(context,
- SecurityConstants.KEYSTORE_FILE_PROP,
- SecurityConstants.KEYSTORE_FILE_VALUE);
- String passwdList = getProperty(context,
- SecurityConstants.KEYSTORE_PASS_PROP,
- SecurityConstants.KEYSTORE_PASS_VALUE);
- String typeList = getProperty(context,
- SecurityConstants.KEYSTORE_TYPE_PROP,
- SecurityConstants.KEYSTORE_TYPE_VALUE);
- String osgi_keystores = getProperty(context,
- Constants.FRAMEWORK_TRUST_REPOSITORIES, null);
- if (osgi_keystores != null)
- {
- StringTokenizer tok = new StringTokenizer(osgi_keystores,
- File.pathSeparator);
-
- if (storeList.length() == 0)
- {
- storeList += "file:" + tok.nextToken();
- passwdList += " ";
- typeList += "JKS";
- }
- while (tok.hasMoreTokens())
- {
- storeList += "|file:" + tok.nextToken();
- passwdList += "| ";
- typeList += "|JKS";
- }
- }
-
- StringTokenizer storeTok = new StringTokenizer(storeList, "|");
- StringTokenizer passwdTok = new StringTokenizer(passwdList, "|");
- StringTokenizer typeTok = new StringTokenizer(typeList, "|");
-
- if ((storeTok.countTokens() != typeTok.countTokens())
- || (passwdTok.countTokens() != storeTok.countTokens()))
- {
- throw new BundleException(
- "Each CACerts keystore must have one type and one passwd entry and vice versa.");
- }
-
- SecurityProvider provider = new SecurityProviderImpl(crlList,
- typeList, passwdList, storeList, pai, cpai, action, ((Felix) context.getBundle(0)).getLogger());
-
- ((Felix) context.getBundle(0)).setSecurityProvider(provider);
- }
-
- if (pai != null)
- {
- context.registerService(PermissionAdmin.class.getName(), pai, null);
- }
-
- if (cpai != null)
- {
- context.registerService(ConditionalPermissionAdmin.class.getName(),
- cpai, null);
- }
- }
-
- public synchronized void stop(BundleContext context) throws Exception
- {
- ((Felix) context.getBundle(0)).setSecurityProvider(null);
- }
-
- private String getProperty(BundleContext context, String key,
- String defaultValue)
- {
- String result = context.getProperty(key);
-
- return (result != null) ? result : defaultValue;
- }
-
- private static final class UninstallListener implements BundleListener
- {
- private final Conditions conditions;
-
- UninstallListener(Conditions conditions)
- {
- this.conditions = conditions;
- }
-
- public void bundleChanged(BundleEvent event)
- {
- if (event.getType() == BundleEvent.UNINSTALLED)
- {
- List revisions = ((BundleRevisions)event.getBundle().adapt(BundleRevisions.class)).getRevisions();
- if (revisions != null)
- {
- Iterator iter = revisions.iterator();
- while (iter.hasNext())
- {
- conditions.remove((BundleRevisionImpl) iter.next());
- }
- }
- }
- }
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/SecurityProviderImpl.java b/framework.security/src/main/java/org/apache/felix/framework/SecurityProviderImpl.java
deleted file mode 100644
index 405f9092f8..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/SecurityProviderImpl.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework;
-
-import java.security.Permission;
-import java.security.ProtectionDomain;
-
-import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.ext.SecurityProvider;
-import org.apache.felix.framework.security.condpermadmin.ConditionalPermissionAdminImpl;
-import org.apache.felix.framework.security.permissionadmin.PermissionAdminImpl;
-import org.apache.felix.framework.security.util.TrustManager;
-import org.apache.felix.framework.security.verifier.BundleDNParser;
-import org.apache.felix.framework.util.SecureAction;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleRevision;
-
-/**
- * This class is the entry point to the security. It is used to determine
- * whether a given bundle is signed correctely and has permissions based on
- * PermissionAdmin or ConditionalPermissionAdmin.
- */
-public final class SecurityProviderImpl implements SecurityProvider
-{
- private final BundleDNParser m_parser;
- private final PermissionAdminImpl m_pai;
- private final ConditionalPermissionAdminImpl m_cpai;
- private final SecureAction m_action;
-
- SecurityProviderImpl(String crlList, String typeList, String passwdList,
- String storeList, PermissionAdminImpl pai,
- ConditionalPermissionAdminImpl cpai, SecureAction action, Logger logger)
- {
- m_pai = pai;
- m_cpai = cpai;
- m_action = action;
- m_parser = new BundleDNParser(new TrustManager(crlList, typeList,
- passwdList, storeList, m_action), logger);
- }
-
- /**
- * If the given bundle is signed but can not be verified (e.g., missing
- * files) then throw an exception.
- */
- public void checkBundle(Bundle bundle) throws Exception
- {
- BundleRevisionImpl module = (BundleRevisionImpl) bundle.adapt(BundleRevisionImpl.class);
- m_parser.checkDNChains(module, module.getContent(),
- Bundle.SIGNERS_TRUSTED);
- }
-
- /**
- * Get a signer matcher that can be used to match digital signed bundles.
- */
- public Object getSignerMatcher(final Bundle bundle, int signersType)
- {
- BundleRevisionImpl module = (BundleRevisionImpl) bundle.adapt(BundleRevisionImpl.class);
- return m_parser.getDNChains(module, module.getContent(), signersType);
- }
-
- /**
- * If we have a permissionadmin then ask that one first and have it decide
- * in case there is a location bound. If not then either use its default
- * permission in case there is no conditional permission admin or else ask
- * that one.
- */
- public boolean hasBundlePermission(ProtectionDomain bundleProtectionDomain,
- Permission permission, boolean direct)
- {
- BundleProtectionDomain pd = (BundleProtectionDomain) bundleProtectionDomain;
- BundleImpl bundle = pd.getBundle();
- BundleRevisionImpl module = (BundleRevisionImpl) pd.getRevision();
-
- if (bundle.getBundleId() == 0)
- {
- return true;
- }
-
- // System.out.println(info.getBundleId() + " - " + permission);
- // TODO: using true, false, or null seems a bit awkward. Improve this.
- Boolean result = null;
- if (m_pai != null)
- {
- result = m_pai.hasPermission(bundle._getLocation(), pd.getBundle(),
- permission, m_cpai, pd, module.getContent());
- }
-
- if (result != null)
- {
- if ((m_cpai != null) && !direct)
- {
- boolean allow = result.booleanValue();
- if (!allow)
- {
- m_cpai.clearPD();
- return false;
- }
- return m_cpai.handlePAHandle(pd);
- }
- return result.booleanValue();
- }
-
- if (m_cpai != null)
- {
- try
- {
- return m_cpai.hasPermission(module, module.getContent(), pd,
- permission, direct, m_pai);
- }
- catch (Exception e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- return false;
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/SecurityConstants.java b/framework.security/src/main/java/org/apache/felix/framework/security/SecurityConstants.java
deleted file mode 100644
index 790e1852d4..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/SecurityConstants.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security;
-
-public interface SecurityConstants
-{
- public static final String KEYSTORE_FILE_PROP = "felix.keystore";
-
- public static final String KEYSTORE_FILE_VALUE = "";
-
- public static final String KEYSTORE_TYPE_PROP = "felix.keystore.type";
-
- public static final String KEYSTORE_TYPE_VALUE = "";
-
- public static final String KEYSTORE_PASS_PROP = "felix.keystore.pass";
-
- public static final String KEYSTORE_PASS_VALUE = "";
-
- public static final String CRL_FILE_PROP = "felix.crl";
-
- public static final String CRL_FILE_VALUE = "";
-
- public static final String ENABLE_CONDPERMADMIN_PROP = "felix.security.conpermadmin";
-
- public static final String ENABLE_CONDPERMADMIN_VALUE = "true";
-
- public static final String ENABLE_PERMISSIONADMIN_PROP = "felix.security.permissionadmin";
-
- public static final String ENABLE_PERMISSIONADMIN_VALUE = "true";
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/ConditionalPermissionAdminImpl.java b/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/ConditionalPermissionAdminImpl.java
deleted file mode 100644
index ba6c50fb12..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/ConditionalPermissionAdminImpl.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.condpermadmin;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URL;
-import java.security.AccessControlContext;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Permission;
-import java.security.Principal;
-import java.security.ProtectionDomain;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.X509Certificate;
-import java.util.AbstractSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.Map.Entry;
-
-import org.apache.felix.framework.BundleProtectionDomain;
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.FakeBundle;
-import org.apache.felix.framework.security.permissionadmin.PermissionAdminImpl;
-import org.apache.felix.framework.security.util.Conditions;
-import org.apache.felix.framework.security.util.LocalPermissions;
-import org.apache.felix.framework.security.util.Permissions;
-import org.apache.felix.framework.security.util.PropertiesCache;
-import org.apache.felix.framework.util.manifestparser.NativeLibrary;
-
-/*
-import org.apache.felix.moduleloader.ICapability;
-import org.apache.felix.moduleloader.IContent;
-import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.IRequirement;
-import org.apache.felix.moduleloader.IWire;
-*/
-import org.apache.felix.framework.cache.Content;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.service.condpermadmin.ConditionInfo;
-import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
-import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
-import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
-import org.osgi.service.permissionadmin.PermissionInfo;
-
-/**
- * An implementation of the ConditionalPermissionAdmin service that doesn't need
- * to have a framework specific security manager set. It use the DomainGripper
- * to know what bundleprotectiondomains are expected.
- */
-public final class ConditionalPermissionAdminImpl implements
- ConditionalPermissionAdmin
-{
- private static class OrderedHashMap extends HashMap
- {
- private final List m_order = new ArrayList();
-
- public Object put(Object key, Object value)
- {
- Object result = super.put(key, value);
- if (result != value)
- {
- m_order.remove(key);
- m_order.add(key);
- }
- return result;
- };
-
- public void putAll(Map map)
- {
- for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
- {
- Entry entry = (Entry) iter.next();
- put(entry.getKey(), entry.getValue());
- }
- };
-
- public Set keySet()
- {
- return new AbstractSet()
- {
- public Iterator iterator()
- {
- return m_order.iterator();
- }
-
- public int size()
- {
- return m_order.size();
- }
-
- };
- };
-
- public Set entrySet()
- {
- return new AbstractSet()
- {
-
- public Iterator iterator()
- {
- return new Iterator()
- {
- Iterator m_iter = m_order.iterator();
-
- public boolean hasNext()
- {
- return m_iter.hasNext();
- }
-
- public Object next()
- {
- final Object key = m_iter.next();
- return new Entry()
- {
-
- public Object getKey()
- {
- return key;
- }
-
- public Object getValue()
- {
- return get(key);
- }
-
- public Object setValue(Object arg0)
- {
- throw new IllegalStateException(
- "Not Implemented");
- }
- };
- }
-
- public void remove()
- {
- throw new IllegalStateException("Not Implemented");
- }
-
- };
- }
-
- public int size()
- {
- return m_order.size();
- }
-
- };
- };
-
- public Collection values()
- {
- List result = new ArrayList();
- for (Iterator iter = m_order.iterator(); iter.hasNext();)
- {
- result.add(super.get(iter.next()));
- }
- return result;
- };
-
- public Object remove(Object key)
- {
- Object result = super.remove(key);
- if (result != null)
- {
- m_order.remove(key);
- }
- return result;
- };
-
- public void clear()
- {
- super.clear();
- m_order.clear();
- };
- };
-
- private static final ConditionInfo[] EMPTY_CONDITION_INFO = new ConditionInfo[0];
- private static final PermissionInfo[] EMPTY_PERMISSION_INFO = new PermissionInfo[0];
- private final Map m_condPermInfos = new OrderedHashMap();
- private final PropertiesCache m_propertiesCache;
- private final Permissions m_permissions;
- private final Conditions m_conditions;
- private final LocalPermissions m_localPermissions;
- private final PermissionAdminImpl m_pai;
-
- public ConditionalPermissionAdminImpl(Permissions permissions,
- Conditions condtions, LocalPermissions localPermissions,
- PropertiesCache cache, PermissionAdminImpl pai) throws IOException
- {
- m_propertiesCache = cache;
- m_permissions = permissions;
- m_conditions = condtions;
- m_localPermissions = localPermissions;
- Map old = new OrderedHashMap();
- // Now try to restore the cache.
- m_propertiesCache.read(ConditionalPermissionInfoImpl.class, old);
- for (Iterator iter = old.entrySet().iterator(); iter.hasNext();)
- {
- Entry entry = (Entry) iter.next();
- String name = (String) entry.getKey();
- ConditionalPermissionInfoImpl cpi = ((ConditionalPermissionInfoImpl) entry
- .getValue());
- m_condPermInfos.put(name, new ConditionalPermissionInfoImpl(name,
- cpi._getConditionInfos(), cpi._getPermissionInfos(), this, cpi
- .isAllow()));
- }
- m_pai = pai;
- }
-
- public ConditionalPermissionInfo addConditionalPermissionInfo(
- ConditionInfo[] conditions, PermissionInfo[] permissions)
- {
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
- }
- ConditionalPermissionInfoImpl result = new ConditionalPermissionInfoImpl(
- notNull(conditions), notNull(permissions), this, true);
-
- return write(result.getName(), result);
- }
-
- ConditionalPermissionInfoImpl write(String name,
- ConditionalPermissionInfoImpl cpi)
- {
- synchronized (m_propertiesCache)
- {
- Map tmp = null;
-
- synchronized (m_condPermInfos)
- {
- tmp = new OrderedHashMap();
- tmp.putAll(m_condPermInfos);
-
- if ((name != null) && (cpi != null))
- {
- m_condPermInfos.put(name, cpi);
- }
- else if (name != null)
- {
- m_condPermInfos.remove(name);
- }
- else
- {
- tmp = null;
- }
- }
-
- try
- {
- m_propertiesCache.write(m_condPermInfos);
- }
- catch (IOException ex)
- {
- synchronized (m_condPermInfos)
- {
- if (tmp != null)
- {
- m_condPermInfos.clear();
- m_condPermInfos.putAll(tmp);
- }
- }
- ex.printStackTrace();
- throw new IllegalStateException(ex.getMessage());
- }
- }
- synchronized (m_condPermInfos)
- {
- return (ConditionalPermissionInfoImpl) m_condPermInfos.get(name);
- }
- }
-
- private static class FakeCert extends X509Certificate
- {
- private final Principal m_principal;
-
- public FakeCert(final String principal)
- {
- m_principal = new Principal()
- {
- public String getName()
- {
- return principal;
- }
- };
- }
-
- public void checkValidity()
- throws java.security.cert.CertificateExpiredException,
- java.security.cert.CertificateNotYetValidException
- {
-
- }
-
- public void checkValidity(Date date)
- throws java.security.cert.CertificateExpiredException,
- java.security.cert.CertificateNotYetValidException
- {
- }
-
- public int getBasicConstraints()
- {
- return 0;
- }
-
- public Principal getIssuerDN()
- {
- return null;
- }
-
- public boolean[] getIssuerUniqueID()
- {
- return null;
- }
-
- public boolean[] getKeyUsage()
- {
- return null;
- }
-
- public Date getNotAfter()
- {
- return null;
- }
-
- public Date getNotBefore()
- {
- return null;
- }
-
- public BigInteger getSerialNumber()
- {
- return null;
- }
-
- public String getSigAlgName()
- {
- return null;
- }
-
- public String getSigAlgOID()
- {
- return null;
- }
-
- public byte[] getSigAlgParams()
- {
- return null;
- }
-
- public byte[] getSignature()
- {
- return null;
- }
-
- public Principal getSubjectDN()
- {
- return m_principal;
- }
-
- public boolean[] getSubjectUniqueID()
- {
- return null;
- }
-
- public byte[] getTBSCertificate()
- throws java.security.cert.CertificateEncodingException
- {
- return null;
- }
-
- public int getVersion()
- {
- return 0;
- }
-
- public byte[] getEncoded()
- throws java.security.cert.CertificateEncodingException
- {
- return null;
- }
-
- public PublicKey getPublicKey()
- {
- return null;
- }
-
- public String toString()
- {
- return m_principal.getName();
- }
-
- public void verify(PublicKey key)
- throws java.security.cert.CertificateException,
- NoSuchAlgorithmException, InvalidKeyException,
- NoSuchProviderException, SignatureException
- {
-
- }
-
- public void verify(PublicKey key, String sigProvider)
- throws java.security.cert.CertificateException,
- NoSuchAlgorithmException, InvalidKeyException,
- NoSuchProviderException, SignatureException
- {
-
- }
-
- public Set getCriticalExtensionOIDs()
- {
- return null;
- }
-
- public byte[] getExtensionValue(String arg0)
- {
- return null;
- }
-
- public Set getNonCriticalExtensionOIDs()
- {
- return null;
- }
-
- public boolean hasUnsupportedCriticalExtension()
- {
- return false;
- }
-
- public boolean equals(Object o)
- {
- return this == o;
- }
-
- public int hashCode()
- {
- return System.identityHashCode(this);
- }
-
- }
-
- public AccessControlContext getAccessControlContext(final String[] signers)
- {
- Map certificates = new HashMap();
- for (int i = 0; i < signers.length; i++)
- {
- StringTokenizer tok = new StringTokenizer(signers[i], ";");
- List certsList = new ArrayList();
- while (tok.hasMoreTokens())
- {
- certsList.add(tok.nextToken());
- }
- String[] certs = (String[]) certsList.toArray(new String[certsList
- .size()]);
-
- X509Certificate key = new FakeCert(certs[0]);
- List certList = new ArrayList();
- certificates.put(key, certList);
- certList.add(key);
- for (int j = 1; j < certs.length; j++)
- {
- certList.add(new FakeCert(certs[j]));
- }
- }
- final FakeBundle fake = new FakeBundle(certificates);
- ProtectionDomain domain = new ProtectionDomain(null, null)
- {
- public boolean implies(Permission permission)
- {
- List posts = new ArrayList();
- Boolean result = m_pai.hasPermission("", fake, permission,
- ConditionalPermissionAdminImpl.this, this, null);
- if (result != null)
- {
- return result.booleanValue();
- }
- if (eval(posts, new BundleRevisionImpl(fake, Long.toString(fake.getBundleId())), permission, m_pai))
- {
- if (!posts.isEmpty())
- {
- return m_conditions.evalRecursive(posts);
- }
- return true;
- }
- return false;
- }
- };
- return new AccessControlContext(new ProtectionDomain[] { domain });
- }
-
- public ConditionalPermissionInfo getConditionalPermissionInfo(String name)
- {
- if (name == null)
- {
- throw new IllegalArgumentException("Name may not be null");
- }
- ConditionalPermissionInfoImpl result = null;
-
- synchronized (m_condPermInfos)
- {
- result = (ConditionalPermissionInfoImpl) m_condPermInfos.get(name);
- }
-
- if (result == null)
- {
- result = new ConditionalPermissionInfoImpl(this, name, true);
-
- result = write(result.getName(), result);
- }
-
- return result;
- }
-
- public Enumeration getConditionalPermissionInfos()
- {
- synchronized (m_condPermInfos)
- {
- return Collections.enumeration(new ArrayList(m_condPermInfos
- .values()));
- }
- }
-
- public ConditionalPermissionInfo setConditionalPermissionInfo(String name,
- ConditionInfo[] conditions, PermissionInfo[] permissions)
- {
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
- }
-
- ConditionalPermissionInfoImpl result = null;
- conditions = notNull(conditions);
- permissions = notNull(permissions);
-
- if (name != null)
- {
- synchronized (m_condPermInfos)
- {
- result = (ConditionalPermissionInfoImpl) m_condPermInfos
- .get(name);
-
- if (result == null)
- {
- result = new ConditionalPermissionInfoImpl(name,
- conditions, permissions, this, true);
- }
- else
- {
- result.setConditionsAndPermissions(conditions, permissions);
- }
- }
- }
- else
- {
- result = new ConditionalPermissionInfoImpl(conditions, permissions,
- this, true);
- }
-
- return write(result.getName(), result);
- }
-
- private PermissionInfo[] notNull(PermissionInfo[] permissions)
- {
- if (permissions == null)
- {
- return ConditionalPermissionInfoImpl.PERMISSION_INFO;
- }
- return (PermissionInfo[]) notNull((Object[]) permissions).toArray(
- EMPTY_PERMISSION_INFO);
- }
-
- private ConditionInfo[] notNull(ConditionInfo[] conditions)
- {
- if (conditions == null)
- {
- return ConditionalPermissionInfoImpl.CONDITION_INFO;
- }
- return (ConditionInfo[]) notNull((Object[]) conditions).toArray(
- EMPTY_CONDITION_INFO);
- }
-
- private List notNull(Object[] elements)
- {
- List result = new ArrayList();
-
- for (int i = 0; i < elements.length; i++)
- {
- if (elements[i] != null)
- {
- result.add(elements[i]);
- }
- }
-
- return result;
- }
-
- // The thread local stack used to keep track of bundle protection domains we
- // still expect to see.
- private final ThreadLocal m_stack = new ThreadLocal();
-
- /**
- * This method does the actual permission check. If it is not a direct check
- * it will try to determine the other bundle domains that will follow
- * automatically in case this is the first check in one permission check. If
- * not then it will keep track of which domains we have already see. While
- * it keeps track it builds up a list of postponed tuples which it will
- * evaluate at the last domain. See the core spec 9.5.1 and following for a
- * general description.
- *
- * @param felixBundle
- * the bundle in question.
- * @param loader
- * the content loader of the bundle to get access to the jar to
- * check for local permissions.
- * @param root
- * the bundle id.
- * @param signers
- * the signers (this is to support the ACC based on signers)
- * @param pd
- * the bundle protection domain
- * @param permission
- * the permission currently checked
- * @param direct
- * whether this is a direct check or not. direct check will not
- * expect any further bundle domains on the stack
- * @return true in case the permission is granted or there are postponed
- * tuples false if not. Again, see the spec for more explanations.
- */
- public boolean hasPermission(BundleRevisionImpl module, Content content,
- ProtectionDomain pd, Permission permission, boolean direct, Object admin)
- {
- // System.out.println(felixBundle + "-" + permission);
- List domains = null;
- List tuples = null;
- Object[] entry = null;
- // first see whether this is the normal case (the special case is for
- // the ACC based on signers).
- // In case of a direct call we don't need to look for other pds
- if (direct)
- {
- domains = new ArrayList();
- tuples = new ArrayList();
- domains.add(pd);
- }
- else
- {
- // Get the other pds from the stck
- entry = (Object[]) m_stack.get();
-
- // if there are none then get them from the gripper
- if (entry == null)
- {
- entry = new Object[] { new ArrayList(DomainGripper.grab()),
- new ArrayList() };
- }
- else
- {
- m_stack.set(null);
- }
-
- domains = (List) entry[0];
- tuples = (List) entry[1];
- if (!domains.contains(pd))
- {
- // We have been called directly without the direct flag
- domains.clear();
- domains.add(pd);
- }
- }
-
- // check the local permissions. they need to all the permission if there
- // are any
- if (!impliesLocal(module.getBundle(), content, permission))
- {
- return false;
- }
-
- List posts = new ArrayList();
-
- boolean result = eval(posts, module, permission, admin);
-
- domains.remove(pd);
-
- // We postponed tuples
- if (!posts.isEmpty())
- {
- tuples.add(posts);
- }
-
- // Are we at the end or this was a direct call?
- if (domains.isEmpty())
- {
- m_stack.set(null);
- // Now eval the postponed tupels. if the previous eval did return
- // false
- // tuples will be empty so we don't return from here.
- if (!tuples.isEmpty())
- {
- return m_conditions.evalRecursive(tuples);
- }
- }
- else
- {
- // this is to support recursive permission checks. In case we
- // trigger
- // a permission check while eval the stack is null until this point
- m_stack.set(entry);
- }
-
- return result;
- }
-
- public boolean impliesLocal(Bundle felixBundle, Content content,
- Permission permission)
- {
- return m_localPermissions.implies(content, felixBundle, permission);
- }
-
- public boolean isEmpty()
- {
- synchronized (m_condPermInfos)
- {
- return m_condPermInfos.isEmpty();
- }
- }
-
- // we need to find all conditions that apply and then check whether they
- // de note the permission in question unless the conditions are postponed
- // then we make sure their permissions imply the permission and add them
- // to the list of posts. Return true in case we pass or have posts
- // else falls and clear the posts first.
- private boolean eval(List posts, BundleRevisionImpl module, Permission permission,
- Object admin)
- {
- List condPermInfos = null;
-
- synchronized (m_condPermInfos)
- {
- if (isEmpty() && (admin == null))
- {
- return true;
- }
- condPermInfos = new ArrayList(m_condPermInfos.values());
- }
-
- // Check for implicit permissions like access to file area
- if (m_permissions.getPermissions(
- m_permissions.getImplicit(module.getBundle())).implies(permission,
- module.getBundle()))
- {
- return true;
- }
- List pls = new ArrayList();
- // now do the real thing
- for (Iterator iter = condPermInfos.iterator(); iter.hasNext();)
- {
- ConditionalPermissionInfoImpl cpi = (ConditionalPermissionInfoImpl) iter
- .next();
-
- ConditionInfo[] conditions = cpi._getConditionInfos();
-
- List currentPosts = new ArrayList();
-
- Conditions conds = m_conditions.getConditions(module, conditions);
- if (!conds.isSatisfied(currentPosts, m_permissions
- .getPermissions(cpi._getPermissionInfos()), permission))
- {
- continue;
- }
-
- if (!m_permissions.getPermissions(cpi._getPermissionInfos())
- .implies(permission, null))
- {
- continue;
- }
-
- if (currentPosts.isEmpty())
- {
- pls.add(new Object[] { cpi, null });
- break;
- }
- pls.add(new Object[] { cpi, currentPosts, conds });
- }
- while (pls.size() > 1)
- {
- if (!((ConditionalPermissionInfoImpl) ((Object[]) pls.get(pls
- .size() - 1))[0]).isAllow())
- {
- pls.remove(pls.size() - 1);
- }
- else
- {
- break;
- }
- }
- if (pls.size() == 1)
- {
- if (((Object[]) pls.get(0))[1] != null)
- {
- posts.add(pls.get(0));
- }
- return ((ConditionalPermissionInfoImpl) ((Object[]) pls.get(0))[0])
- .isAllow();
- }
- for (Iterator iter = pls.iterator(); iter.hasNext();)
- {
- posts.add(iter.next());
- }
- return !posts.isEmpty();
- }
-
- public ConditionalPermissionInfo newConditionalPermissionInfo(
- String encodedConditionalPermissionInfo)
- {
- return new ConditionalPermissionInfoImpl(
- encodedConditionalPermissionInfo);
- }
-
- public ConditionalPermissionInfo newConditionalPermissionInfo(String name,
- ConditionInfo[] conditions, PermissionInfo[] permissions, String access)
- {
- return new ConditionalPermissionInfoImpl(name, conditions, permissions,
- ConditionalPermissionAdminImpl.this, access
- .equals(ConditionalPermissionInfo.ALLOW));
- }
-
- public ConditionalPermissionUpdate newConditionalPermissionUpdate()
- {
- return new ConditionalPermissionUpdate()
- {
- List current = null;
- List out = null;
- {
- synchronized (m_condPermInfos)
- {
- current = new ArrayList(m_condPermInfos.values());
- out = new ArrayList(m_condPermInfos.values());
- }
- }
-
- public boolean commit()
- {
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
- }
-
- synchronized (m_condPermInfos)
- {
- if (current.equals(new ArrayList(m_condPermInfos.values())))
- {
- m_condPermInfos.clear();
- write(null, null);
- for (Iterator iter = out.iterator(); iter.hasNext();)
- {
- ConditionalPermissionInfoImpl cpii = (ConditionalPermissionInfoImpl) iter
- .next();
- write(cpii.getName(), cpii);
- }
- }
- else
- {
- return false;
- }
- }
- return true;
- }
-
- public List getConditionalPermissionInfos()
- {
- return out;
- }
- };
- }
-
- public boolean handlePAHandle(BundleProtectionDomain pd)
- {
- Object[] entry = (Object[]) m_stack.get();
-
- if (entry == null)
- {
- entry = new Object[] { new ArrayList(DomainGripper.grab()),
- new ArrayList() };
- }
-
- ((List) entry[0]).remove(pd);
- if (((List) entry[0]).isEmpty())
- {
- m_stack.set(null);
- if (!((List) entry[1]).isEmpty())
- {
- return m_conditions.evalRecursive(((List) entry[1]));
- }
- }
- else
- {
- m_stack.set(entry);
- }
-
- return true;
- }
-
- public void clearPD()
- {
- m_stack.set(null);
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/ConditionalPermissionInfoImpl.java b/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/ConditionalPermissionInfoImpl.java
deleted file mode 100644
index 102ace18a1..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/ConditionalPermissionInfoImpl.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.condpermadmin;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.StringTokenizer;
-
-import org.apache.felix.framework.security.util.Permissions;
-import org.osgi.service.condpermadmin.ConditionInfo;
-import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
-import org.osgi.service.permissionadmin.PermissionInfo;
-
-/**
- * Simple storage class for condperminfos. Additionally, this class can be used
- * to encode and decode infos.
- */
-public final class ConditionalPermissionInfoImpl implements
- ConditionalPermissionInfo
-{
- private static final Random RANDOM = new Random();
- static final ConditionInfo[] CONDITION_INFO = new ConditionInfo[0];
- static final PermissionInfo[] PERMISSION_INFO = new PermissionInfo[0];
- private final Object m_lock = new Object();
- private final String m_name;
- private final boolean m_allow;
- private volatile ConditionalPermissionAdminImpl m_cpai;
- private ConditionInfo[] m_conditions;
- private PermissionInfo[] m_permissions;
-
- private int parseConditionInfo(char[] encoded, int idx, List conditions) {
- String type;
- String[] args;
- try {
- int pos = idx;
-
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
-
- /* the first character must be '[' */
- if (encoded[pos] != '[') {
- throw new IllegalArgumentException("expecting open bracket");
- }
- pos++;
-
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
-
- /* type is not quoted or encoded */
- int begin = pos;
- while (!Character.isWhitespace(encoded[pos])
- && (encoded[pos] != ']')) {
- pos++;
- }
- if (pos == begin || encoded[begin] == '"') {
- throw new IllegalArgumentException("expecting type");
- }
- type = new String(encoded, begin, pos - begin);
-
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
-
- /* type may be followed by args which are quoted and encoded */
- ArrayList argsList = new ArrayList();
- while (encoded[pos] == '"') {
- pos++;
- begin = pos;
- while (encoded[pos] != '"') {
- if (encoded[pos] == '\\') {
- pos++;
- }
- pos++;
- }
- argsList.add(unescapeString(encoded, begin, pos));
- pos++;
-
- if (Character.isWhitespace(encoded[pos])) {
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
- }
- }
- args = (String[]) argsList
- .toArray(new String[argsList.size()]);
-
- /* the final character must be ']' */
- char c = encoded[pos++];
- if (c != ']') {
- throw new IllegalArgumentException("expecting close bracket");
- }
- conditions.add(new ConditionInfo(type, args));
- return pos;
- }
- catch (ArrayIndexOutOfBoundsException e) {
- throw new IllegalArgumentException("parsing terminated abruptly");
- }
- }
-
- private int parsePermissionInfo(char[] encoded, int idx, List permissions)
- {
- String parsedType = null;
- String parsedName = null;
- String parsedActions = null;
- try {
- int pos = idx;
-
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
-
- /* the first character must be '(' */
- if (encoded[pos] != '(') {
- throw new IllegalArgumentException("expecting open parenthesis");
- }
- pos++;
-
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
-
- /* type is not quoted or encoded */
- int begin = pos;
- while (!Character.isWhitespace(encoded[pos])
- && (encoded[pos] != ')')) {
- pos++;
- }
- if (pos == begin || encoded[begin] == '"') {
- throw new IllegalArgumentException("expecting type");
- }
- parsedType = new String(encoded, begin, pos - begin);
-
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
-
- /* type may be followed by name which is quoted and encoded */
- if (encoded[pos] == '"') {
- pos++;
- begin = pos;
- while (encoded[pos] != '"') {
- if (encoded[pos] == '\\') {
- pos++;
- }
- pos++;
- }
- parsedName = unescapeString(encoded, begin, pos);
- pos++;
-
- if (Character.isWhitespace(encoded[pos])) {
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
-
- /*
- * name may be followed by actions which is quoted and
- * encoded
- */
- if (encoded[pos] == '"') {
- pos++;
- begin = pos;
- while (encoded[pos] != '"') {
- if (encoded[pos] == '\\') {
- pos++;
- }
- pos++;
- }
- parsedActions = unescapeString(encoded, begin, pos);
- pos++;
-
- /* skip whitespace */
- while (Character.isWhitespace(encoded[pos])) {
- pos++;
- }
- }
- }
- }
-
- /* the final character must be ')' */
- char c = encoded[pos++];
- if (c != ')') {
- throw new IllegalArgumentException(
- "expecting close parenthesis");
- }
- permissions.add(new PermissionInfo(parsedType,parsedName, parsedActions));
- return pos;
- }
- catch (ArrayIndexOutOfBoundsException e) {
- throw new IllegalArgumentException("parsing terminated abruptly");
- }
- }
- /**
- * Takes an encoded character array and decodes it into a new String.
- */
- private static String unescapeString(char[] str, int begin, int end) {
- StringBuffer output = new StringBuffer(end - begin);
- for (int i = begin; i < end; i++) {
- char c = str[i];
- if (c == '\\') {
- i++;
- if (i < end) {
- c = str[i];
- switch (c) {
- case '"' :
- case '\\' :
- break;
- case 'r' :
- c = '\r';
- break;
- case 'n' :
- c = '\n';
- break;
- default :
- c = '\\';
- i--;
- break;
- }
- }
- }
- output.append(c);
- }
-
- return output.toString();
- }
-
- public ConditionalPermissionInfoImpl(String encoded)
- {
- encoded = encoded.trim();
- String toUpper = encoded.toUpperCase();
- if (!(toUpper.startsWith("ALLOW {") || toUpper.startsWith("DENY {")))
- {
- throw new IllegalArgumentException();
- }
- m_allow = toUpper.startsWith("ALLOW {");
- m_cpai = null;
- List conditions = new ArrayList();
- List permissions = new ArrayList();
- try {
- char[] chars = encoded.substring((m_allow ? "ALLOW {".length() : "DENY {".length())).toCharArray();
- int idx = 0;
- while (idx < chars.length)
- {
- if (Character.isWhitespace(chars[idx])) {
- idx++;
- }
- else if (chars[idx] == '[')
- {
- idx = parseConditionInfo(chars, idx, conditions);
- }
- else if (chars[idx] == '(')
- {
- idx = parsePermissionInfo(chars, idx, permissions);
- }
- else
- {
- if (chars[idx] != '}')
- {
- throw new IllegalArgumentException("Expected } but was: " + chars[idx]);
- }
- idx++;
- break;
- }
- }
- while (Character.isWhitespace(chars[idx])) {
- idx++;
- }
- if (chars[idx] == '"') {
- idx++;
- int begin = idx;
- while (chars[idx] != '"') {
- if (chars[idx] == '\\') {
- idx++;
- }
- idx++;
- }
- m_name = unescapeString(chars, begin, idx);
- }
- else {
- m_name = Long.toString(RANDOM.nextLong() ^ System.currentTimeMillis());
- }
- } catch (ArrayIndexOutOfBoundsException ex) {
- ex.printStackTrace();
- throw new IllegalArgumentException("Unable to parse conditional permission info: " + ex.getMessage());
- }
- m_conditions = conditions.isEmpty() ? CONDITION_INFO
- : (ConditionInfo[]) conditions.toArray(new ConditionInfo[conditions
- .size()]);
- m_permissions = permissions.isEmpty() ? PERMISSION_INFO
- : (PermissionInfo[]) permissions
- .toArray(new PermissionInfo[permissions.size()]);
- }
-
- public ConditionalPermissionInfoImpl(ConditionalPermissionAdminImpl cpai,
- String name, boolean access)
- {
- m_allow = access;
- m_name = name;
- m_cpai = cpai;
- m_conditions = CONDITION_INFO;
- m_permissions = PERMISSION_INFO;
- }
-
- public ConditionalPermissionInfoImpl(ConditionInfo[] conditions,
- PermissionInfo[] permisions, ConditionalPermissionAdminImpl cpai,
- boolean access)
- {
- m_allow = access;
- m_name = Long.toString(RANDOM.nextLong() ^ System.currentTimeMillis());
- m_cpai = cpai;
- m_conditions = conditions == null ? CONDITION_INFO : conditions;
- m_permissions = permisions == null ? PERMISSION_INFO : permisions;
- }
-
- public ConditionalPermissionInfoImpl(String name,
- ConditionInfo[] conditions, PermissionInfo[] permisions,
- ConditionalPermissionAdminImpl cpai, boolean access)
- {
- m_allow = access;
- m_name = (name != null) ? name : Long.toString(RANDOM.nextLong()
- ^ System.currentTimeMillis());
- m_conditions = conditions == null ? CONDITION_INFO : conditions;
- m_permissions = permisions == null ? PERMISSION_INFO : permisions;
- m_cpai = cpai;
- }
-
- public void delete()
- {
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
- }
-
- synchronized (m_lock)
- {
- m_cpai.write(m_name, null);
- m_conditions = CONDITION_INFO;
- m_permissions = PERMISSION_INFO;
- }
- }
-
- public ConditionInfo[] getConditionInfos()
- {
- synchronized (m_lock)
- {
- return (ConditionInfo[]) m_conditions.clone();
- }
- }
-
- ConditionInfo[] _getConditionInfos()
- {
- synchronized (m_lock)
- {
- return m_conditions;
- }
- }
-
- void setConditionsAndPermissions(ConditionInfo[] conditions,
- PermissionInfo[] permissions)
- {
- synchronized (m_lock)
- {
- m_conditions = conditions;
- m_permissions = permissions;
- }
- }
-
- public String getName()
- {
- return m_name;
- }
-
- public PermissionInfo[] getPermissionInfos()
- {
- synchronized (m_lock)
- {
- return (PermissionInfo[]) m_permissions.clone();
- }
- }
-
- PermissionInfo[] _getPermissionInfos()
- {
- synchronized (m_lock)
- {
- return m_permissions;
- }
- }
-
- public String getEncoded()
- {
- StringBuffer buffer = new StringBuffer();
- buffer.append(m_allow ? "ALLOW " : "DENY ");
- buffer.append('{');
- buffer.append(' ');
- synchronized (m_lock)
- {
- writeTo(m_conditions, buffer);
- writeTo(m_permissions, buffer);
- }
- buffer.append('}');
- buffer.append(' ');
- buffer.append('"');
- escapeString(m_name, buffer);
- buffer.append('"');
- return buffer.toString();
- }
-
- /**
- * This escapes the quotes, backslashes, \n, and \r in the string using a
- * backslash and appends the newly escaped string to a StringBuffer.
- */
- private static void escapeString(String str, StringBuffer output) {
- int len = str.length();
- for (int i = 0; i < len; i++) {
- char c = str.charAt(i);
- switch (c) {
- case '"' :
- case '\\' :
- output.append('\\');
- output.append(c);
- break;
- case '\r' :
- output.append("\\r");
- break;
- case '\n' :
- output.append("\\n");
- break;
- default :
- output.append(c);
- break;
- }
- }
- }
-
- private void writeTo(Object[] elements, StringBuffer buffer)
- {
- for (int i = 0; i < elements.length; i++)
- {
- buffer.append(elements[i]);
- buffer.append(' ');
- }
- }
-
- public String toString()
- {
- return getEncoded();
- }
-
- public String getAccessDecision()
- {
- return m_allow ? ConditionalPermissionInfo.ALLOW
- : ConditionalPermissionInfo.DENY;
- }
-
- public boolean isAllow()
- {
- return m_allow;
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/DomainGripper.java b/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/DomainGripper.java
deleted file mode 100644
index c9c299f789..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/condpermadmin/DomainGripper.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.condpermadmin;
-
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.AllPermission;
-import java.security.DomainCombiner;
-import java.security.Permission;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.framework.BundleProtectionDomain;
-
-/**
- * This class is a hack to get all BundleProtectionDomains currently on the
- * security stack. This way we don't need to have our own security manager set.
- */
-final class DomainGripper implements DomainCombiner, PrivilegedAction
-{
- private static final ProtectionDomain[] ALL_PERMISSION_PD = new ProtectionDomain[] { new ProtectionDomain(
- null, null)
- {
- public boolean implies(Permission perm)
- {
- return true;
- }
- } };
-
- // A per thread cache of DomainGripper objects. We might want to wrap them
- // in a softreference eventually
- private static final ThreadLocal m_cache = new ThreadLocal();
-
- private static final Permission ALL_PERMISSION = new AllPermission();
-
- private final List m_domains = new ArrayList();
-
- private AccessControlContext m_system = null;
-
- /**
- * Get all bundle protection domains and add them to the m_domains. Then
- * return the ALL_PERMISSION_PD.
- */
- public ProtectionDomain[] combine(ProtectionDomain[] current,
- ProtectionDomain[] assigned)
- {
- filter(current, m_domains);
- filter(assigned, m_domains);
-
- return ALL_PERMISSION_PD;
- }
-
- private void filter(ProtectionDomain[] assigned, List domains)
- {
- if (assigned != null)
- {
- for (int i = 0; i < assigned.length; i++)
- {
- if ((assigned[i].getClass() == BundleProtectionDomain.class)
- && !domains.contains(assigned[i]))
- {
- domains.add(assigned[i]);
- }
- }
- }
- }
-
- /**
- * Get the current bundle protection domains on the stack up to the last
- * privileged call.
- */
- public static List grab()
- {
- // First try to get a cached version. We cache by thread.
- DomainGripper gripper = (DomainGripper) m_cache.get();
- if (gripper == null)
- {
- // there is none so create one and cache it
- gripper = new DomainGripper();
- m_cache.set(gripper);
- }
- else
- {
- // This thread has a cached version so prepare it
- gripper.m_domains.clear();
- }
-
- // Get the current context.
- gripper.m_system = AccessController.getContext();
-
- // and merge it with the current combiner (i.e., gripper)
- AccessControlContext context = (AccessControlContext) AccessController
- .doPrivileged(gripper);
-
- gripper.m_system = null;
-
- // now get the protection domains
- AccessController.doPrivileged(gripper, context);
-
- // and return them
- return gripper.m_domains;
- }
-
- public Object run()
- {
- // this is a call to merge with the current context.
- if (m_system != null)
- {
- return new AccessControlContext(m_system, this);
- }
-
- // this is a call to get the protection domains.
- AccessController.checkPermission(ALL_PERMISSION);
- return null;
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/permissionadmin/PermissionAdminImpl.java b/framework.security/src/main/java/org/apache/felix/framework/security/permissionadmin/PermissionAdminImpl.java
deleted file mode 100644
index 92617d812f..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/permissionadmin/PermissionAdminImpl.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.permissionadmin;
-
-import java.io.IOException;
-import java.security.AllPermission;
-import java.security.Permission;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.felix.framework.security.condpermadmin.ConditionalPermissionAdminImpl;
-import org.apache.felix.framework.security.util.Permissions;
-import org.apache.felix.framework.security.util.PropertiesCache;
-
-//import org.apache.felix.moduleloader.IContent;
-import org.apache.felix.framework.cache.Content;
-
-import org.osgi.framework.Bundle;
-import org.osgi.service.permissionadmin.PermissionAdmin;
-import org.osgi.service.permissionadmin.PermissionInfo;
-
-/**
- * This class is a relatively straight forward implementation of the
- * PermissionAdmin service. The only somewhat involved thing is that it respects
- * the presents of a conditionalpermissionadmin service as per spec.
- */
-// TODO: Do we need this class at all or can we just emulate it using the
-// condpermadmin?
-public final class PermissionAdminImpl implements PermissionAdmin
-{
- private static final PermissionInfo[] ALL_PERMISSION = new PermissionInfo[] { new PermissionInfo(
- AllPermission.class.getName(), "", "") };
-
- private final Map m_store = new HashMap();
-
- private final PropertiesCache m_cache;
-
- private final Permissions m_permissions;
-
- private PermissionInfo[] m_default = null;
-
- public PermissionAdminImpl(Permissions permissions, PropertiesCache cache)
- throws IOException
- {
- m_permissions = permissions;
- m_cache = cache;
- m_cache.read(PermissionInfo[].class, m_store);
- }
-
- public PermissionInfo[] getDefaultPermissions()
- {
- synchronized (m_store)
- {
- if (m_default == null)
- {
- return null;
- }
- return (PermissionInfo[]) m_default.clone();
- }
- }
-
- public synchronized String[] getLocations()
- {
- synchronized (m_store)
- {
- if (m_store.isEmpty())
- {
- return null;
- }
-
- return (String[]) m_store.keySet().toArray(
- new String[m_store.size()]);
- }
- }
-
- public PermissionInfo[] getPermissions(String location)
- {
- synchronized (m_store)
- {
- if (m_store.containsKey(location))
- {
- return (PermissionInfo[]) ((PermissionInfo[]) m_store
- .get(location)).clone();
- }
- return null;
- }
- }
-
- /**
- * This will do the actual permission check as described in the core spec
- * 10.2 It will respect a present condpermadmin service as described in
- * 9.10.
- *
- * @param location
- * the location of the bundle.
- * @param bundle
- * the bundle in question.
- * @param permission
- * the permission to check.
- * @param cpai
- * A condpermadmin if one is present else null.
- * @param pd
- * the protectiondomain
- * @return Boolean.TRUE if the location is bound and the permission is
- * granted or if there is no cpa and the default permissions imply
- * the permission Boolean.FALSE otherwise unless the location is not
- * bound and their is a cpa in which case null is returned.
- */
- public Boolean hasPermission(String location, Bundle bundle,
- Permission permission, ConditionalPermissionAdminImpl cpai,
- ProtectionDomain pd, Content content)
- {
- PermissionInfo[] permissions = null;
- PermissionInfo[] defaults = null;
- boolean contains = false;
- synchronized (m_store)
- {
- contains = m_store.containsKey(location);
- permissions = (PermissionInfo[]) m_store.get(location);
- defaults = m_default;
- }
- if (contains)
- {
- if (check(permissions, permission, bundle))
- {
- return Boolean.TRUE;
- }
- return check(m_permissions.getImplicit(bundle), permission, bundle) ? Boolean.TRUE
- : Boolean.FALSE;
- }
- else if (cpai == null
- || (cpai.isEmpty() && cpai
- .impliesLocal(bundle, content, permission)))
- {
- if (defaults != null)
- {
- if (check(defaults, permission, null))
- {
- return Boolean.TRUE;
- }
- return check(m_permissions.getImplicit(bundle), permission,
- bundle) ? Boolean.TRUE : Boolean.FALSE;
- }
- else
- {
- return Boolean.TRUE;
- }
- }
- else
- {
- return null;
- }
- }
-
- private boolean check(PermissionInfo[] permissions, Permission permission,
- Bundle bundle)
- {
- Permissions permissionsObject = m_permissions
- .getPermissions(permissions);
-
- return permissionsObject.implies(permission, bundle);
- }
-
- public void setDefaultPermissions(PermissionInfo[] permissions)
- {
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
- }
-
- synchronized (m_cache)
- {
- PermissionInfo[] def = null;
- Map store = null;
- synchronized (m_store)
- {
- def = m_default;
- store = new HashMap(m_store);
-
- m_default = (permissions != null) ? notNull(permissions) : null;
- }
-
- try
- {
- m_cache.write(setDefaults(store, def));
- }
- catch (IOException ex)
- {
- synchronized (m_store)
- {
- m_default = def;
- }
-
- ex.printStackTrace();
- // TODO: log this
- throw new IllegalStateException(ex.getMessage());
- }
- }
- }
-
- public void setPermissions(String location, PermissionInfo[] permissions)
- {
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
- }
-
- synchronized (m_cache)
- {
- if (location != null)
- {
- Map store = null;
- Map storeCopy = null;
- PermissionInfo[] def = null;
- synchronized (m_store)
- {
- storeCopy = new HashMap(m_store);
- if (permissions != null)
- {
- m_store.put(location, notNull(permissions));
- }
- else
- {
- m_store.remove(location);
- }
- store = new HashMap(m_store);
- }
- try
- {
- m_cache.write(setDefaults(store, def));
- }
- catch (IOException ex)
- {
- synchronized (m_store)
- {
- m_store.clear();
- m_store.putAll(storeCopy);
- }
-
- ex.printStackTrace();
- // TODO: log this
- throw new IllegalStateException(ex.getMessage());
- }
- }
- }
- }
-
- private Map setDefaults(Map store, PermissionInfo[] def)
- {
- if (def != null)
- {
- store.put("DEFAULT", def);
- }
- else
- {
- store.remove("DEFAULT");
- }
- return store;
- }
-
- private PermissionInfo[] notNull(PermissionInfo[] permissions)
- {
- List result = new ArrayList();
-
- for (int i = 0; i < permissions.length; i++)
- {
- if (permissions[i] != null)
- {
- result.add(permissions[i]);
- }
- }
- return (PermissionInfo[]) result.toArray(new PermissionInfo[result
- .size()]);
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/util/BundleInputStream.java b/framework.security/src/main/java/org/apache/felix/framework/security/util/BundleInputStream.java
deleted file mode 100644
index bb78d662c9..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/util/BundleInputStream.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-
-//import org.apache.felix.moduleloader.IContent;
-import org.apache.felix.framework.cache.Content;
-
-/**
- * This class makes a given content available as a inputstream with a jar
- * content. In other words the stream can be used as input to a JarInputStream.
- */
-public final class BundleInputStream extends InputStream
-{
- private final Content m_root;
- private final Enumeration m_content;
- private final OutputStreamBuffer m_outputBuffer = new OutputStreamBuffer();
-
- private ByteArrayInputStream m_buffer = null;
- private JarOutputStream m_output = null;
-
- private static final String DUMMY_ENTRY = "__DUMMY-ENTRY__/";
-
- public BundleInputStream(Content root) throws IOException
- {
- m_root = root;
-
- List entries = new ArrayList();
-
- int count = 0;
- boolean inMetaInf = true;
- String manifest = null;
- for (Enumeration e = m_root.getEntries(); e.hasMoreElements();)
- {
- String entry = (String) e.nextElement();
- if (entry.endsWith("/"))
- {
- // ignore
- }
- else if (entry.equalsIgnoreCase("META-INF/MANIFEST.MF"))
- {
- if (manifest == null)
- {
- manifest = entry;
- }
- }
- else if (entry.toUpperCase().startsWith("META-INF/")
- && entry.indexOf('/', "META-INF/".length()) < 0)
- {
- entries.add(count++, entry);
- }
- else
- {
- entries.add(entry);
- }
- }
- entries.add(count++, DUMMY_ENTRY);
- if (manifest == null)
- {
- manifest = "META-INF/MANIFEST.MF";
- }
- m_content = Collections.enumeration(entries);
-
- try
- {
- m_output = new JarOutputStream(m_outputBuffer);
- readNext(manifest);
- m_buffer = new ByteArrayInputStream(m_outputBuffer.m_outBuffer
- .toByteArray());
-
- m_outputBuffer.m_outBuffer = null;
- }
- catch (IOException ex)
- {
- // TODO: figure out what is wrong
- ex.printStackTrace();
- throw ex;
- }
- }
-
- public int read() throws IOException
- {
- if ((m_output == null) && (m_buffer == null))
- {
- return -1;
- }
-
- if (m_buffer != null)
- {
- int result = m_buffer.read();
-
- if (result == -1)
- {
- m_buffer = null;
- return read();
- }
-
- return result;
- }
-
- if (m_content.hasMoreElements())
- {
- String current = (String) m_content.nextElement();
-
- readNext(current);
-
- if (!m_content.hasMoreElements())
- {
- m_output.close();
- m_output = null;
- }
-
- m_buffer = new ByteArrayInputStream(m_outputBuffer.m_outBuffer
- .toByteArray());
-
- m_outputBuffer.m_outBuffer = null;
- }
- else
- {
- m_output.close();
- m_output = null;
- }
-
- return read();
- }
-
- private void readNext(String path) throws IOException
- {
- m_outputBuffer.m_outBuffer = new ByteArrayOutputStream();
-
- if (path == DUMMY_ENTRY)
- {
- JarEntry entry = new JarEntry(path);
-
- m_output.putNextEntry(entry);
- }
- else
- {
- InputStream in = null;
- try
- {
- in = m_root.getEntryAsStream(path);
-
- if (in == null)
- {
- throw new IOException("Missing entry");
- }
-
- JarEntry entry = new JarEntry(path);
-
- m_output.putNextEntry(entry);
-
- byte[] buffer = new byte[4 * 1024];
-
- for (int c = in.read(buffer); c != -1; c = in.read(buffer))
- {
- m_output.write(buffer, 0, c);
- }
- }
- finally
- {
- if (in != null)
- {
- try
- {
- in.close();
- }
- catch (Exception ex)
- {
- // Not much we can do
- }
- }
- }
- }
-
- m_output.closeEntry();
-
- m_output.flush();
- }
-
- private static final class OutputStreamBuffer extends OutputStream
- {
- ByteArrayOutputStream m_outBuffer = null;
-
- public void write(int b)
- {
- m_outBuffer.write(b);
- }
-
- public void write(byte[] buffer) throws IOException
- {
- m_outBuffer.write(buffer);
- }
-
- public void write(byte[] buffer, int offset, int length)
- {
- m_outBuffer.write(buffer, offset, length);
- }
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/util/Conditions.java b/framework.security/src/main/java/org/apache/felix/framework/security/util/Conditions.java
deleted file mode 100644
index 739576cb24..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/util/Conditions.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.util;
-
-import java.security.Permission;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.security.condpermadmin.ConditionalPermissionInfoImpl;
-import org.apache.felix.framework.util.SecureAction;
-import org.osgi.framework.Bundle;
-import org.osgi.service.condpermadmin.Condition;
-import org.osgi.service.condpermadmin.ConditionInfo;
-
-/**
- * This class caches conditions instances by their infos. Furthermore, it allows
- * to eval postponed condition permission tuples as per spec (see 9.45).
- */
-public final class Conditions
-{
- private static final ThreadLocal m_conditionStack = new ThreadLocal();
- private static final Map m_conditionCache = new HashMap();
-
- private final Map m_cache = new WeakHashMap();
-
- private final BundleRevisionImpl m_module;
-
- private final ConditionInfo[] m_conditionInfos;
- private final Condition[] m_conditions;
- private final SecureAction m_action;
-
- public Conditions(SecureAction action)
- {
- this(null, null, action);
- }
-
- private Conditions(BundleRevisionImpl module, ConditionInfo[] conditionInfos,
- SecureAction action)
- {
- m_module = module;
- m_conditionInfos = conditionInfos;
- if ((module != null) && (conditionInfos != null))
- {
- synchronized (m_conditionCache)
- {
- Map conditionMap = (Map) m_conditionCache.get(module);
- if (conditionMap == null)
- {
- conditionMap = new HashMap();
- conditionMap.put(m_conditionInfos,
- new Condition[m_conditionInfos.length]);
- m_conditionCache.put(module, conditionMap);
- }
- Condition[] conditions = (Condition[]) conditionMap
- .get(m_conditionInfos);
- if (conditions == null)
- {
- conditions = new Condition[m_conditionInfos.length];
- conditionMap.put(m_conditionInfos, conditions);
- }
- m_conditions = conditions;
- }
- }
- else
- {
- m_conditions = null;
- }
- m_action = action;
- }
-
- public Conditions getConditions(BundleRevisionImpl key, ConditionInfo[] conditions)
- {
- Conditions result = null;
- Map index = null;
- synchronized (m_cache)
- {
- index = (Map) m_cache.get(conditions);
- if (index == null)
- {
- index = new HashMap();
- m_cache.put(conditions, index);
- }
- }
- synchronized (index)
- {
- if (key != null)
- {
- result = (Conditions) index.get(key);
- }
- if (result == null)
- {
- result = new Conditions(key, conditions, m_action);
- index.put(key, result);
- }
- }
-
- return result;
- }
-
- public void remove(BundleRevisionImpl key) {
- final Map conditionMap;
- synchronized (m_conditionCache)
- {
- conditionMap = (Map) m_conditionCache.remove(key);
- }
-
- if (conditionMap != null)
- {
- final Iterator iter = conditionMap.keySet().iterator();
- if (iter.hasNext())
- {
- synchronized (m_cache)
- {
- do
- {
- final Map index = (Map) m_cache.get(iter.next());
- if (index != null)
- {
- index.remove(key);
- }
- }
- while (iter.hasNext());
- }
- }
- }
- }
-
- // See whether the given list is satisfied or not
- public boolean isSatisfied(List posts, Permissions permissions,
- Permission permission)
- {
- if (m_conditionInfos == null)
- {
- return true;
- }
- boolean check = true;
- for (int i = 0; i < m_conditionInfos.length; i++)
- {
- if (m_module == null)
- {
- // TODO: check whether this is correct!
- break;
- }
- try
- {
- Condition condition = null;
- boolean add = false;
- Class clazz = Class.forName(m_conditionInfos[i].getType());
-
- synchronized (m_conditions)
- {
- if (m_conditions[i] == null)
- {
- m_conditions[i] = createCondition(m_module.getBundle(),
- clazz, m_conditionInfos[i]);
- }
- condition = m_conditions[i];
- }
-
- Object current = m_conditionStack.get();
- if (current != null)
- {
- if (current instanceof HashSet)
- {
- if (((HashSet) current).contains(clazz))
- {
- return false;
- }
- }
- else
- {
- if (current == clazz)
- {
- return false;
- }
- }
- }
-
- if (condition.isPostponed())
- {
- if (check && !permissions.implies(permission, null))
- {
- return false;
- }
- else
- {
- check = false;
- }
- posts.add(new Object[] { condition, new Integer(i) });
- }
- else
- {
-
- if (current == null)
- {
- m_conditionStack.set(clazz);
- }
- else
- {
- if (current instanceof HashSet)
- {
- if (((HashSet) current).contains(clazz))
- {
- return false;
- }
- ((HashSet) current).add(clazz);
- }
- else
- {
- if (current == clazz)
- {
- return false;
- }
- HashSet frame = new HashSet();
- frame.add(current);
- frame.add(clazz);
- m_conditionStack.set(frame);
- current = frame;
- }
- }
- try
- {
- boolean mutable = condition.isMutable();
- boolean result = condition.isSatisfied();
-
- if (!mutable
- && ((condition != Condition.TRUE) && (condition != Condition.FALSE)))
- {
- synchronized (m_conditions)
- {
- m_conditions[i] = result ? Condition.TRUE
- : Condition.FALSE;
- }
- }
- if (!result)
- {
- return false;
- }
- }
- finally
- {
- if (current == null)
- {
- m_conditionStack.set(null);
- }
- else
- {
- ((HashSet) current).remove(clazz);
- if (((HashSet) current).isEmpty())
- {
- m_conditionStack.set(null);
- }
- }
- }
- }
- }
- catch (Exception e)
- {
- // TODO: log this as per spec
- e.printStackTrace();
- return false;
- }
- }
- return true;
- }
-
- public boolean evalRecursive(List entries)
- {
- Map contexts = new HashMap();
- outer: for (Iterator iter = entries.iterator(); iter.hasNext();)
- {
- List tuples = (List) iter.next();
- inner: for (Iterator inner = tuples.iterator(); inner.hasNext();)
- {
- Object[] entry = (Object[]) inner.next();
- List conditions = (List) entry[1];
- if (conditions == null)
- {
- if (!((ConditionalPermissionInfoImpl) entry[0]).isAllow())
- {
- return false;
- }
- continue outer;
- }
- for (Iterator iter2 = conditions.iterator(); iter2.hasNext();)
- {
- Object[] condEntry = (Object[]) iter2.next();
- Condition cond = (Condition) condEntry[0];
- Dictionary context = (Dictionary) contexts.get(cond
- .getClass());
- if (context == null)
- {
- context = new Hashtable();
- contexts.put(cond.getClass(), context);
- }
- Object current = m_conditionStack.get();
- if (current == null)
- {
- m_conditionStack.set(cond.getClass());
- }
- else
- {
- if (current instanceof HashSet)
- {
- ((HashSet) current).add(cond.getClass());
- }
- else
- {
- HashSet frame = new HashSet();
- frame.add(current);
- frame.add(cond.getClass());
- m_conditionStack.set(frame);
- current = frame;
- }
- }
- boolean result;
- boolean mutable = cond.isMutable();
- try
- {
- result = cond.isSatisfied(new Condition[] { cond },
- context);
- }
- finally
- {
- if (current == null)
- {
- m_conditionStack.set(null);
- }
- else
- {
- ((HashSet) current).remove(cond.getClass());
- if (((HashSet) current).isEmpty())
- {
- m_conditionStack.set(null);
- }
- }
- }
- if (!mutable && (cond != Condition.TRUE)
- && (cond != Condition.FALSE))
- {
- synchronized (((Conditions) entry[2]).m_conditions)
- {
- ((Conditions) entry[2]).m_conditions[((Integer) condEntry[1])
- .intValue()] = result ? Condition.TRUE
- : Condition.FALSE;
- }
- }
- if (!result)
- {
- continue inner;
- }
- }
- if (!((ConditionalPermissionInfoImpl) entry[0]).isAllow())
- {
- return false;
- }
- continue outer;
- }
- return false;
- }
- return true;
- }
-
- private Condition createCondition(final Bundle bundle, final Class clazz,
- final ConditionInfo info) throws Exception
- {
- try
- {
- return (Condition) m_action.getMethod(clazz, "getCondition",
- new Class[] { Bundle.class, ConditionInfo.class }).invoke(null,
- new Object[] { bundle, info });
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- return (Condition) m_action.getConstructor(clazz,
- new Class[] { Bundle.class, ConditionInfo.class }).newInstance(
- new Object[] { bundle, info });
- }
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/util/LocalPermissions.java b/framework.security/src/main/java/org/apache/felix/framework/security/util/LocalPermissions.java
deleted file mode 100644
index 4f921c30d3..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/util/LocalPermissions.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.util;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.security.AllPermission;
-import java.security.Permission;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-//import org.apache.felix.moduleloader.IContent;
-import org.apache.felix.framework.cache.Content;
-import org.osgi.framework.Bundle;
-import org.osgi.service.permissionadmin.PermissionInfo;
-
-/**
- * A cache for local permissions. Local permissions are read from a given bundle
- * and cached for later lookup. See core spec 9.2.1.
- */
-// TODO: maybe use bundle events to clean thing up or weak/soft references
-public final class LocalPermissions
-{
- private static final PermissionInfo[] ALL_PERMISSION = new PermissionInfo[] { new PermissionInfo(
- AllPermission.class.getName(), "", "") };
-
- private final Map m_cache = new WeakHashMap();
- private final Permissions m_permissions;
-
- public LocalPermissions(Permissions permissions) throws IOException
- {
- m_permissions = permissions;
- }
-
- /**
- * Return true in case that the given permission is implied by the local
- * permissions of the given bundle or if there are none otherwise, false.
- * See core spec 9.2.1.
- *
- * @param root
- * the root to use for cacheing as a key
- * @param loader
- * the loader to get the content of the bundle from
- * @param bundle
- * the bundle in quesiton
- * @param permission
- * the permission to check
- * @return true if implied by local permissions.
- */
- public boolean implies(Content content, Bundle bundle,
- Permission permission)
- {
- PermissionInfo[] permissions = null;
-
- synchronized (m_cache)
- {
- if (!m_cache.containsKey(content))
- {
- InputStream in = null;
- try
- {
- in = content.getEntryAsStream("OSGI-INF/permissions.perm");
- if (in != null)
- {
- ArrayList perms = new ArrayList();
-
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(in, "UTF-8"));
- for (String line = reader.readLine(); line != null; line = reader
- .readLine())
- {
- String trim = line.trim();
- if (trim.startsWith("#") || trim.startsWith("//")
- || (trim.length() == 0))
- {
- continue;
- }
- perms.add(new PermissionInfo(line));
- }
-
- permissions = (PermissionInfo[]) perms
- .toArray(new PermissionInfo[perms.size()]);
- }
- }
- catch (Exception ex)
- {
- }
- finally
- {
- if (in != null)
- {
- try
- {
- in.close();
- }
- catch (IOException ex)
- {
- // TODO Auto-generated catch block
- ex.printStackTrace();
- }
- }
- }
-
- if (permissions == null)
- {
- permissions = ALL_PERMISSION;
- }
-
- m_cache.put(content, permissions);
- }
- else
- {
- permissions = (PermissionInfo[]) m_cache.get(content);
- }
- }
-
- return m_permissions.getPermissions(permissions).implies(permission,
- bundle);
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/util/Permissions.java b/framework.security/src/main/java/org/apache/felix/framework/security/util/Permissions.java
deleted file mode 100644
index df971594bd..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/util/Permissions.java
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.util;
-
-import java.io.File;
-import java.io.FilePermission;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import java.security.AccessController;
-import java.security.AllPermission;
-import java.security.Permission;
-import java.security.PermissionCollection;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.PropertyPermission;
-
-import org.apache.felix.framework.util.SecureAction;
-import org.osgi.framework.AdminPermission;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.CapabilityPermission;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.PackagePermission;
-import org.osgi.framework.ServicePermission;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.service.permissionadmin.PermissionInfo;
-
-/**
- * A permission cache that uses permission infos as keys. Permission are
- * created from the parent classloader or any exported package.
- */
-// TODO: maybe use bundle events instead of soft/weak references
-public final class Permissions
-{
- private static final ClassLoader m_classLoader = Permissions.class
- .getClassLoader();
-
- private static final Map m_permissionCache = new HashMap();
- private static final Map m_permissions = new HashMap();
- private static final ReferenceQueue m_permissionsQueue = new ReferenceQueue();
-
- private static final ThreadLocal m_stack = new ThreadLocal();
-
- private final Map m_cache;
- private final ReferenceQueue m_queue;
- private final BundleContext m_context;
- private final PermissionInfo[] m_permissionInfos;
- private final boolean m_allPermission;
- private final SecureAction m_action;
-
- public static final AllPermission ALL_PERMISSION = new AllPermission();
-
- private static final PermissionInfo[] IMPLICIT = new PermissionInfo[] { new PermissionInfo(
- FilePermission.class.getName(), "-", "read,write,delete") };
-
- Permissions(PermissionInfo[] permissionInfos, BundleContext context,
- SecureAction action)
- {
- m_context = context;
- m_permissionInfos = permissionInfos;
- m_cache = new HashMap();
- m_queue = new ReferenceQueue();
- m_action = action;
- for (int i = 0; i < m_permissionInfos.length; i++)
- {
- if (m_permissionInfos[i].getType().equals(
- AllPermission.class.getName()))
- {
- m_allPermission = true;
- return;
- }
- }
- m_allPermission = false;
- }
-
- public Permissions(BundleContext context, SecureAction action)
- {
- m_context = context;
- m_permissionInfos = null;
- m_cache = null;
- m_queue = null;
- m_allPermission = true;
- m_action = action;
- }
-
- public PermissionInfo[] getImplicit(Bundle bundle)
- {
- return new PermissionInfo[] {
- IMPLICIT[0],
- new PermissionInfo(PropertyPermission.class.getName(), "org.osgi.framework.*", "read"),
- new PermissionInfo(
- AdminPermission.class.getName(),
- "(id=" + bundle.getBundleId() + ")",
- AdminPermission.CLASS + "," + AdminPermission.METADATA + "," + AdminPermission.RESOURCE + "," + AdminPermission.CONTEXT),
- new PermissionInfo(CapabilityPermission.class.getName(), "(|(capability.namespace=osgi.ee)(capability.namespace=osgi.native))", CapabilityPermission.REQUIRE),
- new PermissionInfo(PackagePermission.class.getName(),"(package.name=java.*)",PackagePermission.IMPORT),
- new PermissionInfo(ServicePermission.class.getName(),"org.osgi.service.condition.Condition", ServicePermission.GET)
- };
- }
-
- public Permissions getPermissions(PermissionInfo[] permissionInfos)
- {
- cleanUp(m_permissionsQueue, m_permissions);
-
- Permissions result;
- synchronized (m_permissions)
- {
- result = (Permissions) m_permissions.get(new Entry(permissionInfos));
- if (result == null)
- {
- //permissionInfos may not be referenced by the new Permissions, as
- //otherwise the reference in m_permissions prevents the key from
- //being garbage collectable.
- PermissionInfo[] permissionInfosClone = new PermissionInfo[permissionInfos.length];
- System.arraycopy(permissionInfos, 0, permissionInfosClone, 0, permissionInfos.length);
- result = new Permissions(permissionInfosClone, m_context, m_action);
- m_permissions.put(
- new Entry(permissionInfos, m_permissionsQueue), result);
- }
- }
- return result;
- }
-
- private static final class Entry extends WeakReference
- {
- private final int m_hashCode;
-
- // Replace with Arrays.hashCode(Object[]) by supporting Java 5+.
- private static int hashCode(Object[] array)
- {
- int hash = 0;
- for (int i = 0; i < array.length; ++i)
- {
- Object element = array[i];
- hash = hash * 31 + ((element == null) ? 0 : element.hashCode());
- }
- return hash;
- }
-
- Entry(Object entry, ReferenceQueue queue)
- {
- super(entry, queue);
- m_hashCode = entry instanceof Object[] ? hashCode((Object[]) entry): entry.hashCode();
- }
-
- Entry(Object entry)
- {
- this(entry, null);
- }
-
- public int hashCode()
- {
- return m_hashCode;
- }
-
- public boolean equals(Object o)
- {
- if (o == null)
- {
- return false;
- }
-
- if (o == this)
- {
- return true;
- }
-
- final Object entry = get();
-
- if (o instanceof Entry)
- {
-
- final Object otherEntry = ((Entry) o).get();
- if (entry == null)
- {
- return otherEntry == null;
- }
- if (otherEntry == null)
- {
- return false;
- }
- if (!entry.getClass().equals(otherEntry.getClass()))
- {
- return false;
- }
- if (entry instanceof Object[])
- {
- return Arrays.equals((Object[])entry, (Object[])otherEntry);
- }
- return entry.equals(otherEntry);
- }
- else
- {
- return false;
- }
- }
- }
-
- private static final class DefaultPermissionCollection extends
- PermissionCollection
- {
- private final Map m_perms = new HashMap();
-
- public void add(Permission perm)
- {
- synchronized (m_perms)
- {
- m_perms.put(perm, perm);
- }
- }
-
- public Enumeration elements()
- {
- throw new IllegalStateException("Not implemented");
- }
-
- public boolean implies(Permission perm)
- {
- Map perms = null;
-
- synchronized (m_perms)
- {
- perms = m_perms;
- }
-
- Permission permission = (Permission) perms.get(perm);
-
- if ((permission != null) && permission.implies(perm))
- {
- return true;
- }
-
- for (Iterator iter = perms.values().iterator(); iter.hasNext();)
- {
- Permission current = (Permission) iter.next();
- if ((current != null) && (current != permission)
- && current.implies(perm))
- {
- return true;
- }
- }
- return false;
- }
- }
-
- private void cleanUp(ReferenceQueue queue, Map cache)
- {
- for (Entry entry = (Entry) queue.poll(); entry != null; entry = (Entry) queue
- .poll())
- {
- synchronized (cache)
- {
- cache.remove(entry);
- }
- }
- }
-
- /**
- * @param target
- * the permission to be implied
- * @param bundle
- * if not null then allow implicit permissions like file access
- * to local data area
- * @return true if the permission is implied by this permissions object.
- */
- public boolean implies(Permission target, final Bundle bundle)
- {
- if (m_allPermission)
- {
- return true;
- }
-
- Class targetClass = target.getClass();
-
- cleanUp(m_queue, m_cache);
-
- if ((bundle != null) && targetClass == FilePermission.class)
- {
- for (int i = 0; i < m_permissionInfos.length; i++)
- {
- if (m_permissionInfos[i].getType().equals(
- FilePermission.class.getName()))
- {
- String postfix = "";
- String name = m_permissionInfos[i].getName();
- if (!"<>".equals(name))
- {
- if (name.endsWith("*") || name.endsWith("-"))
- {
- postfix = name.substring(name.length() - 1);
- name = name.substring(0, name.length() - 1);
- }
- if (!(new File(name)).isAbsolute())
- {
- BundleContext context = (BundleContext) AccessController
- .doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- return bundle.getBundleContext();
- }
- });
- if (context == null)
- {
- break;
- }
- name = m_action.getAbsolutePath(new File(context
- .getDataFile(""), name));
- }
- if (postfix.length() > 0)
- {
- if ((name.length() > 0) && !name.endsWith("/"))
- {
- name += "/" + postfix;
- }
- else
- {
- name += postfix;
- }
- }
- }
- Permission source = createPermission(new PermissionInfo(
- FilePermission.class.getName(), name,
- m_permissionInfos[i].getActions()), targetClass);
- if (source.implies(target))
- {
- return true;
- }
- }
- }
- return false;
- }
-
- Object current = m_stack.get();
-
- if (current == null)
- {
- m_stack.set(targetClass);
- }
- else
- {
- if (current instanceof HashSet)
- {
- if (((HashSet) current).contains(targetClass))
- {
- return false;
- }
- ((HashSet) current).add(targetClass);
- }
- else
- {
- if (current == targetClass)
- {
- return false;
- }
- HashSet frame = new HashSet();
- frame.add(current);
- frame.add(targetClass);
- m_stack.set(frame);
- current = frame;
- }
- }
-
- try
- {
- PermissionCollection collection = null;
-
- synchronized (m_cache)
- {
- final SoftReference collectionEntry = (SoftReference) m_cache.get(targetClass);
-
- if (collectionEntry != null)
- {
- collection = (PermissionCollection) collectionEntry.get();
- }
- }
-
- if (collection == null)
- {
- collection = target.newPermissionCollection();
-
- if (collection == null)
- {
- collection = new DefaultPermissionCollection();
- }
-
- for (int i = 0; i < m_permissionInfos.length; i++)
- {
- PermissionInfo permissionInfo = m_permissionInfos[i];
- String infoType = permissionInfo.getType();
- String permissionType = targetClass.getName();
-
- if (infoType.equals(permissionType))
- {
- Permission permission = createPermission(
- permissionInfo, targetClass);
-
- if (permission != null)
- {
- collection.add(permission);
- }
- }
- }
-
- synchronized (m_cache)
- {
- m_cache.put(new Entry(target.getClass(), m_queue),
- new SoftReference(collection));
- }
- }
-
- return collection.implies(target);
- }
- finally
- {
- if (current == null)
- {
- m_stack.set(null);
- }
- else
- {
- ((HashSet) current).remove(targetClass);
- if (((HashSet) current).isEmpty())
- {
- m_stack.set(null);
- }
- }
- }
- }
-
- private Permission addToCache(String encoded, Permission permission)
- {
- if (permission == null)
- {
- return null;
- }
-
- synchronized (m_permissionCache)
- {
- Map inner = null;
-
- SoftReference ref = (SoftReference) m_permissionCache.get(encoded);
- if (ref != null)
- {
- inner = (Map) ref.get();
- }
- if (inner == null)
- {
- inner = new HashMap();
- m_permissionCache.put(encoded,
- new SoftReference(inner));
- }
-
- inner.put(new Entry(permission.getClass()), new Entry(permission));
- }
-
- return permission;
- }
-
- private Permission getFromCache(String encoded, Class target)
- {
- synchronized (m_permissionCache)
- {
- SoftReference ref = (SoftReference) m_permissionCache.get(encoded);
- if (ref != null)
- {
- Map inner = (Map) ref.get();
- if (inner != null)
- {
- Entry entry = (Entry) inner.get(target);
- if (entry != null)
- {
- Permission result = (Permission) entry.get();
- if (result != null)
- {
- return result;
- }
- inner.remove(entry);
- }
- if (inner.isEmpty())
- {
- m_permissionCache.remove(encoded);
- }
- }
- else
- {
- m_permissionCache.remove(encoded);
- }
- }
-
- }
-
- return null;
- }
-
- private Permission createPermission(final PermissionInfo permissionInfo,
- final Class target)
- {
- return (Permission) AccessController
- .doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- Permission cached = getFromCache(permissionInfo
- .getEncoded(), target);
-
- if (cached != null)
- {
- return cached;
- }
-
- try
- {
- if (m_classLoader.loadClass(target.getName()) == target)
- {
- return addToCache(permissionInfo.getEncoded(),
- createPermission(permissionInfo.getName(),
- permissionInfo.getActions(), target));
- }
- }
- catch (ClassNotFoundException e1)
- {
- }
-
- ServiceReference[] refs = null;
- try
- {
- refs = m_context.getServiceReferences(
- PackageAdmin.class.getName(), null);
- }
- catch (InvalidSyntaxException e)
- {
- }
- if (refs != null)
- {
- for (int i = 0; i < refs.length; i++)
- {
- PackageAdmin admin = (PackageAdmin) m_context
- .getService(refs[i]);
-
- if (admin != null)
- {
- Permission result = null;
- Bundle bundle = admin.getBundle(target);
- if (bundle != null)
- {
- ExportedPackage[] exports = admin
- .getExportedPackages(bundle);
- if (exports != null)
- {
- String name = target.getName();
- name = name.substring(0, name
- .lastIndexOf('.'));
-
- for (int j = 0; j < exports.length; j++)
- {
- if (exports[j].getName().equals(
- name))
- {
- result = createPermission(
- permissionInfo.getName(),
- permissionInfo.getActions(),
- target);
- break;
- }
- }
- }
- }
-
- m_context.ungetService(refs[i]);
-
- return addToCache(permissionInfo.getEncoded(),
- result);
- }
- }
- }
-
- return null;
- }
- });
- }
-
- private Permission createPermission(String name, String action, Class target)
- {
- // System.out.println("\n\n|" + name + "|\n--\n|" + action + "|\n--\n" +
- // target + "\n\n");
- try
- {
- try
- {
- return (Permission) m_action.getConstructor(target,
- new Class[] { String.class, String.class }).newInstance(
- new Object[] { name, action });
- }
- // Fall-back to action-less constructor
- catch (NoSuchMethodException ex)
- {
- return (Permission) m_action.getConstructor(target,
- new Class[] { String.class }).newInstance(
- new Object[] { name });
- }
- }
- catch (Exception ex)
- {
- // TODO: log this or something
- }
-
- return null;
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/util/PropertiesCache.java b/framework.security/src/main/java/org/apache/felix/framework/security/util/PropertiesCache.java
deleted file mode 100644
index 6c76d39c2e..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/util/PropertiesCache.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-
-import org.apache.felix.framework.util.SecureAction;
-
-public final class PropertiesCache
-{
- private final File m_file;
-
- private final File m_tmp;
-
- private final SecureAction m_action;
-
- public PropertiesCache(File store, File tmp, SecureAction action)
- {
- m_action = action;
- m_file = store;
- m_tmp = tmp;
- }
-
- public void write(Map data) throws IOException
- {
- OutputStream out = null;
- File tmp = null;
- File tmp2 = null;
- try
- {
- tmp = m_action.createTempFile("tmp", null, m_tmp);
- tmp2 = m_action.createTempFile("tmp", null, m_tmp);
- m_action.deleteFile(tmp2);
- Exception org = null;
- try
- {
- out = m_action.getFileOutputStream(tmp);
-
- Properties store = new Properties();
-
- int count = 0;
-
- for (Iterator iter = data.entrySet().iterator(); iter.hasNext();)
- {
- Entry entry = (Entry) iter.next();
- store.setProperty(count++ + "-" + (String) entry.getKey(),
- getEncoded(entry.getValue()));
- }
-
- store.store(out, null);
- }
- catch (IOException ex)
- {
- org = ex;
- throw ex;
- }
- finally
- {
- if (out != null)
- {
- try
- {
- out.close();
- }
- catch (IOException ex)
- {
- if (org == null)
- {
- throw ex;
- }
- }
- }
- }
- if ((m_action.fileExists(m_file) && !m_action.renameFile(m_file,
- tmp2))
- || !m_action.renameFile(tmp, m_file))
- {
- throw new IOException("Unable to write permissions");
- }
- }
- catch (IOException ex)
- {
- if (!m_action.fileExists(m_file) && (tmp2 != null)
- && m_action.fileExists(tmp2))
- {
- m_action.renameFile(tmp2, m_file);
- }
- throw ex;
- }
- finally
- {
- if (tmp != null)
- {
- m_action.deleteFile(tmp);
- }
- if (tmp2 != null)
- {
- m_action.deleteFile(tmp2);
- }
- }
- }
-
- public void read(Class target, Map map) throws IOException
- {
- if (!m_file.isFile())
- {
- return;
- }
- InputStream in = null;
- Exception other = null;
- Map result = new TreeMap();
- try
- {
- in = m_action.getFileInputStream(m_file);
-
- Properties store = new Properties();
- store.load(in);
-
- for (Iterator iter = store.entrySet().iterator(); iter.hasNext();)
- {
- Entry entry = (Entry) iter.next();
- result.put(entry.getKey(), getUnencoded((String) entry
- .getValue(), target));
- }
- }
- catch (IOException ex)
- {
- other = ex;
- throw ex;
- }
- finally
- {
- if (in != null)
- {
- try
- {
- in.close();
- }
- catch (IOException ex)
- {
- if (other == null)
- {
- throw ex;
- }
- }
- }
- }
- for (Iterator iter = result.entrySet().iterator(); iter.hasNext();)
- {
- Entry entry = (Entry) iter.next();
- String key = (String) entry.getKey();
- map.put(key.substring(key.indexOf("-")), entry.getValue());
- }
- }
-
- private String getEncoded(Object target) throws IOException
- {
- Properties props = new Properties();
- if (target.getClass().isArray())
- {
-
- Object[] array = (Object[]) target;
- for (int i = 0; i < array.length; i++)
- {
- props.setProperty(Integer.toString(i), array[i].toString());
- }
-
- ByteArrayOutputStream tmp = new ByteArrayOutputStream();
- props.store(tmp, null);
- return new String(tmp.toByteArray());
- }
-
- return target.toString();
- }
-
- private Object getUnencoded(String encoded, Class target)
- throws IOException
- {
- try
- {
- if (target.isArray())
- {
- Properties props = new Properties();
- props.load(new ByteArrayInputStream(encoded.getBytes()));
- Class componentType = target.getComponentType();
- Constructor constructor = m_action.getConstructor(
- componentType, new Class[] { String.class });
- Object[] params = new Object[1];
- Object[] result = (Object[]) Array.newInstance(componentType,
- props.size());
-
- for (Iterator iter = props.entrySet().iterator(); iter
- .hasNext();)
- {
- Entry entry = (Entry) iter.next();
- params[0] = entry.getValue();
- result[Integer.parseInt((String) entry.getKey())] = constructor
- .newInstance(params);
- }
-
- return result;
- }
-
- return m_action.invoke(m_action.getConstructor(target,
- new Class[] { String.class }), new Object[] { encoded });
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
-
- throw new IOException(ex.getMessage());
- }
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/util/TrustManager.java b/framework.security/src/main/java/org/apache/felix/framework/security/util/TrustManager.java
deleted file mode 100644
index 5b2520e08e..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/util/TrustManager.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.util;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.security.KeyStore;
-import java.security.cert.CertificateFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.StringTokenizer;
-
-import org.apache.felix.framework.util.SecureAction;
-
-/*
- * TODO: the certificate stores as well as the CRLs might change over time
- * (added/removed certificates). We need a way to detect that and act on it.
- * The problem is to find a good balance between re-checking and caching...
- */
-public final class TrustManager
-{
- private final SecureAction m_action;
- private final String m_crlList;
- private final String m_typeList;
- private final String m_passwdList;
- private final String m_storeList;
- private Collection m_caCerts = null;
- private Collection m_crls = null;
-
- public TrustManager(String crlList, String typeList, String passwdList,
- String storeList, SecureAction action)
- {
- m_crlList = crlList;
- m_typeList = typeList;
- m_passwdList = passwdList;
- m_storeList = storeList;
- m_action = action;
- }
-
- private synchronized void init()
- {
- if (m_caCerts == null)
- {
- try
- {
- initCRLs();
- initCaCerts();
- }
- catch (Exception ex)
- {
- m_caCerts = new ArrayList();
- m_crls = new ArrayList();
- // TODO: log this
- ex.printStackTrace();
- }
- }
- }
-
- private void initCRLs() throws Exception
- {
- final Collection result = new ArrayList();
-
- if (m_crlList.trim().length() != 0)
- {
- CertificateFactory fac = CertificateFactory.getInstance("X509");
-
- for (StringTokenizer tok = new StringTokenizer(m_crlList, "|"); tok
- .hasMoreElements();)
- {
- InputStream input = null;
- try
- {
- input = m_action.getURLConnectionInputStream(m_action
- .createURL(null, tok.nextToken(), null)
- .openConnection());
- result.addAll(fac.generateCRLs(input));
- }
- catch (Exception ex)
- {
- // TODO: log this or something
- ex.printStackTrace();
- }
- finally
- {
- if (input != null)
- {
- try
- {
- input.close();
- }
- catch (Exception ex)
- {
- // TODO: log this or something
- ex.printStackTrace();
- }
- }
- }
- }
- }
-
- m_crls = result;
- }
-
- private void initCaCerts() throws Exception
- {
- final Collection result = new ArrayList();
-
- if (m_storeList.trim().length() != 0)
- {
-
- StringTokenizer storeTok = new StringTokenizer(m_storeList, "|");
- StringTokenizer passwdTok = new StringTokenizer(m_passwdList, "|");
- StringTokenizer typeTok = new StringTokenizer(m_typeList, "|");
-
- while (storeTok.hasMoreTokens())
- {
- KeyStore ks = KeyStore.getInstance(typeTok.nextToken().trim());
-
- InputStream input = null;
- try
- {
- input = m_action.getURLConnectionInputStream(m_action
- .createURL(null, storeTok.nextToken().trim(), null)
- .openConnection());
- String pass = passwdTok.nextToken().trim();
-
- ks.load(input, (pass.length() > 0) ? pass.toCharArray()
- : null);
-
- for (Enumeration e = ks.aliases(); e.hasMoreElements();)
- {
- String alias = (String) e.nextElement();
- result.add(ks.getCertificate(alias));
- }
- }
- catch (Exception ex)
- {
- // TODO: log this or something
- ex.printStackTrace();
- }
- finally
- {
- if (input != null)
- {
- try
- {
- input.close();
- }
- catch (Exception ex)
- {
- // TODO: log this or something
- ex.printStackTrace();
- }
- }
- }
- }
- }
-
- m_caCerts = result;
- }
-
- public Collection getCRLs()
- {
- init();
-
- return m_crls;
- }
-
- public Collection getCaCerts()
- {
- init();
-
- return m_caCerts;
- }
-}
diff --git a/framework.security/src/main/java/org/apache/felix/framework/security/verifier/BundleDNParser.java b/framework.security/src/main/java/org/apache/felix/framework/security/verifier/BundleDNParser.java
deleted file mode 100644
index d24c4d42f3..0000000000
--- a/framework.security/src/main/java/org/apache/felix/framework/security/verifier/BundleDNParser.java
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * 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.
- */
-package org.apache.felix.framework.security.verifier;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.security.cert.CRL;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.security.util.BundleInputStream;
-import org.apache.felix.framework.security.util.TrustManager;
-/*
-import org.apache.felix.moduleloader.IContent;
-import org.apache.felix.moduleloader.IModule;
-*/
-import org.apache.felix.framework.cache.Content;
-
-
-import org.osgi.framework.Bundle;
-
-public final class BundleDNParser
-{
- private static final Method m_getCodeSigners;
- private static final Method m_getSignerCertPath;
- private static final Method m_getCertificates;
-
- static
- {
- Method getCodeSigners = null;
- Method getSignerCertPath = null;
- Method getCertificates = null;
- try
- {
- getCodeSigners = Class.forName("java.util.jar.JarEntry").getMethod(
- "getCodeSigners", null);
- getSignerCertPath = Class.forName("java.security.CodeSigner")
- .getMethod("getSignerCertPath", null);
- getCertificates = Class.forName("java.security.cert.CertPath")
- .getMethod("getCertificates", null);
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- getCodeSigners = null;
- getSignerCertPath = null;
- getCertificates = null;
- }
- m_getCodeSigners = getCodeSigners;
- m_getSignerCertPath = getSignerCertPath;
- m_getCertificates = getCertificates;
- }
-
- private final Logger m_logger;
- private final Map m_cache = new WeakHashMap();
- private final Map m_allCache = new WeakHashMap();
-
- private final TrustManager m_manager;
-
- public BundleDNParser(TrustManager manager, Logger logger)
- {
- m_manager = manager;
- m_logger = logger;
- }
-
- public Map getCache()
- {
- synchronized (m_cache)
- {
- return new HashMap(m_cache);
- }
- }
-
- public void put(String root, X509Certificate[] dnChains)
- {
- synchronized (m_cache)
- {
- m_cache.put(root, dnChains);
- }
- }
-
- public void checkDNChains(BundleRevisionImpl root, Content content, int signersType)
- throws Exception
- {
- if (signersType == Bundle.SIGNERS_TRUSTED)
- {
- synchronized (m_cache)
- {
- if (m_cache.containsKey(root))
- {
- Map result = (Map) m_cache.get(root);
- if ((result != null) && (result.isEmpty()))
- {
- throw new IOException("Bundle not properly signed");
- }
- return;
- }
- }
- }
- else
- {
- synchronized (m_allCache)
- {
- if (m_allCache.containsKey(root))
- {
- Map result = (Map) m_allCache.get(root);
- if ((result != null) && (result.isEmpty()))
- {
- throw new IOException("Bundle not properly signed");
- }
- return;
- }
- }
- }
-
- Map result = null;
- Exception org = null;
- try
- {
- result = _getDNChains(content,
- signersType == Bundle.SIGNERS_TRUSTED);
- }
- catch (Exception ex)
- {
- org = ex;
- }
-
- if (signersType == Bundle.SIGNERS_TRUSTED)
- {
- synchronized (m_cache)
- {
- m_cache.put(root, result);
- }
- }
- else
- {
- synchronized (m_allCache)
- {
- m_allCache.put(root, result);
- }
- }
-
- if (org != null)
- {
- throw org;
- }
- }
-
- public Map getDNChains(BundleRevisionImpl root, Content bundleRevision,
- int signersType)
- {
- if (signersType == Bundle.SIGNERS_TRUSTED)
- {
- synchronized (m_cache)
- {
- if (m_cache.containsKey(root))
- {
- Map result = (Map) m_cache.get(root);
- return (result == null) ? new HashMap() : new HashMap(
- result);
- }
- }
- }
- else
- {
- synchronized (m_allCache)
- {
- if (m_allCache.containsKey(root))
- {
- Map result = (Map) m_allCache.get(root);
- return (result == null) ? new HashMap() : new HashMap(
- result);
- }
- }
- }
-
- Map result = null;
-
- try
- {
- result = _getDNChains(bundleRevision,
- signersType == Bundle.SIGNERS_TRUSTED);
- }
- catch (Exception ex)
- {
- // Ignore
- }
-
- if (signersType == Bundle.SIGNERS_TRUSTED)
- {
- synchronized (m_cache)
- {
- m_cache.put(root, result);
- }
- }
- else
- {
- synchronized (m_allCache)
- {
- m_allCache.put(root, result);
- }
- }
-
- return (result == null) ? new HashMap() : new HashMap(result);
- }
-
- private Map _getDNChains(Content content, boolean check)
- throws IOException
- {
- X509Certificate[] certificates = null;
-
- certificates = getCertificates(new BundleInputStream(content), check);
-
- if (certificates == null)
- {
- return null;
- }
-
- List rootChains = new ArrayList();
-
- getRootChains(certificates, rootChains, check);
-
- Map result = new HashMap();
-
- for (Iterator rootIter = rootChains.iterator(); rootIter.hasNext();)
- {
- StringBuffer buffer = new StringBuffer();
-
- List chain = (List) rootIter.next();
-
- Iterator iter = chain.iterator();
-
- X509Certificate current = (X509Certificate) iter.next();
-
- result.put(current, chain);
- }
-
- if (!result.isEmpty())
- {
- return result;
- }
-
- throw new IOException();
- }
-
- private X509Certificate[] getCertificates(InputStream input, boolean check)
- throws IOException
- {
- JarInputStream bundle = new JarInputStream(input, true);
-
- if (bundle.getManifest() == null)
- {
- return null;
- }
-
- List certificateChains = new ArrayList();
-
- int count = certificateChains.size();
-
- // This is tricky: jdk1.3 doesn't say anything about what is happening
- // if a bad sig is detected on an entry - later jdk's do say that they
- // will throw a security Exception. The below should cater for both
- // behaviors.
- for (JarEntry entry = bundle.getNextJarEntry(); entry != null; entry = bundle
- .getNextJarEntry())
- {
-
- if (entry.isDirectory() ||
- (entry.getName().startsWith("META-INF/") &&
- (entry.getName().indexOf('/', "META-INF/".length()) < 0)))
- {
- continue;
- }
-
- for (byte[] tmp = new byte[4096]; bundle.read(tmp, 0, tmp.length) != -1;)
- {
- }
-
- Certificate[] certificates = entry.getCertificates();
-
- // Workaround stupid bug in the sun jdk 1.5.x - getCertificates()
- // returns null there even if there are valid certificates.
- // This is a regression bug that has been fixed in 1.6.
- //
- // We use reflection to see whether we have a SignerCertPath
- // for the entry (available >= 1.5) and if so check whether
- // there are valid certificates - don't try this at home.
- if ((certificates == null) && (m_getCodeSigners != null))
- {
- try
- {
- Object[] signers = (Object[]) m_getCodeSigners.invoke(
- entry, null);
-
- if (signers != null)
- {
- List certChains = new ArrayList();
-
- for (int i = 0; i < signers.length; i++)
- {
- Object path = m_getSignerCertPath.invoke(
- signers[i], null);
-
- certChains.addAll((List) m_getCertificates.invoke(
- path, null));
- }
-
- certificates = (Certificate[]) certChains
- .toArray(new Certificate[certChains.size()]);
- }
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- // Not much we can do - probably we are not on >= 1.5
- }
- }
-
- if ((certificates == null) || (certificates.length == 0))
- {
- return null;
- }
-
- List chains = new ArrayList();
-
- getRootChains(certificates, chains, check);
-
- if (certificateChains.isEmpty())
- {
- certificateChains.addAll(chains);
- count = certificateChains.size();
- }
- else
- {
- for (Iterator iter2 = certificateChains.iterator(); iter2
- .hasNext();)
- {
- X509Certificate cert = (X509Certificate) ((List) iter2
- .next()).get(0);
- boolean found = false;
- for (Iterator iter3 = chains.iterator(); iter3.hasNext();)
- {
- X509Certificate cert2 = (X509Certificate) ((List) iter3
- .next()).get(0);
-
- if (cert.getSubjectDN().equals(cert2.getSubjectDN())
- && cert.equals(cert2))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- iter2.remove();
- }
- }
- }
-
- if (certificateChains.isEmpty())
- {
- if (count > 0)
- {
- throw new IOException("Bad signers");
- }
- return null;
- }
- }
-
- List result = new ArrayList();
-
- for (Iterator iter = certificateChains.iterator(); iter.hasNext();)
- {
- result.addAll((List) iter.next());
- }
-
- return (X509Certificate[]) (!result.isEmpty() ? result.toArray(new X509Certificate[result
- .size()]) : null);
- }
-
- private boolean isRevoked(Certificate certificate)
- {
- for (Iterator iter = m_manager.getCRLs().iterator(); iter.hasNext();)
- {
- if (((CRL) iter.next()).isRevoked(certificate))
- {
- return true;
- }
- }
-
- return false;
- }
-
- private void getRootChains(Certificate[] certificates, List chains,
- boolean check)
- {
- List chain = new ArrayList();
-
- boolean revoked = false;
-
- for (int i = 0; i < certificates.length - 1; i++)
- {
- X509Certificate certificate = (X509Certificate) certificates[i];
-
- if (!revoked && isRevoked(certificate))
- {
- revoked = true;
- }
- if (!check || !revoked)
- {
- try
- {
- if (check)
- {
- certificate.checkValidity();
- }
-
- chain.add(certificate);
- }
- catch (CertificateException ex)
- {
- m_logger.log(Logger.LOG_WARNING, "Invalid Certificate", ex);
- revoked = true;
- }
- }
-
- if (!((X509Certificate) certificates[i + 1]).getSubjectDN().equals(
- certificate.getIssuerDN()))
- {
- if (!check || (!revoked && trusted(certificate)))
- {
- chains.add(chain);
- }
-
- revoked = false;
-
- if (!chain.isEmpty())
- {
- chain = new ArrayList();
- }
- }
- }
- // The final entry in the certs array is always
- // a "root" certificate
- if (!check || !revoked)
- {
- chain.add(certificates[certificates.length - 1]);
- if (!check
- || trusted((X509Certificate) certificates[certificates.length - 1]))
- {
- chains.add(chain);
- }
- }
- }
-
- private boolean trusted(X509Certificate cert)
- {
- if (m_manager.getCaCerts().isEmpty() || isRevoked(cert))
- {
- return false;
- }
-
- for (Iterator iter = m_manager.getCaCerts().iterator(); iter.hasNext();)
- {
- X509Certificate trustedCaCert = (X509Certificate) iter.next();
-
- if (isRevoked(trustedCaCert))
- {
- continue;
- }
-
- // If the cert has the same SubjectDN
- // as a trusted CA, check whether
- // the two certs are the same.
- if (cert.getSubjectDN().equals(trustedCaCert.getSubjectDN()))
- {
- if (cert.equals(trustedCaCert))
- {
- try
- {
- cert.checkValidity();
- trustedCaCert.checkValidity();
- return true;
- }
- catch (CertificateException ex)
- {
- // Not much we can do
- m_logger.log(Logger.LOG_WARNING, "Invalid Certificate", ex);
- }
- }
- }
- }
-
- // cert issued by any of m_trustedCaCerts ? return true : return false
- for (Iterator iter = m_manager.getCaCerts().iterator(); iter.hasNext();)
- {
- X509Certificate trustedCaCert = (X509Certificate) iter.next();
-
- if (isRevoked(trustedCaCert))
- {
- continue;
- }
-
- if (cert.getIssuerDN().equals(trustedCaCert.getSubjectDN()))
- {
- try
- {
- cert.verify(trustedCaCert.getPublicKey());
- cert.checkValidity();
- trustedCaCert.checkValidity();
- return true;
- }
- catch (Exception ex)
- {
- m_logger.log(Logger.LOG_WARNING, "Invalid Certificate", ex);
- }
- }
- }
-
- return false;
- }
-}
diff --git a/framework.tck/pom.xml b/framework.tck/pom.xml
index 35cd65a10d..e3d9314512 100644
--- a/framework.tck/pom.xml
+++ b/framework.tck/pom.xml
@@ -47,7 +47,7 @@
biz.aQute.bndbnd-resolver-maven-plugin
- 7.1.0
+ 7.4.0true
@@ -74,7 +74,7 @@
biz.aQute.bndbnd-testing-maven-plugin
- 7.1.0
+ 7.4.0truetrue
@@ -105,7 +105,7 @@
net.bytebuddybyte-buddy
- 1.17.5
+ 1.18.12test
@@ -120,12 +120,6 @@
4.13.2_1test
-
- org.junit.platform
- junit-platform-launcher
- 1.12.1
- test
- org.junit.platformjunit-platform-engine
@@ -147,7 +141,7 @@
org.apache.felixorg.apache.felix.framework
- 7.1.0-SNAPSHOT
+ 8.0.0-SNAPSHOT
diff --git a/framework.tck/tck.bndrun b/framework.tck/tck.bndrun
index 541ec5ddb6..73c87aabe1 100644
--- a/framework.tck/tck.bndrun
+++ b/framework.tck/tck.bndrun
@@ -17,7 +17,7 @@
bnd.identity;id='biz.aQute.junit'
--runfw: org.apache.felix.framework;version='[7.0.0,8)
+-runfw: org.apache.felix.framework;version='[8.0.0,9)
-tester: biz.aQute.tester.junit-platform
@@ -30,7 +30,7 @@
junit-platform-engine;version='[1.12.1,1.12.2)',\
org.opentest4j;version='[1.3.0,1.3.1)',\
junit-platform-launcher;version='[1.12.1,1.12.2)',\
- assertj-core;version='[3.27.3,3.27.4)',\
- biz.aQute.junit;version='[6.4.1,6.4.2)',\
+ assertj-core;version='[3.27.7,3.27.8)',\
+ biz.aQute.junit;version='[7.4.0,7.4.1)',\
junit-vintage-engine;version='[5.7.1,5.7.2)',\
- net.bytebuddy.byte-buddy;version='[1.17.5,1.17.6)'
\ No newline at end of file
+ net.bytebuddy.byte-buddy;version='[1.18.12,1.18.13)'
\ No newline at end of file
diff --git a/framework/README.md b/framework/README.md
new file mode 100644
index 0000000000..5ba1599112
--- /dev/null
+++ b/framework/README.md
@@ -0,0 +1,81 @@
+# Apache Felix Framework
+
+An implementation of the [OSGi Core](https://docs.osgi.org/specification/osgi.core/8.0.0/)
+specification.
+
+For documentation on how to use, launch, and/or embed the framework, see
+[`doc/README.txt`](doc/README.txt). A full change history is in
+[`doc/changelog.txt`](doc/changelog.txt).
+
+## Choosing a version
+
+The framework is maintained in two lines. They differ in the Java versions they
+support and in whether the OSGi security layer is available.
+
+| | 7.x | 8.x |
+|---|---|---|
+| Minimum Java version | 8 | 9 |
+| Runs on Java 24 and later | no | yes |
+| OSGi security layer | supported | **removed** |
+| `Require-Capability: osgi.ee` | `JavaSE 1.8` | `JavaSE 9` |
+
+Pick **7.x** if you need the security layer, or if you must run on Java 8.
+Pick **8.x** if you need to run on Java 24 or later.
+
+## What changed in 8.0.0
+
+### The OSGi security layer has been removed
+
+This is the reason for the major version bump, and the only change that requires
+action when upgrading.
+
+Java SE 24 permanently disabled the Security Manager
+([JEP 486](https://openjdk.org/jeps/486)). `System.setSecurityManager` throws
+`UnsupportedOperationException`, so the framework can no longer install one and no
+permission check can ever run. Rather than appear to enforce permissions while
+silently enforcing nothing, the framework no longer implements the security layer at
+all.
+
+What this means in practice:
+
+- **Launching with `org.osgi.framework.security` set now fails** with a
+ `SecurityException`. Previously the framework installed a Security Manager. It does
+ not fail silently, so a launcher that depends on security will not start rather than
+ start unprotected.
+- **`Bundle.hasPermission(Object)` returns `true`** unless a `SecurityProvider` has
+ been installed explicitly.
+- **No permission checks are performed** on bundle lifecycle operations, service
+ registration and lookup, resource and class loading, weaving, or resolution.
+- **The `org.apache.felix.framework.security` bundle has been removed.** It existed
+ only to supply the `PermissionAdmin` and `ConditionalPermissionAdmin` services to
+ this framework.
+
+The OSGi permission API is **still exported and unchanged**: `AdminPermission`,
+`ServicePermission`, `PackagePermission`, `BundlePermission`, `CapabilityPermission`,
+`AdaptPermission`, `Bundle.hasPermission`, `ProtectionDomain` and
+`org.apache.felix.framework.ext.SecurityProvider` all remain. Bundles that reference
+those types continue to compile and resolve; the types simply no longer gate
+anything.
+
+Bundles that merely *declare* permissions, for example by shipping
+`OSGI-INF/permissions.perm`, need no change. Only code that *relies on a permission
+being denied* is affected.
+
+### Minimum Java version raised to 9
+
+The framework inspects the caller's class context in a few places to work out which
+framework instance or bundle a call belongs to. That used to be done with a
+`SecurityManager` subclass, purely to reach the protected `getClassContext()` method.
+It now uses `java.lang.StackWalker`, which is the supported replacement and available
+from Java 9.
+
+The bundle therefore declares `Require-Capability: osgi.ee ... JavaSE 9` and will not
+resolve on a Java 8 VM. Use the 7.x line if you need Java 8.
+
+### Other changes
+
+- `sun.misc.Unsafe` is still used in one place, to obtain a trusted
+ `MethodHandles.Lookup` for taking over the JVM-wide `java.net.URL` stream handler
+ factory. It is guarded and falls back to `AccessibleObject.setAccessible`, so it
+ degrades to a warning on recent JDKs. Replacing it is tracked separately.
+- Verified on Java 17, 21, 23 and 25, including the OSGi Core R8 TCK.
diff --git a/framework/doc/changelog.txt b/framework/doc/changelog.txt
index 137717e2a3..56c2623422 100644
--- a/framework/doc/changelog.txt
+++ b/framework/doc/changelog.txt
@@ -1,3 +1,24 @@
+Changes from 7.1.0 to 8.0.0
+---------------------------
+
+** Incompatible changes
+ * The OSGi security layer has been removed. Java SE 24 permanently disabled the
+ Security Manager (JEP 486), so no permission check can run. Launching with
+ org.osgi.framework.security set now fails with a SecurityException instead of
+ starting without the requested security, Bundle.hasPermission returns true
+ unless a SecurityProvider is installed, and the
+ org.apache.felix.framework.security bundle has been removed. The OSGi
+ permission API is still exported and unchanged.
+ * The minimum Java version is now 9, so the bundle requires
+ osgi.ee JavaSE 9. Inspecting the caller's class context no longer uses a
+ SecurityManager subclass to reach getClassContext(); it uses StackWalker.
+
+** Bug
+ * FilterImpl.WrapperCapability: Filter.matches(Map) threw
+ UnsupportedOperationException for any non-empty map, and
+ WrapperCapability(ServiceReference) required the OSGi Core 1.10
+ ServiceReference.getProperties() method.
+
Changes from 7.0.5 to 7.1.0
---------------------------
diff --git a/framework/pom.xml b/framework/pom.xml
index f747013a6f..cffb6a1ce7 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -27,10 +27,13 @@
bundleApache Felix Frameworkorg.apache.felix.framework
- 7.1.0-SNAPSHOT
+ 8.0.0-SNAPSHOT$
- 8
+
+ 9scm:git:https://github.com/apache/felix-dev.git
@@ -41,15 +44,6 @@
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- -Djava.security.manager=allow
-
-
- org.moditectmoditect-maven-plugin
@@ -219,10 +213,18 @@
+
+
+ org.ow2.asm
+ asm
+ 9.8
+ test
+ org.ow2.asm
- asm-all
- 5.2
+ asm-tree
+ 9.8test
@@ -234,7 +236,7 @@
org.mockitomockito-core
- 5.17.0
+ 5.18.0test
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index fba86d21b5..24ed215399 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -25,22 +25,18 @@
import java.util.Collections;
import java.util.Dictionary;
-import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleListener;
-import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceObjects;
-import org.osgi.framework.ServicePermission;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.SynchronousBundleListener;
class BundleContextImpl implements BundleContext
{
@@ -71,22 +67,6 @@ public String getProperty(String name)
// the result is the same as if the calling thread had
// won the race condition.
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- if (!(Constants.FRAMEWORK_VERSION.equals(name) ||
- Constants.FRAMEWORK_VENDOR.equals(name) ||
- Constants.FRAMEWORK_LANGUAGE.equals(name)||
- Constants.FRAMEWORK_OS_NAME.equals(name) ||
- Constants.FRAMEWORK_OS_VERSION.equals(name) ||
- Constants.FRAMEWORK_PROCESSOR.equals(name)))
- {
- ((SecurityManager) sm).checkPermission(
- new java.util.PropertyPermission(name, "read"));
- }
- }
-
return m_felix.getProperty(name);
}
@@ -135,22 +115,7 @@ public Bundle installBundle(String location, InputStream is)
// the result is the same as if the calling thread had
// won the race condition.
- Bundle result = null;
-
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- result = m_felix.installBundle(m_bundle, location, is);
- // Do check the bundle again in case that is was installed
- // already.
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(result, AdminPermission.LIFECYCLE));
- }
- else
- {
- result = m_felix.installBundle(m_bundle, location, is);
- }
+ Bundle result = m_felix.installBundle(m_bundle, location, is);
return result;
}
@@ -205,17 +170,6 @@ public void addBundleListener(BundleListener l)
// while holding the event queue lock, so it will either succeed
// or fail.
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- if (l instanceof SynchronousBundleListener)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(m_bundle,
- AdminPermission.LISTENER));
- }
- }
-
m_felix.addBundleListener(m_bundle, l);
}
@@ -229,17 +183,6 @@ public void removeBundleListener(BundleListener l)
// the result is the same as if the calling thread had
// won the race condition.
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- if (l instanceof SynchronousBundleListener)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(m_bundle,
- AdminPermission.LISTENER));
- }
- }
-
m_felix.removeBundleListener(m_bundle, l);
}
@@ -328,19 +271,6 @@ public ServiceRegistration> registerService(
// because internally the framework acquires the bundle state
// lock to ensure state consistency.
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- if (clazzes != null)
- {
- for (String clazz : clazzes) {
- ((SecurityManager) sm).checkPermission(
- new ServicePermission(clazz, ServicePermission.REGISTER));
- }
- }
- }
-
return m_felix.registerService(this, clazzes, svcObj, dict);
}
@@ -466,13 +396,6 @@ public S getService(ServiceReference ref)
throw new NullPointerException("Specified service reference cannot be null.");
}
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new ServicePermission(ref, ServicePermission.GET));
- }
-
return m_felix.getService(m_bundle, ref, false);
}
@@ -539,13 +462,6 @@ public ServiceObjects getServiceObjects(final ServiceReference ref)
{
checkValidity();
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new ServicePermission(ref, ServicePermission.GET));
- }
-
ServiceRegistrationImpl reg =
((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
if ( reg.isValid() )
@@ -576,13 +492,6 @@ public S getService() {
// the result is the same as if the calling thread had
// won the race condition.
- final Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new ServicePermission(m_ref, ServicePermission.GET));
- }
-
return m_felix.getService(m_bundle, m_ref, true);
}
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 49cf856bbb..dddbf21399 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -40,19 +40,15 @@
import java.util.StringTokenizer;
import org.apache.felix.framework.cache.BundleArchive;
-import org.apache.felix.framework.util.SecurityManagerEx;
import org.apache.felix.framework.util.ShrinkableCollection;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.framework.util.Util;
import org.osgi.dto.DTO;
-import org.osgi.framework.AdaptPermission;
-import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
-import org.osgi.framework.ServicePermission;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.framework.hooks.bundle.CollisionHook;
@@ -246,14 +242,6 @@ synchronized void setActivator(BundleActivator activator)
@Override
public BundleContext getBundleContext()
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(this, AdminPermission.CONTEXT));
- }
-
return m_context;
}
@@ -283,63 +271,18 @@ public long getBundleId()
@Override
public URL getEntry(String name)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.RESOURCE));
- }
- catch (Exception e)
- {
- return null; // No permission
- }
- }
-
return getFramework().getBundleEntry(this, name);
}
@Override
public Enumeration getEntryPaths(String path)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.RESOURCE));
- }
- catch (Exception e)
- {
- return null; // No permission
- }
- }
-
return getFramework().getBundleEntryPaths(this, path);
}
@Override
public Enumeration findEntries(String path, String filePattern, boolean recurse)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.RESOURCE));
- }
- catch (Exception e)
- {
- return null; // No permission
- }
- }
-
return getFramework().findBundleEntries(
this, path, filePattern, recurse);
}
@@ -353,14 +296,6 @@ public Dictionary getHeaders()
@Override
public Dictionary getHeaders(String locale)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.METADATA));
- }
-
if (locale == null)
{
locale = Locale.getDefault().toString();
@@ -623,13 +558,6 @@ void setLastModified(long l)
@Override
public String getLocation()
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.METADATA));
- }
return _getLocation();
}
@@ -658,42 +586,12 @@ String _getLocation()
@Override
public URL getResource(String name)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(this, AdminPermission.RESOURCE));
- }
- catch (Exception e)
- {
- return null; // No permission
- }
- }
-
return getFramework().getBundleResource(this, name);
}
@Override
public Enumeration getResources(String name) throws IOException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(this, AdminPermission.RESOURCE));
- }
- catch (Exception e)
- {
- return null; // No permission
- }
- }
-
// Spec says we should return null when resources not found,
// even though ClassLoader.getResources() returns empty enumeration.
Enumeration e = getFramework().getBundleResources(this, name);
@@ -709,84 +607,12 @@ public Enumeration getResources(String name) throws IOException
@Override
public ServiceReference>[] getRegisteredServices()
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ServiceReference>[] refs = getFramework().getBundleRegisteredServices(this);
-
- if (refs == null)
- {
- return refs;
- }
-
- List> result = new ArrayList<>();
-
- for (ServiceReference> ref : refs) {
- try
- {
- ((SecurityManager) sm).checkPermission(new ServicePermission(
- ref, ServicePermission.GET));
-
- result.add(ref);
- }
- catch (Exception ex)
- {
- // Silently ignore.
- }
- }
-
- if (result.isEmpty())
- {
- return null;
- }
-
- return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
- }
- else
- {
- return getFramework().getBundleRegisteredServices(this);
- }
+ return getFramework().getBundleRegisteredServices(this);
}
@Override
public ServiceReference>[] getServicesInUse()
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ServiceReference>[] refs = getFramework().getBundleServicesInUse(this);
-
- if (refs == null)
- {
- return refs;
- }
-
- List> result = new ArrayList<>();
-
- for (ServiceReference> ref : refs) {
- try
- {
- ((SecurityManager) sm).checkPermission(
- new ServicePermission(ref, ServicePermission.GET));
-
- result.add(ref);
- }
- catch (Exception ex)
- {
- // Silently ignore.
- }
- }
-
- if (result.isEmpty())
- {
- return null;
- }
-
- return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
- }
-
return getFramework().getBundleServicesInUse(this);
}
@@ -968,21 +794,6 @@ public Class> loadClass(String name) throws ClassNotFoundException
throw new ClassNotFoundException("Extension bundles cannot load classes.");
}
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- try
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.CLASS));
- }
- catch (Exception ex)
- {
- throw new ClassNotFoundException("No permission.", ex);
- }
- }
-
return getFramework().loadBundleClass(this, name);
}
@@ -995,14 +806,6 @@ public void start() throws BundleException
@Override
public void start(int options) throws BundleException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.EXECUTE));
- }
-
getFramework().startBundle(this, options);
}
@@ -1015,14 +818,6 @@ public void update() throws BundleException
@Override
public void update(InputStream is) throws BundleException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.LIFECYCLE));
- }
-
getFramework().updateBundle(this, is);
}
@@ -1035,28 +830,12 @@ public void stop() throws BundleException
@Override
public void stop(int options) throws BundleException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.EXECUTE));
- }
-
getFramework().stopBundle(this, ((options & Bundle.STOP_TRANSIENT) == 0));
}
@Override
public void uninstall() throws BundleException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.LIFECYCLE));
- }
-
Map headers = getCurrentLocalizedHeader(Locale.getDefault().toString());
// Uninstall the bundle.
@@ -1080,22 +859,8 @@ public void uninstall() throws BundleException
}
}
- private static final SecurityManagerEx m_smEx = new SecurityManagerEx();
- private static final ClassLoader m_classloader = Felix.class.getClassLoader();
-
void checkAdapt(Class type)
{
- Object sm = System.getSecurityManager();
- if ((sm != null) && (getFramework().getSecurityProvider() != null))
- {
- Class>[] classes = m_smEx.getClassContext();
- if (classes.length < 3 || ((Felix.m_secureAction.getClassLoader(classes[3]) != m_classloader) ||
- !classes[3].getName().startsWith("org.apache.felix.framework.")))
- {
- ((SecurityManager) sm).checkPermission(
- new AdaptPermission(type.getName(), this, AdaptPermission.ADAPT));
- }
- }
}
@SuppressWarnings("unchecked")
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java b/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
index c9dede2d4f..f7bf5d77c8 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
@@ -29,12 +29,10 @@
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
-import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
-import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.ArrayList;
@@ -323,22 +321,7 @@ protected URLConnection openConnection(URL u) throws IOException
private static boolean getUseCachedURL(final BundleRevisionImpl revision)
{
- String property;
-
- if (System.getSecurityManager() != null)
- {
- property = AccessController.doPrivileged(new PrivilegedAction(){
- @Override
- public String run()
- {
- return getUseCachedURLProperty(revision);
- }
- });
- }
- else
- {
- property = getUseCachedURLProperty(revision);
- }
+ String property = getUseCachedURLProperty(revision);
return Boolean.parseBoolean(property);
}
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index 809bb358c9..accf994d6a 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -33,10 +33,8 @@
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleReference;
-import org.osgi.framework.CapabilityPermission;
import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.PackagePermission;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.hooks.weaving.WeavingException;
import org.osgi.framework.hooks.weaving.WeavingHook;
@@ -56,10 +54,6 @@
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
import java.security.SecureClassLoader;
import java.util.ArrayList;
import java.util.Collection;
@@ -387,37 +381,6 @@ protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundE
}
}
- if (System.getSecurityManager() != null)
- {
- for (Iterator iter = capList.iterator(); iter.hasNext();)
- {
- BundleCapability cap = iter.next();
- String bundleNamespace = cap.getNamespace();
- if (bundleNamespace.isEmpty())
- {
- iter.remove();
- }
- else if (bundleNamespace.equals(BundleRevision.PACKAGE_NAMESPACE))
- {
- if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
- new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE), PackagePermission.EXPORTONLY)))
- {
- iter.remove();
- }
- }
- else if (!bundleNamespace.equals(BundleRevision.HOST_NAMESPACE)
- && !bundleNamespace.equals(BundleRevision.BUNDLE_NAMESPACE)
- && !bundleNamespace.equals("osgi.ee"))
- {
- CapabilityPermission permission = new CapabilityPermission(bundleNamespace, CapabilityPermission.PROVIDE);
- if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(permission))
- {
- iter.remove();
- }
- }
- }
- }
-
m_resolvedCaps = Util.newImmutableList(capList);
m_includedPkgFilters = (includedPkgFilters.isEmpty())
? Collections.emptyMap() : includedPkgFilters;
@@ -740,16 +703,7 @@ private synchronized ClassLoader _getClassLoaderInternal()
if (m_classLoader == null)
{
- m_classLoader = BundleRevisionImpl.getSecureAction().run(
- new PrivilegedAction()
- {
- @Override
- public BundleClassLoader run()
- {
- return new BundleClassLoader(BundleWiringImpl.this, determineParentClassLoader(), m_logger);
- }
- }
- );
+ m_classLoader = new BundleClassLoader(BundleWiringImpl.this, determineParentClassLoader(), m_logger);
}
}
return m_classLoader;
@@ -1714,38 +1668,7 @@ private Object tryImplicitBootDelegation(final String name, final boolean isClas
// Get the class context to see the classes on the stack.
final Class>[] classes = m_sm.getClassContext();
- try
- {
- if (System.getSecurityManager() != null)
- {
- return AccessController
- .doPrivileged(new PrivilegedExceptionAction()
- {
- @Override
- public Object run() throws Exception
- {
- return doImplicitBootDelegation(classes, name,
- isClass);
- }
- });
- }
- else
- {
- return doImplicitBootDelegation(classes, name, isClass);
- }
- }
- catch (PrivilegedActionException ex)
- {
- Exception cause = ex.getException();
- if (cause instanceof ClassNotFoundException)
- {
- throw (ClassNotFoundException) cause;
- }
- else
- {
- throw (ResourceNotFoundException) cause;
- }
- }
+ return doImplicitBootDelegation(classes, name, isClass);
}
return null;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/EventDispatcher.java b/framework/src/main/java/org/apache/felix/framework/EventDispatcher.java
index 2e86fe35cf..f843ce4562 100644
--- a/framework/src/main/java/org/apache/felix/framework/EventDispatcher.java
+++ b/framework/src/main/java/org/apache/felix/framework/EventDispatcher.java
@@ -18,8 +18,6 @@
*/
package org.apache.felix.framework;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -44,7 +42,6 @@
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServicePermission;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.SynchronousBundleListener;
import org.osgi.framework.UnfilteredServiceListener;
@@ -219,12 +216,6 @@ else if (clazz == BundleListener.class)
}
else if (clazz == ServiceListener.class)
{
- // Remember security context for filtering service events.
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- acc = ((SecurityManager) sm).getSecurityContext();
- }
// We need to create a Set for keeping track of matching service
// registrations so we can fire ServiceEvent.MODIFIED_ENDMATCH
// events. We need a Set even if filter is null, since the
@@ -864,21 +855,7 @@ private static void invokeFrameworkListenerCallback(
if ((bundle.getState() == Bundle.STARTING) ||
(bundle.getState() == Bundle.ACTIVE))
{
- if (System.getSecurityManager() != null)
- {
- AccessController.doPrivileged(new PrivilegedAction() {
- @Override
- public Object run()
- {
- ((FrameworkListener) l).frameworkEvent((FrameworkEvent) event);
- return null;
- }
- });
- }
- else
- {
- ((FrameworkListener) l).frameworkEvent((FrameworkEvent) event);
- }
+ ((FrameworkListener) l).frameworkEvent((FrameworkEvent) event);
}
}
@@ -898,21 +875,7 @@ private static void invokeBundleListenerCallback(
((bundle.getState() == Bundle.STARTING) ||
(bundle.getState() == Bundle.ACTIVE)))
{
- if (System.getSecurityManager() != null)
- {
- AccessController.doPrivileged(new PrivilegedAction() {
- @Override
- public Object run()
- {
- ((BundleListener) l).bundleChanged((BundleEvent) event);
- return null;
- }
- });
- }
- else
- {
- ((BundleListener) l).bundleChanged((BundleEvent) event);
- }
+ ((BundleListener) l).bundleChanged((BundleEvent) event);
}
}
@@ -929,93 +892,38 @@ private static void invokeServiceListenerCallback(
return;
}
- // Check that the bundle has permission to get at least
- // one of the service interfaces; the objectClass property
- // of the service stores its service interfaces.
- ServiceReference> ref = ((ServiceEvent) event).getServiceReference();
-
- boolean hasPermission = true;
- Object sm = System.getSecurityManager();
- if ((acc != null) && (sm != null))
+ // Dispatch according to the filter.
+ boolean matched;
+ if (l instanceof UnfilteredServiceListener)
{
- try
- {
- ServicePermission perm =
- new ServicePermission(
- ref, ServicePermission.GET);
- ((SecurityManager) sm).checkPermission(perm, acc);
- }
- catch (Exception ex)
- {
- hasPermission = false;
- }
+ // An UnfilteredServiceListener always matches, regardless of the filter.
+ // The filter is still passed on to the Service Registry Hooks.
+ matched = true;
}
-
- if (hasPermission)
+ else
{
- // Dispatch according to the filter.
- boolean matched;
- if (l instanceof UnfilteredServiceListener)
- {
- // An UnfilteredServiceListener always matches, regardless of the filter.
- // The filter is still passed on to the Service Registry Hooks.
- matched = true;
- }
- else
- {
- matched = (filter == null)
- || filter.match(((ServiceEvent) event).getServiceReference());
- }
+ matched = (filter == null)
+ || filter.match(((ServiceEvent) event).getServiceReference());
+ }
- if (matched)
+ if (matched)
+ {
+ if ((l instanceof AllServiceListener) ||
+ Util.isServiceAssignable(bundle, ((ServiceEvent) event).getServiceReference()))
{
- if ((l instanceof AllServiceListener) ||
- Util.isServiceAssignable(bundle, ((ServiceEvent) event).getServiceReference()))
- {
- if (System.getSecurityManager() != null)
- {
- AccessController.doPrivileged(new PrivilegedAction()
- {
- @Override
- public Object run()
- {
- ((ServiceListener) l).serviceChanged((ServiceEvent) event);
- return null;
- }
- });
- }
- else
- {
- ((ServiceListener) l).serviceChanged((ServiceEvent) event);
- }
- }
+ ((ServiceListener) l).serviceChanged((ServiceEvent) event);
}
- // We need to send an MODIFIED_ENDMATCH event if the listener
- // matched previously.
- else if (((ServiceEvent) event).getType() == ServiceEvent.MODIFIED)
+ }
+ // We need to send an MODIFIED_ENDMATCH event if the listener
+ // matched previously.
+ else if (((ServiceEvent) event).getType() == ServiceEvent.MODIFIED)
+ {
+ if (filter.match(oldProps))
{
- if (filter.match(oldProps))
- {
- final ServiceEvent se = new ServiceEvent(
- ServiceEvent.MODIFIED_ENDMATCH,
- ((ServiceEvent) event).getServiceReference());
- if (System.getSecurityManager() != null)
- {
- AccessController.doPrivileged(new PrivilegedAction()
- {
- @Override
- public Object run()
- {
- ((ServiceListener) l).serviceChanged(se);
- return null;
- }
- });
- }
- else
- {
- ((ServiceListener) l).serviceChanged(se);
- }
- }
+ final ServiceEvent se = new ServiceEvent(
+ ServiceEvent.MODIFIED_ENDMATCH,
+ ((ServiceEvent) event).getServiceReference());
+ ((ServiceListener) l).serviceChanged(se);
}
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
index ee899853e6..704be317ee 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -34,7 +34,6 @@
import org.apache.felix.framework.wiring.BundleRequirementImpl;
import org.apache.felix.framework.wiring.BundleWireImpl;
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
-import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -61,9 +60,6 @@
import java.io.OutputStreamWriter;
import java.net.URI;
import java.net.URL;
-import java.security.AccessController;
-import java.security.AllPermission;
-import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -408,18 +404,6 @@ public BundleRevisionImpl getRevision()
*/
void addExtensionBundle(BundleImpl bundle) throws Exception
{
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
-
- if (!((BundleProtectionDomain) bundle.getProtectionDomain()).impliesDirect(new AllPermission()))
- {
- throw new SecurityException("Extension Bundles must have AllPermission");
- }
- }
-
String directive = ManifestParser.parseExtensionBundleHeader((String)
((BundleRevisionImpl) bundle.adapt(BundleRevision.class))
.getHeaders().get(Constants.FRAGMENT_HOST));
@@ -581,15 +565,7 @@ else if (revisionContent instanceof DirectoryContent)
{
try
{
- AccessController.doPrivileged(new PrivilegedExceptionAction()
- {
- @Override
- public Void run() throws Exception
- {
- m_extenderFramework.add(f);
- return null;
- }
- });
+ m_extenderFramework.add(f);
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index e52eac6829..f2104d2aa5 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -208,9 +208,6 @@ public class Felix extends BundleImpl implements Framework
// Shutdown gate.
private volatile ThreadGate m_shutdownGate = null;
- // Security Manager created by the framework
- private SecurityManager m_securityManager = null;
-
// Do we need to consult the default java security policy if no security provider is present?
private volatile boolean m_securityDefaultPolicy;
@@ -662,34 +659,15 @@ public void init(final FrameworkListener... listeners) throws BundleException
{
if ((getState() == Bundle.INSTALLED) || (getState() == Bundle.RESOLVED))
{
+ // Java SE 24 permanently disabled the Security Manager (JEP 486), so this
+ // framework can no longer enforce the OSGi security layer. Fail fast rather
+ // than silently launching without the security the launcher asked for.
String security = (String) m_configMap.get(Constants.FRAMEWORK_SECURITY);
if (security != null)
{
- if (System.getSecurityManager() != null)
- {
- throw new SecurityException("SecurityManager already installed");
- }
- security = security.trim();
- if (Constants.FRAMEWORK_SECURITY_OSGI.equalsIgnoreCase(security) || (security.length() == 0))
- {
- System.setSecurityManager(m_securityManager = new SecurityManager());
- }
- else
- {
- try
- {
- System.setSecurityManager(m_securityManager =
- (SecurityManager) Class.forName(security).newInstance());
- }
- catch (Throwable t)
- {
- SecurityException se =
- new SecurityException(
- "Unable to install custom SecurityManager: " + security);
- se.initCause(t);
- throw se;
- }
- }
+ throw new SecurityException(
+ "The " + Constants.FRAMEWORK_SECURITY + " property is not supported: the Java"
+ + " Security Manager is permanently disabled as of Java SE 24 (JEP 486).");
}
// Generate a framework UUID.
@@ -909,7 +887,7 @@ public void init(final FrameworkListener... listeners) throws BundleException
// We have to check with the security provider (if there is one).
// This is to avoid having bundles in the cache that have been tampered with
SecurityProvider sp = getFramework().getSecurityProvider();
- if ((sp != null) && (System.getSecurityManager() != null))
+ if (sp != null)
{
boolean locked = acquireGlobalLock();
if (!locked)
@@ -1077,7 +1055,7 @@ void setBundleProtectionDomain(BundleRevisionImpl revisionImpl) throws Exception
{
Object certificates = null;
SecurityProvider sp = getFramework().getSecurityProvider();
- if ((sp != null) && (System.getSecurityManager() != null))
+ if (sp != null)
{
BundleImpl bundleImpl = revisionImpl.getBundle();
sp.checkBundle(bundleImpl);
@@ -1160,14 +1138,6 @@ public void start(int options) throws BundleException
@Override
public void stop() throws BundleException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.EXECUTE));
- }
-
if ((getState() & (Bundle.INSTALLED | Bundle.RESOLVED)) == 0)
{
// Spec says stop() on SystemBundle should return immediately and
@@ -1254,14 +1224,6 @@ public void update() throws BundleException
@Override
public void update(InputStream is) throws BundleException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.EXECUTE));
- }
-
// Spec says to close input stream first.
try
{
@@ -1337,15 +1299,6 @@ public void run()
private void stopRefresh() throws BundleException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(new AdminPermission(this,
- AdminPermission.EXECUTE));
- }
-
-
// Stop the framework on a separate thread.
new Thread(new Runnable() {
@Override
@@ -2051,7 +2004,9 @@ boolean bundleHasPermission(BundleImpl bundle, Object obj)
throw new IllegalStateException("The bundle is uninstalled.");
}
- if (System.getSecurityManager() != null)
+ // Without a Security Manager there is nothing to enforce, so only consult an
+ // explicitly installed SecurityProvider; otherwise every permission is granted.
+ if (m_securityProvider != null)
{
try
{
@@ -2470,11 +2425,6 @@ void activateBundle(BundleImpl bundle, boolean fireEvent) throws BundleException
{
throw (BundleException) th;
}
- else if ((System.getSecurityManager() != null) &&
- (th instanceof java.security.PrivilegedActionException))
- {
- th = ((java.security.PrivilegedActionException) th).getException();
- }
// Rethrow all other exceptions as a BundleException.
throw new BundleException(
@@ -2580,14 +2530,6 @@ void updateBundle(BundleImpl bundle, InputStream is)
// Verify bundle revision.
try
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(bundle, AdminPermission.LIFECYCLE));
- }
-
// If this is an update from a normal to an extension bundle
// then attach the extension
if (!wasExtension && bundle.isExtension())
@@ -2869,11 +2811,6 @@ void stopBundle(BundleImpl bundle, boolean record)
{
throw (BundleException) rethrow;
}
- else if ((System.getSecurityManager() != null) &&
- (rethrow instanceof java.security.PrivilegedActionException))
- {
- rethrow = ((java.security.PrivilegedActionException) rethrow).getException();
- }
// Rethrow all other exceptions as a BundleException.
throw new BundleException(
@@ -3293,16 +3230,7 @@ Bundle installBundle(
releaseGlobalLock();
}
- if (!bundle.isExtension())
- {
- Object sm = System.getSecurityManager();
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(bundle, AdminPermission.LIFECYCLE));
- }
- }
- else
+ if (bundle.isExtension())
{
m_extensionManager.addExtensionBundle(bundle);
}
@@ -3931,8 +3859,6 @@ ServiceReference>[] getServiceReferences(
/**
* Retrieves Array of {@link ServiceReference} objects based on calling bundle, service class name,
* optional filter expression, and optionally filters further on the version.
- * If running under a {@link SecurityManager}, checks that the calling bundle has permissions to
- * see the service references and removes references that aren't.
* @param bundle Calling Bundle
* @param className Service Classname or null for all
* @param expr Filter Criteria or null
@@ -3944,36 +3870,9 @@ ServiceReference>[] getAllowedServiceReferences(
BundleImpl bundle, String className, String expr, boolean checkAssignable)
throws InvalidSyntaxException
{
- ServiceReference>[] refs = getServiceReferences(bundle, className, expr, checkAssignable);
-
- Object sm = System.getSecurityManager();
-
- if ((sm == null) || (refs == null))
- {
- return refs;
- }
-
- List> result = new ArrayList<>();
-
- for (ServiceReference> ref : refs) {
- try
- {
- ((SecurityManager) sm).checkPermission(new ServicePermission(ref, ServicePermission.GET));
- result.add(ref);
- }
- catch (Exception ex)
- {
- // Ignore, since we are just testing permission.
- }
- }
-
- if (result.isEmpty())
- {
- return null;
- }
-
- return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
-
+ // Without a Security Manager there are no ServicePermission restrictions to
+ // filter on, so every visible reference is allowed.
+ return getServiceReferences(bundle, className, expr, checkAssignable);
}
S getService(Bundle bundle, ServiceReference ref, boolean isServiceObjetcs)
@@ -5227,11 +5126,6 @@ public void stop(BundleContext context)
}
m_reg.unregister();
m_activatorList.clear();
- if (m_securityManager != null)
- {
- System.setSecurityManager(null);
- m_securityManager = null;
- }
m_dependencies.removeDependents(adapt(BundleRevision.class));
diff --git a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
index 2dddad0e25..5ff4982215 100644
--- a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
@@ -104,13 +104,11 @@ static class WrapperCapability extends BundleCapabilityImpl
{
private final Map m_map;
+ @SuppressWarnings("unchecked")
public WrapperCapability(Map map)
{
super(null, null, Collections.emptyMap(), Collections.emptyMap());
- m_map = Collections.emptyMap();
- if(map != null ) {
- }
- m_map.putAll(map);
+ m_map = (map == null) ? Collections.emptyMap() : (Map) map;
}
public WrapperCapability(Dictionary dict, boolean caseSensitive)
@@ -122,7 +120,14 @@ public WrapperCapability(Dictionary dict, boolean caseSensitive)
public WrapperCapability(ServiceReference> sr)
{
super(null, null, Collections.emptyMap(), Collections.emptyMap());
- m_map = new DictionaryToMap(sr.getProperties(), false);
+ // Read the properties one by one rather than via getProperties(): that
+ // method was only added in OSGi Core 1.10 and is not implemented by every
+ // ServiceReference, whereas getPropertyKeys()/getProperty() always are.
+ m_map = new StringMap();
+ for (String key : sr.getPropertyKeys())
+ {
+ m_map.put(key, sr.getProperty(key));
+ }
}
@Override
diff --git a/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java b/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
index 083ac36e02..c6c378146d 100644
--- a/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
@@ -21,7 +21,6 @@
import java.util.ArrayList;
import java.util.List;
-import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkListener;
@@ -108,14 +107,6 @@ public int getStartLevel()
@Override
public void setStartLevel(int startlevel, FrameworkListener... listeners)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(m_felix, AdminPermission.STARTLEVEL));
- }
-
if (startlevel <= 0)
{
throw new IllegalArgumentException(
@@ -178,13 +169,6 @@ public int getInitialBundleStartLevel()
@Override
public void setInitialBundleStartLevel(int startlevel)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(m_felix, AdminPermission.STARTLEVEL));
- }
m_felix.setInitialBundleStartLevel(startlevel);
}
@@ -217,14 +201,6 @@ public int getStartLevel()
@Override
public void setStartLevel(int startlevel)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(m_bundle, AdminPermission.EXECUTE));
- }
-
if (m_bundle.getBundleId() == 0)
{
throw new IllegalArgumentException(
diff --git a/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
index 693e239f24..365ccb2394 100644
--- a/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
@@ -22,7 +22,6 @@
import java.util.Collection;
import java.util.List;
-import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceRegistration;
@@ -89,13 +88,6 @@ public Bundle getBundle()
@Override
public void refreshBundles(Collection bundles, FrameworkListener... listeners)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(m_felix, AdminPermission.RESOLVE));
- }
synchronized (m_requests)
{
// Start a thread to perform asynchronous package refreshes.
@@ -116,14 +108,6 @@ public void refreshBundles(Collection bundles, FrameworkListener... list
@Override
public boolean resolveBundles(Collection bundles)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(m_felix, AdminPermission.RESOLVE));
- }
-
if (m_thread == null)
{
return false;
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index 64665e167a..f5b7bb90a0 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -18,9 +18,6 @@
*/
package org.apache.felix.framework;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
@@ -239,32 +236,7 @@ Object getService(Bundle acqBundle)
// let it create the service object.
if (m_factory != null)
{
- Object svcObj = null;
- try
- {
- if (System.getSecurityManager() != null)
- {
- svcObj = AccessController.doPrivileged(
- new ServiceFactoryPrivileged<>(acqBundle, null));
- }
- else
- {
- svcObj = getFactoryUnchecked(acqBundle);
- }
- }
- catch (PrivilegedActionException ex)
- {
- if (ex.getException() instanceof ServiceException)
- {
- throw (ServiceException) ex.getException();
- }
- else
- {
- throw new ServiceException(
- "Service factory exception: " + ex.getException().getMessage(),
- ServiceException.FACTORY_EXCEPTION, ex.getException());
- }
- }
+ Object svcObj = getFactoryUnchecked(acqBundle);
return svcObj;
}
else
@@ -281,15 +253,7 @@ void ungetService(Bundle relBundle, S svcObj)
{
try
{
- if (System.getSecurityManager() != null)
- {
- AccessController.doPrivileged(
- new ServiceFactoryPrivileged<>(relBundle, svcObj));
- }
- else
- {
- ungetFactoryUnchecked(relBundle, svcObj);
- }
+ ungetFactoryUnchecked(relBundle, svcObj);
}
catch (Throwable ex)
{
@@ -395,38 +359,6 @@ private void ungetFactoryUnchecked(Bundle bundle, S svcObj)
m_factory.ungetService(bundle, this, svcObj);
}
- /**
- * This simple class is used to ensure that when a service factory
- * is called, that no other classes on the call stack interferes
- * with the permissions of the factory itself.
- **/
- private class ServiceFactoryPrivileged implements PrivilegedExceptionAction
- {
- private Bundle m_bundle = null;
- private S m_svcObj = null;
-
- public ServiceFactoryPrivileged(Bundle bundle, S svcObj)
- {
- m_bundle = bundle;
- m_svcObj = svcObj;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public A run() throws Exception
- {
- if (m_svcObj == null)
- {
- return (A)getFactoryUnchecked(m_bundle);
- }
- else
- {
- ungetFactoryUnchecked(m_bundle, m_svcObj);
- }
- return null;
- }
- }
-
//
// ServiceReference implementation
//
diff --git a/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
index 7dcfe632a1..a88d9a3f18 100644
--- a/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
@@ -50,10 +50,7 @@
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
-import org.osgi.framework.BundlePermission;
-import org.osgi.framework.CapabilityPermission;
import org.osgi.framework.Constants;
-import org.osgi.framework.PackagePermission;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.resolver.ResolverHook;
@@ -293,11 +290,6 @@ synchronized List findProvidersInternal(
BundleCapability bcap = (BundleCapability) cap;
- // Filter according to security.
- if (invokeHooksAndSecurity && filteredBySecurity((BundleRequirement)req, bcap))
- {
- continue;
- }
// Filter already resolved hosts, since we don't support
// dynamic attachment of fragments.
if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE)
@@ -352,69 +344,6 @@ synchronized List findProvidersInternal(
return result;
}
- private boolean filteredBySecurity(BundleRequirement req, BundleCapability cap)
- {
- if (System.getSecurityManager() != null)
- {
- BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
-
- if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
- {
- if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
- new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
- PackagePermission.EXPORTONLY)) ||
- !((reqRevision == null) ||
- ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
- new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
- cap.getRevision().getBundle(),PackagePermission.IMPORT))
- ))
- {
- if (reqRevision != cap.getRevision())
- {
- return true;
- }
- }
- }
- else if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
- { if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
- new BundlePermission(cap.getRevision().getSymbolicName(), BundlePermission.PROVIDE)) ||
- !((reqRevision == null) ||
- ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
- new BundlePermission(cap.getRevision().getSymbolicName(), BundlePermission.REQUIRE))
- ))
- {
- return true;
- }
- }
- else if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
- {
- if (!((BundleProtectionDomain) reqRevision.getProtectionDomain())
- .impliesDirect(new BundlePermission(
- cap.getRevision().getSymbolicName(),
- BundlePermission.FRAGMENT))
- || !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain())
- .impliesDirect(new BundlePermission(
- cap.getRevision().getSymbolicName(),
- BundlePermission.HOST)))
- {
- return true;
- }
- }
- else if (!req.getNamespace().equals("osgi.ee"))
- {
- if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
- new CapabilityPermission(req.getNamespace(), CapabilityPermission.PROVIDE))
- ||
- !((reqRevision == null) || ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
- new CapabilityPermission(req.getNamespace(), cap.getAttributes(), cap.getRevision().getBundle(), CapabilityPermission.REQUIRE))))
- {
- return true;
- }
- }
- }
- return false;
- }
-
void resolve(
Set mandatory,
Set optional)
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
index ba524fa94e..e8f7a00cb7 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
@@ -20,14 +20,10 @@
import java.io.IOException;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
import java.net.*;
-import java.security.Permission;
import org.apache.felix.framework.util.SecureAction;
import org.apache.felix.framework.util.Util;
-import org.osgi.framework.AdminPermission;
-import org.osgi.framework.Bundle;
class URLHandlersBundleStreamHandler extends URLStreamHandler
{
@@ -49,10 +45,6 @@ public URLHandlersBundleStreamHandler(SecureAction action)
@Override
protected URLConnection openConnection(URL url) throws IOException
{
- if (!"felix".equals(url.getAuthority()))
- {
- checkPermission(url);
- }
Object framework = m_framework;
if (framework == null)
@@ -92,10 +84,7 @@ protected void parseURL(URL u, String spec, int start, int limit)
{
super.parseURL(u, spec, start, limit);
- if (checkPermission(u))
- {
- super.setURL(u, u.getProtocol(), u.getHost(), u.getPort(), "felix", u.getUserInfo(), u.getPath(), u.getQuery(), u.getRef());
- }
+ super.setURL(u, u.getProtocol(), u.getHost(), u.getPort(), "felix", u.getUserInfo(), u.getPath(), u.getQuery(), u.getRef());
}
@Override
@@ -129,62 +118,4 @@ protected java.net.InetAddress getHostAddress(URL u)
{
return null;
}
-
- private boolean checkPermission(URL u)
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- Object framework = m_framework;
- if (framework == null)
- {
- framework = URLHandlers.getFrameworkFromContext(Util.getFrameworkUUIDFromURL(u.getHost()));
- }
- try {
- long bundleId = Util.getBundleIdFromRevisionId(Util.getRevisionIdFromURL(u.getHost()));
-
- if (framework instanceof Felix)
- {
- Bundle bundle = ((Felix) framework).getBundle(bundleId);
- if (bundle != null)
- {
- sm.checkPermission(new AdminPermission(bundle, AdminPermission.RESOURCE));
- return true;
- }
- }
- else if (framework != null)
- {
- Method method = m_action.getDeclaredMethod(framework.getClass(), "getBundle", new Class[]{long.class});
- m_action.setAccesssible(method);
- Object bundle = method.invoke(framework, bundleId);
- if (bundle != null)
- {
- ClassLoader loader = m_action.getClassLoader(framework.getClass());
-
- sm.checkPermission((Permission) m_action.getConstructor(
- loader.loadClass(AdminPermission.class.getName()),
- new Class[] {loader.loadClass(Bundle.class.getName()), String.class}).newInstance(bundle, AdminPermission.RESOURCE));
- return true;
- }
- }
- else
- {
- throw new IOException("No framework context found");
- }
- }
- catch (SecurityException ex)
- {
- throw ex;
- }
- catch (Exception ex)
- {
- throw new SecurityException(ex);
- }
- }
- else
- {
- return true;
- }
- return false;
- }
}
diff --git a/framework/src/main/java/org/apache/felix/framework/WovenClassImpl.java b/framework/src/main/java/org/apache/felix/framework/WovenClassImpl.java
index e4361d95d9..be3f5cff46 100644
--- a/framework/src/main/java/org/apache/felix/framework/WovenClassImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/WovenClassImpl.java
@@ -27,8 +27,6 @@
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.util.manifestparser.ManifestParser;
-import org.osgi.framework.AdminPermission;
-import org.osgi.framework.PackagePermission;
import org.osgi.framework.hooks.weaving.WovenClass;
import org.osgi.framework.wiring.BundleWiring;
@@ -71,12 +69,6 @@ synchronized void completeDefine(Class> definedClass)
@Override
public synchronized byte[] getBytes()
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
byte[] bytes = m_bytes;
if (m_isComplete)
{
@@ -89,12 +81,6 @@ public synchronized byte[] getBytes()
@Override
public synchronized void setBytes(byte[] bytes)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
if (m_state >= TRANSFORMED)
{
throw new IllegalStateException(
@@ -193,12 +179,6 @@ public synchronized T[] toArray(T[] ts)
@Override
public synchronized boolean add(String s)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
if (s != null)
{
try
@@ -210,31 +190,14 @@ public synchronized boolean add(String s)
throw new IllegalArgumentException(
"Unable to parse dynamic import.", ex);
}
- checkImport(s);
return m_imports.add(s);
}
return false;
}
- private void checkImport(String s)
- {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null)
- {
- sm.checkPermission(new PackagePermission(s, PackagePermission.IMPORT));
- }
- }
-
@Override
public synchronized boolean remove(Object o)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
return m_imports.remove(o);
}
@@ -247,12 +210,6 @@ public synchronized boolean containsAll(Collection> collection)
@Override
public synchronized boolean addAll(Collection extends String> collection)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
for (String s : collection)
{
try
@@ -264,7 +221,6 @@ public synchronized boolean addAll(Collection extends String> collection)
throw new IllegalArgumentException(
"Unable to parse dynamic import.", ex);
}
- checkImport(s);
}
return m_imports.addAll(collection);
}
@@ -273,12 +229,6 @@ public synchronized boolean addAll(Collection extends String> collection)
public synchronized boolean addAll(int i,
Collection extends String> collection)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
for (String s : collection)
{
try
@@ -290,7 +240,6 @@ public synchronized boolean addAll(int i,
throw new IllegalArgumentException(
"Unable to parse dynamic import.", ex);
}
- checkImport(s);
}
return m_imports.addAll(i, collection);
}
@@ -298,36 +247,18 @@ public synchronized boolean addAll(int i,
@Override
public synchronized boolean removeAll(Collection> collection)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
return m_imports.removeAll(collection);
}
@Override
public synchronized boolean retainAll(Collection> collection)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
return m_imports.retainAll(collection);
}
@Override
public synchronized void clear()
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
m_imports.clear();
}
@@ -340,12 +271,6 @@ public synchronized String get(int i)
@Override
public synchronized String set(int i, String s)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
try
{
ManifestParser
@@ -355,19 +280,12 @@ public synchronized String set(int i, String s)
throw new IllegalArgumentException(
"Unable to parse dynamic import.", ex);
}
- checkImport(s);
return m_imports.set(i, s);
}
@Override
public synchronized void add(int i, String s)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
try
{
ManifestParser
@@ -378,19 +296,12 @@ public synchronized void add(int i, String s)
throw new IllegalArgumentException(
"Unable to parse dynamic import.", ex);
}
- checkImport(s);
m_imports.add(i, s);
}
@Override
public synchronized String remove(int i)
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- {
- sm.checkPermission(new AdminPermission(m_wiring.getBundle(),
- AdminPermission.WEAVE));
- }
return m_imports.remove(i);
}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
index 85895665c3..95fffc6f6c 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
@@ -44,11 +44,7 @@
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.Policy;
import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.HashMap;
@@ -72,14 +68,16 @@
/**
*