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.bnd bnd-resolver-maven-plugin - 7.1.0 + 7.4.0 true @@ -74,7 +74,7 @@ biz.aQute.bnd bnd-testing-maven-plugin - 7.1.0 + 7.4.0 true true @@ -105,7 +105,7 @@ net.bytebuddy byte-buddy - 1.17.5 + 1.18.12 test @@ -120,12 +120,6 @@ 4.13.2_1 test - - org.junit.platform - junit-platform-launcher - 1.12.1 - test - org.junit.platform junit-platform-engine @@ -147,7 +141,7 @@ org.apache.felix org.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 @@ bundle Apache Felix Framework org.apache.felix.framework - 7.1.0-SNAPSHOT + 8.0.0-SNAPSHOT $ - 8 + + 9 scm:git:https://github.com/apache/felix-dev.git @@ -41,15 +44,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - - -Djava.security.manager=allow - - - org.moditect moditect-maven-plugin @@ -219,10 +213,18 @@ + + + org.ow2.asm + asm + 9.8 + test + org.ow2.asm - asm-all - 5.2 + asm-tree + 9.8 test @@ -234,7 +236,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test 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 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 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 collection) public synchronized boolean addAll(int i, Collection 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 @@ /** *

- * This is a utility class to centralize all action that should be performed - * in a doPrivileged() block. To perform a secure action, simply - * create an instance of this class and use the specific method to perform - * the desired action. When an instance is created, this class will capture - * the security context and will then use that context when checking for - * permission to perform the action. Instances of this class should not be - * passed around since they may grant the receiver a capability to perform - * privileged actions. + * This is a utility class centralizing the I/O, reflection and class loading + * operations performed by the framework. + *

+ *

+ * Historically every method here wrapped its operation in a + * doPrivileged() block against a captured security context. Java SE 24 + * permanently disabled the Security Manager (JEP 486), so those blocks no longer + * had any effect and have been removed; each method now performs its operation + * directly. The class is retained as the framework's single point of access for + * these operations. *

**/ public class SecureAction @@ -110,144 +108,31 @@ public class SecureAction getAccessor(URL.class); } - private static final ThreadLocal m_actions = new ThreadLocal() - { - @Override - public Actions initialValue() - { - return new Actions(); - } - }; - protected static transient int BUFSIZE = 4096; - private AccessControlContext m_acc = null; - - public SecureAction() - { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INITIALIZE_CONTEXT_ACTION, null); - m_acc = (AccessControlContext) AccessController.doPrivileged(actions); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - m_acc = AccessController.getContext(); - } - } - public String getSystemProperty(String name, String def) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_PROPERTY_ACTION, name, def); - return (String) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return System.getProperty(name, def); - } + return System.getProperty(name, def); } public ClassLoader getParentClassLoader(ClassLoader loader) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_PARENT_CLASS_LOADER_ACTION, loader); - return (ClassLoader) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return loader.getParent(); - } + return loader.getParent(); } public ClassLoader getSystemClassLoader() { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_SYSTEM_CLASS_LOADER_ACTION); - return (ClassLoader) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return ClassLoader.getSystemClassLoader(); - } + return ClassLoader.getSystemClassLoader(); } public ClassLoader getClassLoader(Class clazz) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_CLASS_LOADER_ACTION, clazz); - return (ClassLoader) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return clazz.getClassLoader(); - } + return clazz.getClassLoader(); } public Class forName(String name, ClassLoader classloader) throws ClassNotFoundException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.FOR_NAME_ACTION, name, classloader); - return (Class) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof ClassNotFoundException) - { - throw (ClassNotFoundException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else if (classloader != null) + if (classloader != null) { return Class.forName(name, true, classloader); } @@ -261,873 +146,204 @@ public URL createURL(String protocol, String host, int port, String path, URLStreamHandler handler) throws MalformedURLException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.CREATE_URL_ACTION, protocol, host, - Integer.valueOf(port), path, handler); - return (URL) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof MalformedURLException) - { - throw (MalformedURLException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return new URL(protocol, host, port, path, handler); - } + return new URL(protocol, host, port, path, handler); } public URL createURL(URL context, String spec, URLStreamHandler handler) throws MalformedURLException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.CREATE_URL_WITH_CONTEXT_ACTION, context, - spec, handler); - return (URL) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof MalformedURLException) - { - throw (MalformedURLException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return new URL(context, spec, handler); - } + return new URL(context, spec, handler); } public Process exec(String command) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.EXEC_ACTION, command); - return (Process) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return Runtime.getRuntime().exec(command); - } + return Runtime.getRuntime().exec(command); } public String getAbsolutePath(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_ABSOLUTE_PATH_ACTION, file); - return (String) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.getAbsolutePath(); - } + return file.getAbsolutePath(); } public boolean fileExists(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.FILE_EXISTS_ACTION, file); - return ((Boolean) AccessController.doPrivileged(actions, m_acc)); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.exists(); - } + return file.exists(); } public boolean isFile(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.FILE_IS_FILE_ACTION, file); - return ((Boolean) AccessController.doPrivileged(actions, m_acc)); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.isFile(); - } + return file.isFile(); } public boolean isFileDirectory(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.FILE_IS_DIRECTORY_ACTION, file); - return ((Boolean) AccessController.doPrivileged(actions, m_acc)); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.isDirectory(); - } + return file.isDirectory(); } public boolean mkdir(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.MAKE_DIRECTORY_ACTION, file); - return ((Boolean) AccessController.doPrivileged(actions, m_acc)); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.mkdir(); - } + return file.mkdir(); } public boolean mkdirs(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.MAKE_DIRECTORIES_ACTION, file); - return ((Boolean) AccessController.doPrivileged(actions, m_acc)); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.mkdirs(); - } + return file.mkdirs(); } public File[] listDirectory(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.LIST_DIRECTORY_ACTION, file); - return (File[]) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.listFiles(); - } + return file.listFiles(); } public boolean renameFile(File oldFile, File newFile) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.RENAME_FILE_ACTION, oldFile, newFile); - return ((Boolean) AccessController.doPrivileged(actions, m_acc)); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return oldFile.renameTo(newFile); - } + return oldFile.renameTo(newFile); } public InputStream getInputStream(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_INPUT_ACTION, file); - return (InputStream) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return Files.newInputStream(file.toPath()); - } + return Files.newInputStream(file.toPath()); } public OutputStream getOutputStream(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_OUTPUT_ACTION, file); - return (OutputStream) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return Files.newOutputStream(file.toPath()); - } + return Files.newOutputStream(file.toPath()); } public FileInputStream getFileInputStream(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_FILE_INPUT_ACTION, file); - return (FileInputStream) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return new FileInputStream(file); - } + return new FileInputStream(file); } public FileOutputStream getFileOutputStream(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_FILE_OUTPUT_ACTION, file); - return (FileOutputStream) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return new FileOutputStream(file); - } + return new FileOutputStream(file); } public FileChannel getFileChannel(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_FILE_CHANNEL_ACTION, file); - return (FileChannel) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return FileChannel.open(file.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE); - } + return FileChannel.open(file.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE); } public URI toURI(File file) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.TO_URI_ACTION, file); - return (URI) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return file.toURI(); - } + return file.toURI(); } public InputStream getURLConnectionInputStream(URLConnection conn) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_URL_INPUT_ACTION, conn); - return (InputStream) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return conn.getInputStream(); - } + return conn.getInputStream(); } public boolean deleteFile(File target) { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.DELETE_FILE_ACTION, target); - return ((Boolean) AccessController.doPrivileged(actions, m_acc)); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return target.delete(); - } + return target.delete(); } public File createTempFile(String prefix, String suffix, File dir) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.CREATE_TMPFILE_ACTION, prefix, suffix, dir); - return (File) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return File.createTempFile(prefix, suffix, dir); - } + return File.createTempFile(prefix, suffix, dir); } public void deleteFileOnExit(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.DELETE_FILEONEXIT_ACTION, file); - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - file.deleteOnExit(); - } + file.deleteOnExit(); } public URLConnection openURLConnection(URL url) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.OPEN_URLCONNECTION_ACTION, url); - return (URLConnection) AccessController.doPrivileged(actions, - m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return url.openConnection(); - } + return url.openConnection(); } public ZipFile openZipFile(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.OPEN_ZIPFILE_ACTION, file); - return (ZipFile) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return new ZipFile(file); - } + return new ZipFile(file); } public JarFile openJarFile(File file) throws IOException { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.OPEN_JARFILE_ACTION, file); - return (JarFile) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - if (ex.getException() instanceof IOException) - { - throw (IOException) ex.getException(); - } - throw (RuntimeException) ex.getException(); - } - } - else - { - return new JarFile(file); - } + return new JarFile(file); } public void startActivator(BundleActivator activator, BundleContext context) throws Exception { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.START_ACTIVATOR_ACTION, activator, context); - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw ex.getException(); - } - } - else - { - activator.start(context); - } + activator.start(context); } public void stopActivator(BundleActivator activator, BundleContext context) throws Exception { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.STOP_ACTIVATOR_ACTION, activator, context); - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw ex.getException(); - } - } - else - { - activator.stop(context); - } - } - - public Policy getPolicy() - { - if (System.getSecurityManager() != null) - { - try - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_POLICY_ACTION, null); - return (Policy) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException ex) - { - throw (RuntimeException) ex.getException(); - } - } - else - { - return Policy.getPolicy(); - } + activator.stop(context); } public void addURLToURLClassLoader(URL extension, ClassLoader loader) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.ADD_EXTENSION_URL_ACTION, extension, loader); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - Method addURL = - URLClassLoader.class.getDeclaredMethod("addURL", - URL.class); - getAccessor(URLClassLoader.class).accept(new AccessibleObject[]{addURL}); - addURL.invoke(loader, extension); - } + Method addURL = + URLClassLoader.class.getDeclaredMethod("addURL", + URL.class); + getAccessor(URLClassLoader.class).accept(new AccessibleObject[]{addURL}); + addURL.invoke(loader, extension); } public Constructor getConstructor(Class target, Class[] types) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_CONSTRUCTOR_ACTION, target, types); - try - { - return (Constructor) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return target.getConstructor(types); - } + return target.getConstructor(types); } public Constructor getDeclaredConstructor(Class target, Class[] types) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_DECLARED_CONSTRUCTOR_ACTION, target, types); - try - { - return (Constructor) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return target.getDeclaredConstructor(types); - } + return target.getDeclaredConstructor(types); } public Method getMethod(Class target, String method, Class[] types) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_METHOD_ACTION, target, method, types); - try - { - return (Method) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return target.getMethod(method, types); - } + return target.getMethod(method, types); } public Method getDeclaredMethod(Class target, String method, Class[] types) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_DECLARED_METHOD_ACTION, target, method, types); - try - { - return (Method) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return target.getDeclaredMethod(method, types); - } + return target.getDeclaredMethod(method, types); } public void setAccesssible(Executable ao) { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.SET_ACCESSIBLE_ACTION, ao); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw (RuntimeException) e.getException(); - } - } - else - { - getAccessor(ao.getDeclaringClass()).accept(new AccessibleObject[]{ao}); - } + getAccessor(ao.getDeclaringClass()).accept(new AccessibleObject[]{ao}); } public Object invoke(Method method, Object target, Object[] params) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_METHOD_ACTION, method, target, params); - try - { - return AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - getAccessor(method.getDeclaringClass()).accept(new AccessibleObject[]{method}); + getAccessor(method.getDeclaringClass()).accept(new AccessibleObject[]{method}); - return method.invoke(target, params); - } + return method.invoke(target, params); } public Object invokeDirect(Method method, Object target, Object[] params) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_DIRECTMETHOD_ACTION, method, target, params); - try - { - return AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return method.invoke(target, params); - } - } - - public Object invoke(Constructor constructor, Object[] params) throws Exception - { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_CONSTRUCTOR_ACTION, constructor, params); - try - { - return AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return constructor.newInstance(params); - } + return method.invoke(target, params); } - - public Object getDeclaredField(Class targetClass, String name, Object target) - throws Exception - { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_FIELD_ACTION, targetClass, name, target); - try - { - return AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - Field field = targetClass.getDeclaredField(name); - getAccessor(targetClass).accept(new AccessibleObject[]{field}); - return field.get(target); - } + + public Object invoke(Constructor constructor, Object[] params) throws Exception + { + return constructor.newInstance(params); + } + + public Object getDeclaredField(Class targetClass, String name, Object target) + throws Exception + { + Field field = targetClass.getDeclaredField(name); + getAccessor(targetClass).accept(new AccessibleObject[]{field}); + return field.get(target); } public Object swapStaticFieldIfNotClass(Class targetClazz, Class targetType, Class condition, String lockName) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.SWAP_FIELD_ACTION, targetClazz, targetType, - condition, lockName); - try - { - return AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return _swapStaticFieldIfNotClass(targetClazz, targetType, - condition, lockName); - } + return _swapStaticFieldIfNotClass(targetClazz, targetType, + condition, lockName); } private static volatile Consumer m_accessorCache = null; @@ -1254,23 +470,7 @@ private static Object _swapStaticFieldIfNotClass(Class targetClazz, public void flush(ClasstargetClazz, Object lock) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.FLUSH_FIELD_ACTION, targetClazz, lock); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - _flush(targetClazz, lock); - } + _flush(targetClazz, lock); } private static void _flush(ClasstargetClazz, Object lock) throws Exception @@ -1310,23 +510,7 @@ public void invokeBundleCollisionHook( Bundle targetBundle, Collection collisionCandidates) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_BUNDLE_COLLISION_HOOK, ch, operationType, targetBundle, collisionCandidates); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - ch.filterCollisions(operationType, targetBundle, collisionCandidates); - } + ch.filterCollisions(operationType, targetBundle, collisionCandidates); } public void invokeBundleFindHook( @@ -1334,23 +518,7 @@ public void invokeBundleFindHook( BundleContext bc, Collection bundles) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_BUNDLE_FIND_HOOK, fh, bc, bundles); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - fh.find(bc, bundles); - } + fh.find(bc, bundles); } public void invokeBundleEventHook( @@ -1358,23 +526,7 @@ public void invokeBundleEventHook( BundleEvent event, Collection contexts) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_BUNDLE_EVENT_HOOK, eh, event, contexts); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - eh.event(event, contexts); - } + eh.event(event, contexts); } public void invokeWeavingHook( @@ -1382,23 +534,7 @@ public void invokeWeavingHook( org.osgi.framework.hooks.weaving.WovenClass wc) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_WEAVING_HOOK, wh, wc); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - wh.weave(wc); - } + wh.weave(wc); } public void invokeServiceEventHook( @@ -1406,23 +542,7 @@ public void invokeServiceEventHook( ServiceEvent event, Collection contexts) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_SERVICE_EVENT_HOOK, eh, event, contexts); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - eh.event(event, contexts); - } + eh.event(event, contexts); } public void invokeServiceFindHook( @@ -1431,25 +551,7 @@ public void invokeServiceFindHook( boolean allServices, Collection> references) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set( - Actions.INVOKE_SERVICE_FIND_HOOK, fh, context, name, filter, - (allServices) ? Boolean.TRUE : Boolean.FALSE, references); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - fh.find(context, name, filter, allServices, references); - } + fh.find(context, name, filter, allServices, references); } public void invokeServiceListenerHookAdded( @@ -1457,23 +559,7 @@ public void invokeServiceListenerHookAdded( Collection listeners) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_SERVICE_LISTENER_HOOK_ADDED, lh, listeners); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - lh.added(listeners); - } + lh.added(listeners); } public void invokeServiceListenerHookRemoved( @@ -1481,23 +567,7 @@ public void invokeServiceListenerHookRemoved( Collection listeners) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_SERVICE_LISTENER_HOOK_REMOVED, lh, listeners); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - lh.removed(listeners); - } + lh.removed(listeners); } public void invokeServiceEventListenerHook( @@ -1506,23 +576,7 @@ public void invokeServiceEventListenerHook( Map> listeners) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_SERVICE_EVENT_LISTENER_HOOK, elh, event, listeners); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - elh.event(event, listeners); - } + elh.event(event, listeners); } public ResolverHook invokeResolverHookFactory( @@ -1530,23 +584,7 @@ public ResolverHook invokeResolverHookFactory( Collection triggers) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_RESOLVER_HOOK_FACTORY, rhf, triggers); - try - { - return (ResolverHook) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return rhf.begin(triggers); - } + return rhf.begin(triggers); } public void invokeResolverHookResolvable( @@ -1554,23 +592,7 @@ public void invokeResolverHookResolvable( Collection candidates) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_RESOLVER_HOOK_RESOLVABLE, rh, candidates); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - rh.filterResolvable(candidates); - } + rh.filterResolvable(candidates); } public void invokeResolverHookSingleton( @@ -1579,23 +601,7 @@ public void invokeResolverHookSingleton( Collection collisions) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_RESOLVER_HOOK_SINGLETON, rh, singleton, collisions); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - rh.filterSingletonCollisions(singleton, collisions); - } + rh.filterSingletonCollisions(singleton, collisions); } public void invokeResolverHookMatches( @@ -1604,46 +610,14 @@ public void invokeResolverHookMatches( Collection candidates) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_RESOLVER_HOOK_MATCHES, rh, req, candidates); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - rh.filterMatches(req, candidates); - } + rh.filterMatches(req, candidates); } public void invokeResolverHookEnd( org.osgi.framework.hooks.resolver.ResolverHook rh) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_RESOLVER_HOOK_END, rh); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - rh.end(); - } + rh.end(); } public void invokeWovenClassListener( @@ -1651,463 +625,32 @@ public void invokeWovenClassListener( org.osgi.framework.hooks.weaving.WovenClass wc) throws Exception { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.INVOKE_WOVEN_CLASS_LISTENER, wcl, wc); - try - { - AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - wcl.modified(wc); - } + wcl.modified(wc); } public T run(PrivilegedAction action) { - if (System.getSecurityManager() != null) - { - return AccessController.doPrivileged(action); - } - else - { - return action.run(); - } + return action.run(); } public T run(PrivilegedExceptionAction action) throws Exception { - if (System.getSecurityManager() != null) - { - try - { - return AccessController.doPrivileged(action); - } - catch (PrivilegedActionException e) - { - throw e.getException(); - } - } - else - { - return action.run(); - } + return action.run(); } public String getCanonicalPath(File dataFile) throws IOException { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.GET_CANONICAL_PATH, dataFile); - try - { - return (String) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw (IOException) e.getException(); - } - } - else - { - return dataFile.getCanonicalPath(); - } + return dataFile.getCanonicalPath(); } public Object createProxy(ClassLoader classLoader, Class[] interfaces, InvocationHandler handler) { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.CREATE_PROXY, classLoader, interfaces, handler); - try - { - return AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw (RuntimeException) e.getException(); - } - } - else - { - return Proxy.newProxyInstance(classLoader, interfaces, handler); - } + return Proxy.newProxyInstance(classLoader, interfaces, handler); } public long getLastModified(File file) { - if (System.getSecurityManager() != null) - { - Actions actions = (Actions) m_actions.get(); - actions.set(Actions.LAST_MODIFIED, file); - try - { - return (Long) AccessController.doPrivileged(actions, m_acc); - } - catch (PrivilegedActionException e) - { - throw (RuntimeException) e.getException(); - } - } - else - { - return file.lastModified(); - } - } - - private static class Actions implements PrivilegedExceptionAction - { - public static final int INITIALIZE_CONTEXT_ACTION = 0; - public static final int ADD_EXTENSION_URL_ACTION = 1; - public static final int CREATE_TMPFILE_ACTION = 2; - public static final int CREATE_URL_ACTION = 3; - public static final int CREATE_URL_WITH_CONTEXT_ACTION = 4; - public static final int DELETE_FILE_ACTION = 5; - public static final int EXEC_ACTION = 6; - public static final int FILE_EXISTS_ACTION = 7; - public static final int FILE_IS_DIRECTORY_ACTION = 8; - public static final int FOR_NAME_ACTION = 9; - public static final int GET_ABSOLUTE_PATH_ACTION = 10; - public static final int GET_CONSTRUCTOR_ACTION = 11; - public static final int GET_DECLARED_CONSTRUCTOR_ACTION = 12; - public static final int GET_DECLARED_METHOD_ACTION = 13; - public static final int GET_FIELD_ACTION = 14; - public static final int GET_FILE_INPUT_ACTION = 15; - public static final int GET_FILE_OUTPUT_ACTION = 16; - public static final int TO_URI_ACTION = 17; - public static final int GET_METHOD_ACTION = 18; - public static final int GET_POLICY_ACTION = 19; - public static final int GET_PROPERTY_ACTION = 20; - public static final int GET_PARENT_CLASS_LOADER_ACTION = 21; - public static final int GET_SYSTEM_CLASS_LOADER_ACTION = 22; - public static final int GET_URL_INPUT_ACTION = 23; - public static final int INVOKE_CONSTRUCTOR_ACTION = 24; - public static final int INVOKE_DIRECTMETHOD_ACTION = 25; - public static final int INVOKE_METHOD_ACTION = 26; - public static final int LIST_DIRECTORY_ACTION = 27; - public static final int MAKE_DIRECTORIES_ACTION = 28; - public static final int MAKE_DIRECTORY_ACTION = 29; - public static final int OPEN_ZIPFILE_ACTION = 30; - public static final int OPEN_URLCONNECTION_ACTION = 31; - public static final int RENAME_FILE_ACTION = 32; - public static final int SET_ACCESSIBLE_ACTION = 33; - public static final int START_ACTIVATOR_ACTION = 34; - public static final int STOP_ACTIVATOR_ACTION = 35; - public static final int SWAP_FIELD_ACTION = 36; - public static final int SYSTEM_EXIT_ACTION = 37; - public static final int FLUSH_FIELD_ACTION = 38; - public static final int GET_CLASS_LOADER_ACTION = 39; - public static final int INVOKE_BUNDLE_FIND_HOOK = 40; - public static final int INVOKE_BUNDLE_EVENT_HOOK = 41; - public static final int INVOKE_WEAVING_HOOK = 42; - public static final int INVOKE_SERVICE_EVENT_HOOK = 43; - public static final int INVOKE_SERVICE_FIND_HOOK = 44; - public static final int INVOKE_SERVICE_LISTENER_HOOK_ADDED = 45; - public static final int INVOKE_SERVICE_LISTENER_HOOK_REMOVED = 46; - public static final int INVOKE_SERVICE_EVENT_LISTENER_HOOK = 47; - public static final int INVOKE_RESOLVER_HOOK_FACTORY = 48; - public static final int INVOKE_RESOLVER_HOOK_RESOLVABLE = 49; - public static final int INVOKE_RESOLVER_HOOK_SINGLETON = 50; - public static final int INVOKE_RESOLVER_HOOK_MATCHES = 51; - public static final int INVOKE_RESOLVER_HOOK_END = 52; - public static final int INVOKE_BUNDLE_COLLISION_HOOK = 53; - public static final int OPEN_JARFILE_ACTION = 54; - public static final int DELETE_FILEONEXIT_ACTION = 55; - public static final int INVOKE_WOVEN_CLASS_LISTENER = 56; - public static final int GET_CANONICAL_PATH = 57; - public static final int CREATE_PROXY = 58; - public static final int LAST_MODIFIED = 59; - public static final int FILE_IS_FILE_ACTION = 60; - public static final int GET_FILE_CHANNEL_ACTION = 61; - private static final int GET_INPUT_ACTION = 62; - private static final int GET_OUTPUT_ACTION = 63; - - private int m_action = -1; - private Object m_arg1 = null; - private Object m_arg2 = null; - private Object m_arg3 = null; - private Object m_arg4 = null; - private Object m_arg5 = null; - private Object m_arg6 = null; - - public void set(int action) - { - m_action = action; - } - - public void set(int action, Object arg1) - { - m_action = action; - m_arg1 = arg1; - } - - public void set(int action, Object arg1, Object arg2) - { - m_action = action; - m_arg1 = arg1; - m_arg2 = arg2; - } - - public void set(int action, Object arg1, Object arg2, Object arg3) - { - m_action = action; - m_arg1 = arg1; - m_arg2 = arg2; - m_arg3 = arg3; - } - - public void set(int action, Object arg1, Object arg2, Object arg3, - Object arg4) - { - m_action = action; - m_arg1 = arg1; - m_arg2 = arg2; - m_arg3 = arg3; - m_arg4 = arg4; - } - - public void set(int action, Object arg1, Object arg2, Object arg3, - Object arg4, Object arg5) - { - m_action = action; - m_arg1 = arg1; - m_arg2 = arg2; - m_arg3 = arg3; - m_arg4 = arg4; - m_arg5 = arg5; - } - - public void set(int action, Object arg1, Object arg2, Object arg3, - Object arg4, Object arg5, Object arg6) - { - m_action = action; - m_arg1 = arg1; - m_arg2 = arg2; - m_arg3 = arg3; - m_arg4 = arg4; - m_arg5 = arg5; - m_arg6 = arg6; - } - - private void unset() - { - m_action = -1; - m_arg1 = null; - m_arg2 = null; - m_arg3 = null; - m_arg4 = null; - m_arg5 = null; - m_arg6 = null; - } - - @Override - public Object run() throws Exception - { - int action = m_action; - Object arg1 = m_arg1; - Object arg2 = m_arg2; - Object arg3 = m_arg3; - Object arg4 = m_arg4; - Object arg5 = m_arg5; - Object arg6 = m_arg6; - - unset(); - - switch (action) - { - case INITIALIZE_CONTEXT_ACTION: - return AccessController.getContext(); - case ADD_EXTENSION_URL_ACTION: - Method addURL = - URLClassLoader.class.getDeclaredMethod("addURL", - URL.class); - getAccessor(URLClassLoader.class).accept(new AccessibleObject[]{addURL}); - addURL.invoke(arg2, arg1); - return null; - case CREATE_TMPFILE_ACTION: - return File.createTempFile((String) arg1, (String) arg2, (File) arg3); - case CREATE_URL_ACTION: - return new URL((String) arg1, (String) arg2, - ((Integer) arg3), (String) arg4, - (URLStreamHandler) arg5); - case CREATE_URL_WITH_CONTEXT_ACTION: - return new URL((URL) arg1, (String) arg2, (URLStreamHandler) arg3); - case DELETE_FILE_ACTION: - return ((File) arg1).delete() ? Boolean.TRUE : Boolean.FALSE; - case EXEC_ACTION: - return Runtime.getRuntime().exec((String) arg1); - case FILE_EXISTS_ACTION: - return ((File) arg1).exists() ? Boolean.TRUE : Boolean.FALSE; - case FILE_IS_DIRECTORY_ACTION: - return ((File) arg1).isDirectory() ? Boolean.TRUE : Boolean.FALSE; - case FOR_NAME_ACTION: - return (arg2 == null) ? Class.forName((String) arg1) : Class.forName((String) arg1, true, - (ClassLoader) arg2); - case GET_ABSOLUTE_PATH_ACTION: - return ((File) arg1).getAbsolutePath(); - case GET_CONSTRUCTOR_ACTION: - return ((Class) arg1).getConstructor((Class[]) arg2); - case GET_DECLARED_CONSTRUCTOR_ACTION: - return ((Class) arg1).getDeclaredConstructor((Class[]) arg2); - case GET_DECLARED_METHOD_ACTION: - return ((Class) arg1).getDeclaredMethod((String) arg2, (Class[]) arg3); - case GET_FIELD_ACTION: - Field field = ((Class) arg1).getDeclaredField((String) arg2); - getAccessor((Class) arg1).accept(new AccessibleObject[]{field}); - return field.get(arg3); - case GET_FILE_INPUT_ACTION: - return new FileInputStream((File) arg1); - case GET_FILE_OUTPUT_ACTION: - return new FileOutputStream((File) arg1); - case TO_URI_ACTION: - return ((File) arg1).toURI(); - case GET_METHOD_ACTION: - return ((Class) arg1).getMethod((String) arg2, (Class[]) arg3); - case GET_POLICY_ACTION: - return Policy.getPolicy(); - case GET_PROPERTY_ACTION: - return System.getProperty((String) arg1, (String) arg2); - case GET_PARENT_CLASS_LOADER_ACTION: - return ((ClassLoader) arg1).getParent(); - case GET_SYSTEM_CLASS_LOADER_ACTION: - return ClassLoader.getSystemClassLoader(); - case GET_URL_INPUT_ACTION: - return ((URLConnection) arg1).getInputStream(); - case INVOKE_CONSTRUCTOR_ACTION: - return ((Constructor) arg1).newInstance((Object[]) arg2); - case INVOKE_DIRECTMETHOD_ACTION: - return ((Method) arg1).invoke(arg2, (Object[]) arg3); - case INVOKE_METHOD_ACTION: - getAccessor(((Method) arg1).getDeclaringClass()).accept(new AccessibleObject[]{(Method) arg1}); - return ((Method) arg1).invoke(arg2, (Object[]) arg3); - case LIST_DIRECTORY_ACTION: - return ((File) arg1).listFiles(); - case MAKE_DIRECTORIES_ACTION: - return ((File) arg1).mkdirs() ? Boolean.TRUE : Boolean.FALSE; - case MAKE_DIRECTORY_ACTION: - return ((File) arg1).mkdir() ? Boolean.TRUE : Boolean.FALSE; - case OPEN_ZIPFILE_ACTION: - return new ZipFile((File) arg1); - case OPEN_URLCONNECTION_ACTION: - return ((URL) arg1).openConnection(); - case RENAME_FILE_ACTION: - return ((File) arg1).renameTo((File) arg2) ? Boolean.TRUE : Boolean.FALSE; - case SET_ACCESSIBLE_ACTION: - getAccessor(((Executable) arg1).getDeclaringClass()).accept(new AccessibleObject[]{(Executable) arg1}); - return null; - case START_ACTIVATOR_ACTION: - ((BundleActivator) arg1).start((BundleContext) arg2); - return null; - case STOP_ACTIVATOR_ACTION: - ((BundleActivator) arg1).stop((BundleContext) arg2); - return null; - case SWAP_FIELD_ACTION: - return _swapStaticFieldIfNotClass((Class) arg1, - (Class) arg2, (Class) arg3, (String) arg4); - case SYSTEM_EXIT_ACTION: - System.exit(((Integer) arg1)); - case FLUSH_FIELD_ACTION: - _flush(((Class) arg1), arg2); - return null; - case GET_CLASS_LOADER_ACTION: - return ((Class) arg1).getClassLoader(); - case INVOKE_BUNDLE_FIND_HOOK: - ((org.osgi.framework.hooks.bundle.FindHook) arg1).find( - (BundleContext) arg2, (Collection) arg3); - return null; - case INVOKE_BUNDLE_EVENT_HOOK: - ((org.osgi.framework.hooks.bundle.EventHook) arg1).event( - (BundleEvent) arg2, (Collection) arg3); - return null; - case INVOKE_WEAVING_HOOK: - ((org.osgi.framework.hooks.weaving.WeavingHook) arg1).weave( - (org.osgi.framework.hooks.weaving.WovenClass) arg2); - return null; - case INVOKE_SERVICE_EVENT_HOOK: - ((org.osgi.framework.hooks.service.EventHook) arg1).event( - (ServiceEvent) arg2, (Collection) arg3); - return null; - case INVOKE_SERVICE_FIND_HOOK: - ((org.osgi.framework.hooks.service.FindHook) arg1).find( - (BundleContext) arg2, (String) arg3, (String) arg4, - ((Boolean) arg5), - (Collection>) arg6); - return null; - case INVOKE_SERVICE_LISTENER_HOOK_ADDED: - ((org.osgi.framework.hooks.service.ListenerHook) arg1).added( - (Collection) arg2); - return null; - case INVOKE_SERVICE_LISTENER_HOOK_REMOVED: - ((org.osgi.framework.hooks.service.ListenerHook) arg1).removed( - (Collection) arg2); - return null; - case INVOKE_SERVICE_EVENT_LISTENER_HOOK: - ((org.osgi.framework.hooks.service.EventListenerHook) arg1).event( - (ServiceEvent) arg2, - (Map>) arg3); - return null; - case INVOKE_RESOLVER_HOOK_FACTORY: - return ((org.osgi.framework.hooks.resolver.ResolverHookFactory) arg1).begin( - (Collection) arg2); - case INVOKE_RESOLVER_HOOK_RESOLVABLE: - ((org.osgi.framework.hooks.resolver.ResolverHook) arg1).filterResolvable( - (Collection) arg2); - return null; - case INVOKE_RESOLVER_HOOK_SINGLETON: - ((org.osgi.framework.hooks.resolver.ResolverHook) arg1) - .filterSingletonCollisions( - (BundleCapability) arg2, - (Collection) arg3); - return null; - case INVOKE_RESOLVER_HOOK_MATCHES: - ((org.osgi.framework.hooks.resolver.ResolverHook) arg1).filterMatches( - (BundleRequirement) arg2, - (Collection) arg3); - return null; - case INVOKE_RESOLVER_HOOK_END: - ((org.osgi.framework.hooks.resolver.ResolverHook) arg1).end(); - return null; - case INVOKE_BUNDLE_COLLISION_HOOK: - ((org.osgi.framework.hooks.bundle.CollisionHook) arg1).filterCollisions((Integer) arg2, - (Bundle) arg3, (Collection) arg4); - return null; - case OPEN_JARFILE_ACTION: - return new JarFile((File) arg1); - case DELETE_FILEONEXIT_ACTION: - ((File) arg1).deleteOnExit(); - return null; - case INVOKE_WOVEN_CLASS_LISTENER: - ((org.osgi.framework.hooks.weaving.WovenClassListener) arg1).modified( - (org.osgi.framework.hooks.weaving.WovenClass) arg2); - return null; - case GET_CANONICAL_PATH: - return ((File) arg1).getCanonicalPath(); - case CREATE_PROXY: - return Proxy.newProxyInstance((ClassLoader)arg1, (Class[])arg2, - (InvocationHandler) arg3); - case LAST_MODIFIED: - return ((File) arg1).lastModified(); - case FILE_IS_FILE_ACTION: - return ((File) arg1).isFile() ? Boolean.TRUE : Boolean.FALSE; - case GET_FILE_CHANNEL_ACTION: - return FileChannel.open(((File) arg1).toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE); - case GET_INPUT_ACTION: - return Files.newInputStream(((File) arg1).toPath()); - case GET_OUTPUT_ACTION: - return Files.newOutputStream(((File) arg1).toPath()); - } - - return null; - } + return file.lastModified(); } } diff --git a/framework/src/main/java/org/apache/felix/framework/util/SecurityManagerEx.java b/framework/src/main/java/org/apache/felix/framework/util/SecurityManagerEx.java index 6b347cf45c..59823c69bd 100644 --- a/framework/src/main/java/org/apache/felix/framework/util/SecurityManagerEx.java +++ b/framework/src/main/java/org/apache/felix/framework/util/SecurityManagerEx.java @@ -18,21 +18,34 @@ */ package org.apache.felix.framework.util; +import java.util.stream.Stream; + /** *

- * Simple utility class used to provide public access to the protected - * getClassContext() method of SecurityManager + * Simple utility class used to obtain the current call stack as an array of + * classes, innermost caller first. + *

+ *

+ * This used to extend SecurityManager purely to expose its protected + * getClassContext() method. The Security Manager is permanently + * disabled as of Java SE 24 (JEP 486) and is marked for removal, so the same + * information is now obtained from StackWalker, which is the supported + * replacement and yields frames in the same order. *

**/ -public class SecurityManagerEx extends SecurityManager +public class SecurityManagerEx { - // In Android apparently getClassContext returns null - we work around this by returning an empty array in that case. + // On Android getClassContext() used to return null - keep tolerating an empty stack. private static final Class[] EMPTY_CLASSES = new Class[0]; - @Override - public Class[] getClassContext() + private static final StackWalker WALKER = + StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + + public Class[] getClassContext() { - Class[] result = super.getClassContext(); + Class[] result = WALKER.walk( + (Stream frames) -> + frames.map(StackWalker.StackFrame::getDeclaringClass).toArray(Class[]::new)); return result != null ? result : EMPTY_CLASSES; } } \ No newline at end of file diff --git a/framework/src/test/java/org/apache/felix/framework/URLHandlersTest.java b/framework/src/test/java/org/apache/felix/framework/URLHandlersTest.java index dce284bdee..8a7124daa8 100644 --- a/framework/src/test/java/org/apache/felix/framework/URLHandlersTest.java +++ b/framework/src/test/java/org/apache/felix/framework/URLHandlersTest.java @@ -28,7 +28,6 @@ import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; -import java.security.Permission; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; @@ -127,41 +126,10 @@ void urlHandlersWithClassLoaderIsolation() throws Exception f.stop(); } - @Test - void urlHandlersWithSecurity() throws Exception - { - System.setSecurityManager(new SecurityManager() - { - @Override - public void checkPermission(Permission perm) {} - }); - try - { - urlHandlers(); - } - finally - { - System.setSecurityManager(null); - } - } - - @Test - void urlHandlersWithClassLoaderIsolationWithSecurity() throws Exception - { - System.setSecurityManager(new SecurityManager() - { - @Override - public void checkPermission(Permission perm) {} - }); - try - { - urlHandlersWithClassLoaderIsolation(); - } - finally - { - System.setSecurityManager(null); - } - } + // The urlHandlersWithSecurity/urlHandlersWithClassLoaderIsolationWithSecurity tests + // used to re-run the two tests above under a permissive SecurityManager. The Security + // Manager is permanently disabled as of Java SE 24 (JEP 486) and can no longer be + // installed, which left them as exact duplicates, so they have been removed. public static class DelegatingClassLoader extends ClassLoader { diff --git a/gogo/gogo-parent/pom.xml b/gogo/gogo-parent/pom.xml index dc35a5bde0..4187c58bd1 100644 --- a/gogo/gogo-parent/pom.xml +++ b/gogo/gogo-parent/pom.xml @@ -99,7 +99,8 @@ org.mockito mockito-core - 5.17.0 + + 5.18.0 test diff --git a/gogo/jline/pom.xml b/gogo/jline/pom.xml index ee5e0ed6c8..9508dc688c 100644 --- a/gogo/jline/pom.xml +++ b/gogo/jline/pom.xml @@ -58,7 +58,7 @@ org.apache.felix org.apache.felix.gogo.runtime - 1.1.7-SNAPSHOT + 1.2.0-SNAPSHOT org.apache.felix diff --git a/gogo/runtime/doc/changelog.txt b/gogo/runtime/doc/changelog.txt index 0504f78621..f1bbf6e94c 100644 --- a/gogo/runtime/doc/changelog.txt +++ b/gogo/runtime/doc/changelog.txt @@ -1,3 +1,11 @@ +Changes from 1.1.6 to 1.2.0 +--------------------------- +Improvement + Removed the Security Manager based ThreadGroup selection in ThreadUtils. Java SE + 24 permanently disabled the Security Manager (JEP 486), so the thread group is + now always taken from the current thread. + + Changes from 1.1.4 to 1.1.6 --------------------------- Bug diff --git a/gogo/runtime/pom.xml b/gogo/runtime/pom.xml index 572d7e0fcf..971bf62256 100644 --- a/gogo/runtime/pom.xml +++ b/gogo/runtime/pom.xml @@ -31,7 +31,7 @@ bundle Apache Felix Gogo Runtime org.apache.felix.gogo.runtime - 1.1.7-SNAPSHOT + 1.2.0-SNAPSHOT http://felix.apache.org/ scm:git:https://github.com/apache/felix-dev.git diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/ThreadUtils.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/ThreadUtils.java index 1845bb5a2b..0cd7824ffe 100644 --- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/ThreadUtils.java +++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/ThreadUtils.java @@ -38,8 +38,7 @@ private static class NamedThreadFactory implements ThreadFactory { private final String namePrefix; public NamedThreadFactory(String prefix) { - SecurityManager s = System.getSecurityManager(); - group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); + group = Thread.currentThread().getThreadGroup(); namePrefix = prefix + "-" + poolNumber.getAndIncrement() + "-thread-"; } diff --git a/http/base/pom.xml b/http/base/pom.xml index e22f4c42a5..8ec06c17ca 100644 --- a/http/base/pom.xml +++ b/http/base/pom.xml @@ -149,7 +149,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test diff --git a/http/jetty/pom.xml b/http/jetty/pom.xml index fd71a5dfd5..e0019d51e8 100644 --- a/http/jetty/pom.xml +++ b/http/jetty/pom.xml @@ -509,7 +509,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test @@ -580,7 +580,7 @@ org.awaitility awaitility - 4.2.1 + 4.3.0 test diff --git a/http/jetty/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java b/http/jetty/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java index 76fa6899a9..70533b85c7 100644 --- a/http/jetty/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java +++ b/http/jetty/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java @@ -175,11 +175,11 @@ protected ModifiableCompositeOption optionalRemoteDebug() { public static ModifiableCompositeOption spifly() { return composite( mavenBundle().groupId("org.apache.aries.spifly").artifactId("org.apache.aries.spifly.dynamic.bundle").version("1.3.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-analysis").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-commons").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-tree").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-util").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm").version("9.7") + mavenBundle().groupId("org.ow2.asm").artifactId("asm-analysis").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm-commons").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm-tree").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm-util").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm").version("9.8") ); } } diff --git a/http/jetty12/pom.xml b/http/jetty12/pom.xml index 4bc669802d..8e9cdb3975 100644 --- a/http/jetty12/pom.xml +++ b/http/jetty12/pom.xml @@ -687,7 +687,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test @@ -758,7 +758,7 @@ org.awaitility awaitility - 4.2.1 + 4.3.0 test diff --git a/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java b/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java index b723a59240..f2b20807ed 100644 --- a/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java +++ b/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/AbstractJettyTestSupport.java @@ -175,11 +175,11 @@ protected ModifiableCompositeOption optionalRemoteDebug() { public static ModifiableCompositeOption spifly() { return composite( mavenBundle().groupId("org.apache.aries.spifly").artifactId("org.apache.aries.spifly.dynamic.bundle").version("1.3.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-analysis").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-commons").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-tree").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm-util").version("9.7"), - mavenBundle().groupId("org.ow2.asm").artifactId("asm").version("9.7") + mavenBundle().groupId("org.ow2.asm").artifactId("asm-analysis").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm-commons").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm-tree").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm-util").version("9.8"), + mavenBundle().groupId("org.ow2.asm").artifactId("asm").version("9.8") ); } } diff --git a/http/sslfilter/pom.xml b/http/sslfilter/pom.xml index c38d16e97d..e7901f0c51 100644 --- a/http/sslfilter/pom.xml +++ b/http/sslfilter/pom.xml @@ -132,7 +132,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test diff --git a/http/wrappers/pom.xml b/http/wrappers/pom.xml index 68ad7b9d87..6e828cf2a0 100644 --- a/http/wrappers/pom.xml +++ b/http/wrappers/pom.xml @@ -109,7 +109,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test diff --git a/main/pom.xml b/main/pom.xml index 423c616ae1..f1c2b3c910 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -20,14 +20,14 @@ org.apache.felix felix-parent - 6 + 9 ../pom/pom.xml 4.0.0 bundle Apache Felix Main org.apache.felix.main - 7.1.0-SNAPSHOT + 8.0.0-SNAPSHOT scm:git:https://github.com/apache/felix-dev.git scm:git:https://github.com/apache/felix-dev.git @@ -38,7 +38,7 @@ ${project.groupId} org.apache.felix.framework - 7.1.0-SNAPSHOT + 8.0.0-SNAPSHOT @@ -103,13 +103,13 @@ run - + - + @@ -180,14 +180,14 @@ run - + - + diff --git a/scr/changelog.txt b/scr/changelog.txt index 935c67f7f0..0b974782b8 100644 --- a/scr/changelog.txt +++ b/scr/changelog.txt @@ -1,3 +1,15 @@ +Changes in 2.3.0 +----------------- +** Improvement + * Removed the Security Manager based permission checks. Java SE 24 permanently + disabled the Security Manager (JEP 486), so these checks could never run: + DependencyManager.hasGetPermission and + AbstractComponentManager.hasServiceRegistrationPermissions now always allow, + the AccessController.doPrivileged wrappers around ConfigurationAdmin access and + around setAccessible on injected fields and lifecycle methods are gone, and the + multilocation ConfigurationPermission check in RegionConfigurationSupport is + removed. No exported API changed. + Changes in 2.2.16 ----------------- ** Improvement diff --git a/scr/pom.xml b/scr/pom.xml index 0ae9793dae..ed244e9585 100644 --- a/scr/pom.xml +++ b/scr/pom.xml @@ -30,7 +30,7 @@ Implementation of the Declarative Services specification 1.5 org.apache.felix.scr - 2.2.19-SNAPSHOT + 2.3.0-SNAPSHOT scm:git:ssh://git@github.com/apache/felix-dev.git scm:git:ssh://git@github.com/apache/felix-dev.git diff --git a/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldUtils.java b/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldUtils.java index 3d80494760..25567255d8 100644 --- a/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldUtils.java +++ b/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldUtils.java @@ -21,8 +21,6 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; import org.apache.felix.scr.impl.inject.internal.ClassUtils; import org.apache.felix.scr.impl.logger.ComponentLogger; @@ -276,15 +274,7 @@ public static String toString(final Class componentClass, */ private static void setAccessible(final Field field) { - AccessController.doPrivileged( new PrivilegedAction() - { - @Override - public Object run() - { - field.setAccessible( true ); - return null; - } - } ); + field.setAccessible( true ); } /** diff --git a/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java index a0aa3437a9..de05ef7abb 100644 --- a/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java +++ b/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java @@ -22,8 +22,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Map; @@ -489,15 +487,7 @@ protected static boolean accept( final Method method, boolean acceptPrivate, boo private static void setAccessible(final Method method) { - AccessController.doPrivileged( new PrivilegedAction() - { - @Override - public Object run() - { - method.setAccessible( true ); - return null; - } - } ); + method.setAccessible( true ); } diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java index a6864dad87..b7ff222283 100644 --- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java +++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java @@ -21,7 +21,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; -import java.security.Permission; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -49,12 +48,10 @@ import org.apache.felix.scr.impl.logger.InternalLogger.Level; import org.apache.felix.scr.impl.metadata.ComponentMetadata; import org.apache.felix.scr.impl.metadata.ReferenceMetadata; -import org.apache.felix.scr.impl.metadata.ServiceMetadata; import org.apache.felix.scr.impl.metadata.TargetedPID; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceException; -import org.osgi.framework.ServicePermission; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentConstants; @@ -1131,33 +1128,8 @@ public String toString() private boolean hasServiceRegistrationPermissions() { - boolean allowed = true; - if (System.getSecurityManager() != null) - { - final ServiceMetadata serviceMetadata = getComponentMetadata().getServiceMetadata(); - if (serviceMetadata != null) - { - final String[] services = serviceMetadata.getProvides(); - if (services != null && services.length > 0) - { - final Bundle bundle = getBundle(); - for (String service : services) - { - final Permission perm = new ServicePermission(service, ServicePermission.REGISTER); - if (!bundle.hasPermission(perm)) - { - m_container.getLogger().log(Level.DEBUG, - "Permission to register service {0} is denied", null, - service ); - allowed = false; - } - } - } - } - } - - // no security manager or no services to register - return allowed; + // no security manager, hence permission given + return true; } private List> loadDependencyManagers(final ComponentMetadata metadata) diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java index 031b2c1c01..9f96b86b3f 100644 --- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java +++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java @@ -18,7 +18,6 @@ */ package org.apache.felix.scr.impl.manager; -import java.security.Permission; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -46,7 +45,6 @@ import org.osgi.framework.Constants; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServicePermission; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentConstants; import org.osgi.service.component.ComponentException; @@ -1462,77 +1460,6 @@ public Collection> getRefs(AtomicInteger trackingCount) } } - private class NoPermissionsCustomizer implements Customizer - { - - @Override - public boolean prebind(ComponentContextImpl key) - { - return false; - } - - @Override - public void close() - { - } - - @Override - public Collection> getRefs(AtomicInteger trackingCount) - { - return Collections.emptyList(); - } - - @Override - public boolean isSatisfied() - { - return isOptional(); - } - - @Override - public void setTracker(ServiceTracker, ExtendedServiceEvent> tRefPairServiceTracker) - { - } - - @Override - public void setTrackerOpened() - { - } - - @Override - public void setPreviousRefMap(Map, RefPair> previousRefMap) - { - } - - @Override - public RefPair addingService(ServiceReference tServiceReference) - { - return null; - } - - @Override - public void addedService(ServiceReference tServiceReference, RefPair service, int trackingCount, - int serviceCount, ExtendedServiceEvent event) - { - } - - @Override - public void modifiedService(ServiceReference tServiceReference, RefPair service, int trackingCount, - ExtendedServiceEvent event) - { - } - - @Override - public void removedService(ServiceReference tServiceReference, RefPair service, int trackingCount, - ExtendedServiceEvent event) - { - } - } - - private String getServiceName() - { - return m_dependencyMetadata.getInterface(); - } - boolean isOptional() { return m_dependencyMetadata.isOptional(); @@ -1604,35 +1531,29 @@ int size() private ServiceReference[] getFrameworkServiceReferences(String targetFilter) { - if (hasGetPermission()) + // get bundle context, may be null if component deactivated since getting bca + BundleContext bc = m_componentManager.getActivator().getBundleContext(); + if (bc == null) { - // get bundle context, may be null if component deactivated since getting bca - BundleContext bc = m_componentManager.getActivator().getBundleContext(); - if (bc == null) - { - return null; - } + return null; + } - try - { - return bc.getServiceReferences(m_dependencyMetadata.getInterface(), - targetFilter); - } - catch (IllegalStateException ise) - { - // bundle context is not valid any longer, cannot log - } - catch (InvalidSyntaxException ise) - { - m_componentManager.getLogger().log(Level.ERROR, - "Unexpected problem with filter ''{0}''", - ise, targetFilter ); - return null; - } + try + { + return bc.getServiceReferences(m_dependencyMetadata.getInterface(), + targetFilter); + } + catch (IllegalStateException ise) + { + // bundle context is not valid any longer, cannot log + } + catch (InvalidSyntaxException ise) + { + m_componentManager.getLogger().log(Level.ERROR, + "Unexpected problem with filter ''{0}''", + ise, targetFilter ); } - m_componentManager.getLogger().log(Level.DEBUG, - "No permission to access the services", null); return null; } @@ -1828,12 +1749,6 @@ public boolean isSatisfied() */ public boolean hasGetPermission() { - if (System.getSecurityManager() != null) - { - Permission perm = new ServicePermission(getServiceName(), ServicePermission.GET); - return m_componentManager.getBundle().hasPermission(perm); - } - // no security manager, hence permission given return true; } @@ -2536,14 +2451,7 @@ private ServiceReference getTrueConditionRef() private Customizer newCustomizer() { Customizer customizer; - if (!hasGetPermission()) - { - customizer = new NoPermissionsCustomizer(); - m_componentManager.getLogger().log(Level.INFO, - "No permission to get services for {0}", - null, getName()); - } - else if (m_componentManager.isFactory()) + if (m_componentManager.isFactory()) { customizer = new FactoryCustomizer(); } diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/RegionConfigurationSupport.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/RegionConfigurationSupport.java index dbe9834c51..cf56c85b20 100644 --- a/scr/src/main/java/org/apache/felix/scr/impl/manager/RegionConfigurationSupport.java +++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/RegionConfigurationSupport.java @@ -19,8 +19,6 @@ package org.apache.felix.scr.impl.manager; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.Collections; import java.util.Dictionary; @@ -45,7 +43,6 @@ import org.osgi.service.cm.ConfigurationEvent; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ConfigurationListener; -import org.osgi.service.cm.ConfigurationPermission; import org.osgi.service.cm.ManagedService; public abstract class RegionConfigurationSupport @@ -84,38 +81,15 @@ public void start() // If RegionConfigurationSupport *directly* implements ConfigurationListener then we get NoClassDefFoundError // when SCR is started without a wiring to an exporter of Config Admin API. This construction allows the // class loading exception to be caught and confined. - final ConfigurationListener serviceDelegator; - if ( System.getSecurityManager() != null ) { - serviceDelegator = new ConfigurationListener() - { - @Override - public void configurationEvent(final ConfigurationEvent event) - { - AccessController.doPrivileged( - new PrivilegedAction() - { - @Override - public Void run() - { - RegionConfigurationSupport.this.configurationEvent(event); - return null; - } - }); - } - }; - } - else + final ConfigurationListener serviceDelegator = new ConfigurationListener() { - serviceDelegator = new ConfigurationListener() - { - @Override - public void configurationEvent(final ConfigurationEvent event) - { - RegionConfigurationSupport.this.configurationEvent(event); - } - }; - } + @Override + public void configurationEvent(final ConfigurationEvent event) + { + RegionConfigurationSupport.this.configurationEvent(event); + } + }; this.m_registration = caBundleContext.registerService(ConfigurationListener.class, serviceDelegator, props ); } @@ -710,15 +684,10 @@ private boolean checkBundleLocation(String configBundleLocation, Bundle bundle) else if ( configBundleLocation.startsWith( "?" ) ) { //multilocation - if ( System.getSecurityManager() != null ) - { - result = bundle.hasPermission( - new ConfigurationPermission(configBundleLocation, ConfigurationPermission.TARGET)); - } - else - { - result = true; - } + // The ConfigurationPermission TARGET check that used to guard this only ran + // under a Security Manager, which is permanently disabled as of Java SE 24 + // (JEP 486), so a multilocation configuration is always visible. + result = true; } else { diff --git a/webconsole/README.md b/webconsole/README.md index 2650a1f66c..3c6e38f3df 100644 --- a/webconsole/README.md +++ b/webconsole/README.md @@ -118,6 +118,13 @@ In this case the Configuration Manager displays the name "myRealm, myClass" as d ## Releases +### Changes in 5.1.0 + +#### Improvement + +- Removed the Security Manager based `AccessController.doPrivileged` wrappers in `AbstractWebConsolePlugin`, `OsgiManager` and `ConfigurationSupport`. Java SE 24 permanently disabled the Security Manager ([JEP 486](https://openjdk.org/jeps/486)), so those blocks could never take effect. No exported API changed, and the Web Console's own HTTP authentication is unaffected. + + ### Changes in 5.0.18 (22/Sep/25) #### Bug diff --git a/webconsole/pom.xml b/webconsole/pom.xml index f6b43d10e9..e701e9ee2c 100644 --- a/webconsole/pom.xml +++ b/webconsole/pom.xml @@ -28,7 +28,7 @@ org.apache.felix.webconsole bundle - 5.0.19-SNAPSHOT + 5.1.0-SNAPSHOT Apache Felix Web Management Console @@ -318,7 +318,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java index 45c46189f4..e300efaf67 100644 --- a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java +++ b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java @@ -26,9 +26,6 @@ import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLConnection; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -454,30 +451,7 @@ public void log(final int level, final String message, final Throwable t ) { private final boolean spoolResource(final HttpServletRequest request, final HttpServletResponse response) throws IOException { - try - { - // We need to call spoolResource0 in privileged block because it uses reflection, which - // requires the following set of permissions: - // (java.lang.RuntimePermission "getClassLoader") - // (java.lang.RuntimePermission "accessDeclaredMembers") - // (java.lang.reflect.ReflectPermission "suppressAccessChecks") - // See also https://issues.apache.org/jira/browse/FELIX-4652 - final Boolean ret = AccessController.doPrivileged(new PrivilegedExceptionAction() - { - - public Boolean run() throws Exception - { - return spoolResource0(request, response) ? Boolean.TRUE : Boolean.FALSE; - } - }); - return ret.booleanValue(); - } - catch (PrivilegedActionException e) - { - final Exception x = e.getException(); - throw x instanceof IOException ? (IOException) x : new IOException( - x.toString()); - } + return spoolResource0(request, response); } final boolean spoolResource0( HttpServletRequest request, HttpServletResponse response ) throws IOException diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java index 3453ad250a..dea7ce91a1 100644 --- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java +++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java @@ -19,9 +19,6 @@ package org.apache.felix.webconsole.internal.servlet; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Dictionary; import org.osgi.framework.BundleContext; @@ -47,36 +44,7 @@ class ConfigurationSupport implements ManagedService //---------- ManagedService public void updated( final Dictionary config ) throws ConfigurationException { - if (null != System.getSecurityManager()) - { - try - { - AccessController.doPrivileged(new PrivilegedExceptionAction<>() - { - public Object run() throws Exception - { - updated0(config); - return null; - } - }); - } - catch (PrivilegedActionException e) - { - final Exception x = e.getException(); - if (x instanceof ConfigurationException) - { - throw (ConfigurationException) x; - } - else - { - throw new ConfigurationException("?", "Update failed", x); - } - } - } - else - { - updated0(config); - } + updated0(config); } void updated0( Dictionary config ) throws ConfigurationException diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java index 6078074cf2..77bf3a717a 100644 --- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java +++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java @@ -18,9 +18,6 @@ import java.io.IOException; import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -412,35 +409,18 @@ public void init() { public void service(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException { // don't really expect to be called within a non-HTTP environment - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Object run() throws Exception { - final HttpServletRequest wrapper = new HttpServletRequestWrapper((HttpServletRequest) req) { - @Override - public String getServletPath() { - return ""; - } - - @Override - public String getPathInfo() { - return super.getServletPath(); - } - }; - doService(wrapper, res); - return null; - } - }); - } catch (PrivilegedActionException e) { - Exception x = e.getException(); - if (x instanceof IOException) { - throw (IOException) x; - } else if (x instanceof ServletException) { - throw (ServletException) x; - } else { - throw new IOException(x.toString()); + final HttpServletRequest wrapper = new HttpServletRequestWrapper((HttpServletRequest) req) { + @Override + public String getServletPath() { + return ""; } - } + + @Override + public String getPathInfo() { + return super.getServletPath(); + } + }; + doService(wrapper, res); } private void ensureLocaleCookieSet(HttpServletRequest request, HttpServletResponse response, Locale locale) {