mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00

Co-authored-by: Sean Mullan <mullan@openjdk.org> Co-authored-by: Alan Bateman <alanb@openjdk.org> Co-authored-by: Weijun Wang <weijun@openjdk.org> Co-authored-by: Aleksei Efimov <aefimov@openjdk.org> Co-authored-by: Brian Burkhalter <bpb@openjdk.org> Co-authored-by: Daniel Fuchs <dfuchs@openjdk.org> Co-authored-by: Harshitha Onkar <honkar@openjdk.org> Co-authored-by: Joe Wang <joehw@openjdk.org> Co-authored-by: Jorn Vernee <jvernee@openjdk.org> Co-authored-by: Justin Lu <jlu@openjdk.org> Co-authored-by: Kevin Walls <kevinw@openjdk.org> Co-authored-by: Lance Andersen <lancea@openjdk.org> Co-authored-by: Naoto Sato <naoto@openjdk.org> Co-authored-by: Roger Riggs <rriggs@openjdk.org> Co-authored-by: Brent Christian <bchristi@openjdk.org> Co-authored-by: Stuart Marks <smarks@openjdk.org> Co-authored-by: Ian Graves <igraves@openjdk.org> Co-authored-by: Phil Race <prr@openjdk.org> Co-authored-by: Erik Gahlin <egahlin@openjdk.org> Co-authored-by: Jaikiran Pai <jpai@openjdk.org> Reviewed-by: kevinw, aivanov, rriggs, lancea, coffeys, dfuchs, ihse, erikj, cjplummer, coleenp, naoto, mchung, prr, weijun, joehw, azvegint, psadhukhan, bchristi, sundar, attila
542 lines
20 KiB
Java
542 lines
20 KiB
Java
/*
|
|
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
|
|
package java.security;
|
|
|
|
import java.util.Enumeration;
|
|
import java.util.Objects;
|
|
import sun.security.jca.GetInstance;
|
|
|
|
/**
|
|
* A {@code Policy} object was responsible for determining whether code
|
|
* executing in the Java runtime environment had permission to perform a
|
|
* security-sensitive operation. This feature no longer exists.
|
|
*
|
|
* @author Roland Schemers
|
|
* @author Gary Ellison
|
|
* @since 1.2
|
|
* @deprecated This class was only useful in conjunction with
|
|
* {@linkplain SecurityManager the Security Manager}, which is no longer
|
|
* supported. Installing a system-wide {@code Policy} object is no longer
|
|
* supported. The {@linkplain #setPolicy setPolicy} method has been
|
|
* changed to always throw {@code UnsupportedOperationException}. The
|
|
* {@linkplain getPolicy getPolicy} method has been changed to always
|
|
* return a {@code Policy} object that grants no permissions. There is no
|
|
* replacement for the Security Manager or this class.
|
|
*/
|
|
|
|
@Deprecated(since="17", forRemoval=true)
|
|
public abstract class Policy {
|
|
|
|
private static Policy NO_PERMISSIONS_POLICY = new Policy() {};
|
|
|
|
/**
|
|
* Constructor for subclasses to call.
|
|
*/
|
|
public Policy() {}
|
|
|
|
/**
|
|
* A read-only empty PermissionCollection instance.
|
|
* @since 1.6
|
|
*/
|
|
public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION =
|
|
new UnsupportedEmptyCollection();
|
|
|
|
/**
|
|
* Returns a {@code Policy} object that grants no permissions.
|
|
* Specifically:
|
|
*
|
|
* <ul>
|
|
* <li> The {@code getParameters} method returns {@code null}. </li>
|
|
* <li> The {@code getPermissions(CodeSource)} and
|
|
* {@code getPermissions(ProtectionDomain)} methods return a read-only
|
|
* empty {@code PermissionCollection}. </li>
|
|
* <li> The {@code implies} method always returns {@code false}. </li>
|
|
* </ul>
|
|
*
|
|
* @return a {@code Policy} object that grants no permissions
|
|
*
|
|
* @apiNote This method originally returned the installed {@code Policy}
|
|
* object, or if no {@code Policy} object had been installed, a default
|
|
* {@code Policy} implementation. Installing a system-wide {@code Policy}
|
|
* object is no longer supported. This method always returns a
|
|
* default {@code Policy} object that grants no permissions. A
|
|
* {@code Policy} object was only useful in conjunction with
|
|
* {@linkplain SecurityManager the Security Manager}, which is no
|
|
* longer supported. There is no replacement for this method.
|
|
*
|
|
* @see #setPolicy(java.security.Policy)
|
|
*/
|
|
public static Policy getPolicy()
|
|
{
|
|
return NO_PERMISSIONS_POLICY;
|
|
}
|
|
|
|
/**
|
|
* Throws {@code UnsupportedOperationException}. Setting a system-wide
|
|
* {@code Policy} object is not supported.
|
|
*
|
|
* @param p ignored
|
|
* @throws UnsupportedOperationException always
|
|
* @apiNote This method originally installed the system-wide
|
|
* {@code Policy} object. Installing a system-wide {@code Policy} object
|
|
* is no longer supported. A {@code Policy} object was only useful in
|
|
* conjunction with {@linkplain SecurityManager the Security Manager},
|
|
* which is no longer supported. There is no replacement for this method.
|
|
*
|
|
* @see #getPolicy()
|
|
*/
|
|
public static void setPolicy(Policy p)
|
|
{
|
|
throw new UnsupportedOperationException(
|
|
"Setting a system-wide Policy object is not supported");
|
|
}
|
|
|
|
/**
|
|
* Returns a Policy object of the specified type.
|
|
*
|
|
* <p> This method traverses the list of registered security providers,
|
|
* starting with the most preferred provider.
|
|
* A new {@code Policy} object encapsulating the
|
|
* {@code PolicySpi} implementation from the first
|
|
* provider that supports the specified type is returned.
|
|
*
|
|
* <p> Note that the list of registered providers may be retrieved via
|
|
* the {@link Security#getProviders() Security.getProviders()} method.
|
|
*
|
|
* @implNote
|
|
* The JDK Reference Implementation additionally uses the
|
|
* {@code jdk.security.provider.preferred}
|
|
* {@link Security#getProperty(String) Security} property to determine
|
|
* the preferred provider order for the specified algorithm. This
|
|
* may be different than the order of providers returned by
|
|
* {@link Security#getProviders() Security.getProviders()}.
|
|
*
|
|
* @param type the specified Policy type
|
|
*
|
|
* @param params parameters for the {@code Policy}, which may be
|
|
* {@code null}.
|
|
*
|
|
* @return the new {@code Policy} object
|
|
*
|
|
* @throws IllegalArgumentException if the specified parameters
|
|
* are not understood by the {@code PolicySpi} implementation
|
|
* from the selected {@code Provider}
|
|
*
|
|
* @throws NoSuchAlgorithmException if no {@code Provider} supports
|
|
* a {@code PolicySpi} implementation for the specified type
|
|
*
|
|
* @throws NullPointerException if {@code type} is {@code null}
|
|
*
|
|
* @see Provider
|
|
* @since 1.6
|
|
*/
|
|
@SuppressWarnings("removal")
|
|
public static Policy getInstance(String type, Policy.Parameters params)
|
|
throws NoSuchAlgorithmException {
|
|
Objects.requireNonNull(type, "null type name");
|
|
try {
|
|
GetInstance.Instance instance = GetInstance.getInstance("Policy",
|
|
PolicySpi.class,
|
|
type,
|
|
params);
|
|
return new PolicyDelegate((PolicySpi)instance.impl,
|
|
instance.provider,
|
|
type,
|
|
params);
|
|
} catch (NoSuchAlgorithmException nsae) {
|
|
return handleException(nsae);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a {@code Policy} object of the specified type.
|
|
*
|
|
* <p> A new {@code Policy} object encapsulating the
|
|
* {@code PolicySpi} implementation from the specified provider
|
|
* is returned. The specified provider must be registered
|
|
* in the provider list.
|
|
*
|
|
* <p> Note that the list of registered providers may be retrieved via
|
|
* the {@link Security#getProviders() Security.getProviders()} method.
|
|
*
|
|
* @param type the specified Policy type
|
|
*
|
|
* @param params parameters for the {@code Policy}, which may be
|
|
* {@code null}.
|
|
*
|
|
* @param provider the provider.
|
|
*
|
|
* @return the new {@code Policy} object
|
|
*
|
|
* @throws IllegalArgumentException if the specified provider
|
|
* is {@code null} or empty, or if the specified parameters are
|
|
* not understood by the {@code PolicySpi} implementation from
|
|
* the specified provider
|
|
*
|
|
* @throws NoSuchAlgorithmException if the specified provider does not
|
|
* support a {@code PolicySpi} implementation for the specified
|
|
* type
|
|
*
|
|
* @throws NoSuchProviderException if the specified provider is not
|
|
* registered in the security provider list
|
|
*
|
|
* @throws NullPointerException if {@code type} is {@code null}
|
|
*
|
|
* @see Provider
|
|
* @since 1.6
|
|
*/
|
|
@SuppressWarnings("removal")
|
|
public static Policy getInstance(String type,
|
|
Policy.Parameters params,
|
|
String provider)
|
|
throws NoSuchProviderException, NoSuchAlgorithmException {
|
|
|
|
Objects.requireNonNull(type, "null type name");
|
|
if (provider == null || provider.isEmpty()) {
|
|
throw new IllegalArgumentException("missing provider");
|
|
}
|
|
|
|
try {
|
|
GetInstance.Instance instance = GetInstance.getInstance("Policy",
|
|
PolicySpi.class,
|
|
type,
|
|
params,
|
|
provider);
|
|
return new PolicyDelegate((PolicySpi)instance.impl,
|
|
instance.provider,
|
|
type,
|
|
params);
|
|
} catch (NoSuchAlgorithmException nsae) {
|
|
return handleException(nsae);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a {@code Policy} object of the specified type.
|
|
*
|
|
* <p> A new {@code Policy} object encapsulating the
|
|
* {@code PolicySpi} implementation from the specified provider
|
|
* is returned. Note that the specified provider does not
|
|
* have to be registered in the provider list.
|
|
*
|
|
* @param type the specified Policy type
|
|
*
|
|
* @param params parameters for the {@code Policy}, which may be
|
|
* {@code null}.
|
|
*
|
|
* @param provider the {@code Provider}.
|
|
*
|
|
* @return the new {@code Policy} object
|
|
*
|
|
* @throws IllegalArgumentException if the specified {@code Provider}
|
|
* is {@code null}, or if the specified parameters are not
|
|
* understood by the {@code PolicySpi} implementation from the
|
|
* specified {@code Provider}
|
|
*
|
|
* @throws NoSuchAlgorithmException if the specified {@code Provider}
|
|
* does not support a {@code PolicySpi} implementation for
|
|
* the specified type
|
|
*
|
|
* @throws NullPointerException if {@code type} is {@code null}
|
|
*
|
|
* @see Provider
|
|
* @since 1.6
|
|
*/
|
|
@SuppressWarnings("removal")
|
|
public static Policy getInstance(String type,
|
|
Policy.Parameters params,
|
|
Provider provider)
|
|
throws NoSuchAlgorithmException {
|
|
|
|
Objects.requireNonNull(type, "null type name");
|
|
if (provider == null) {
|
|
throw new IllegalArgumentException("missing provider");
|
|
}
|
|
|
|
try {
|
|
GetInstance.Instance instance = GetInstance.getInstance("Policy",
|
|
PolicySpi.class,
|
|
type,
|
|
params,
|
|
provider);
|
|
return new PolicyDelegate((PolicySpi)instance.impl,
|
|
instance.provider,
|
|
type,
|
|
params);
|
|
} catch (NoSuchAlgorithmException nsae) {
|
|
return handleException(nsae);
|
|
}
|
|
}
|
|
|
|
private static Policy handleException(NoSuchAlgorithmException nsae)
|
|
throws NoSuchAlgorithmException {
|
|
Throwable cause = nsae.getCause();
|
|
if (cause instanceof IllegalArgumentException) {
|
|
throw (IllegalArgumentException)cause;
|
|
}
|
|
throw nsae;
|
|
}
|
|
|
|
/**
|
|
* Return the {@code Provider} of this policy.
|
|
*
|
|
* <p> This {@code Policy} instance will only have a provider if it
|
|
* was obtained via a call to {@code Policy.getInstance}.
|
|
* Otherwise this method returns {@code null}.
|
|
*
|
|
* @return the {@code Provider} of this policy, or {@code null}.
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
public Provider getProvider() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Return the type of this {@code Policy}.
|
|
*
|
|
* <p> This {@code Policy} instance will only have a type if it
|
|
* was obtained via a call to {@code Policy.getInstance}.
|
|
* Otherwise this method returns {@code null}.
|
|
*
|
|
* @return the type of this {@code Policy}, or {@code null}.
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
public String getType() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Return {@code Policy} parameters.
|
|
*
|
|
* <p> This {@code Policy} instance will only have parameters if it
|
|
* was obtained via a call to {@code Policy.getInstance}.
|
|
* Otherwise this method returns {@code null}.
|
|
*
|
|
* @return {@code Policy} parameters, or {@code null}.
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
public Policy.Parameters getParameters() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Return a PermissionCollection object containing the set of
|
|
* permissions granted to the specified CodeSource.
|
|
*
|
|
* <p> The default implementation of this method ignores the
|
|
* CodeSource and returns Policy.UNSUPPORTED_EMPTY_COLLECTION.
|
|
*
|
|
* @param codesource ignored
|
|
*
|
|
* @return a set of permissions granted to the specified CodeSource.
|
|
* If this operation is supported, the returned
|
|
* set of permissions must be a new mutable instance
|
|
* and it must support heterogeneous Permission types.
|
|
* If this operation is not supported,
|
|
* Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
|
|
*/
|
|
public PermissionCollection getPermissions(CodeSource codesource) {
|
|
return Policy.UNSUPPORTED_EMPTY_COLLECTION;
|
|
}
|
|
|
|
/**
|
|
* Return a PermissionCollection object containing the set of
|
|
* permissions granted to the specified ProtectionDomain.
|
|
*
|
|
* <p> The default implementation of this method ignores the
|
|
* ProtectionDomain and returns Policy.UNSUPPORTED_EMPTY_COLLECTION.
|
|
*
|
|
* @param domain ignored
|
|
*
|
|
* @return a set of permissions granted to the specified ProtectionDomain.
|
|
* If this operation is supported, the returned
|
|
* set of permissions must be a new mutable instance
|
|
* and it must support heterogeneous Permission types.
|
|
* If this operation is not supported,
|
|
* Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
|
|
*
|
|
* @since 1.4
|
|
*/
|
|
public PermissionCollection getPermissions(ProtectionDomain domain) {
|
|
return Policy.UNSUPPORTED_EMPTY_COLLECTION;
|
|
}
|
|
|
|
/**
|
|
* Evaluates the permissions granted to the ProtectionDomain and tests
|
|
* whether the permission is granted.
|
|
*
|
|
* <p> The default implementation of this method ignores the
|
|
* ProtectionDomain and Permission parameters and always returns false.
|
|
*
|
|
* @param domain ignored
|
|
* @param permission ignored
|
|
*
|
|
* @return {@code false} always
|
|
*
|
|
* @see java.security.ProtectionDomain
|
|
* @since 1.4
|
|
*/
|
|
public boolean implies(ProtectionDomain domain, Permission permission) {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Refreshes/reloads the policy configuration.
|
|
*
|
|
* <p> The default implementation of this method does nothing.
|
|
*/
|
|
public void refresh() { }
|
|
|
|
/**
|
|
* This subclass is returned by the getInstance calls. All {@code Policy}
|
|
* calls are delegated to the underlying {@code PolicySpi}.
|
|
*/
|
|
private static class PolicyDelegate extends Policy {
|
|
|
|
@SuppressWarnings("removal")
|
|
private PolicySpi spi;
|
|
private Provider p;
|
|
private String type;
|
|
private Policy.Parameters params;
|
|
|
|
private PolicyDelegate(@SuppressWarnings("removal") PolicySpi spi, Provider p,
|
|
String type, Policy.Parameters params) {
|
|
this.spi = spi;
|
|
this.p = p;
|
|
this.type = type;
|
|
this.params = params;
|
|
}
|
|
|
|
@Override public String getType() { return type; }
|
|
|
|
@Override public Policy.Parameters getParameters() { return params; }
|
|
|
|
@Override public Provider getProvider() { return p; }
|
|
|
|
@Override
|
|
public PermissionCollection getPermissions(CodeSource codesource) {
|
|
return spi.engineGetPermissions(codesource);
|
|
}
|
|
@Override
|
|
public PermissionCollection getPermissions(ProtectionDomain domain) {
|
|
return spi.engineGetPermissions(domain);
|
|
}
|
|
@Override
|
|
public boolean implies(ProtectionDomain domain, Permission perm) {
|
|
return spi.engineImplies(domain, perm);
|
|
}
|
|
@Override
|
|
public void refresh() {
|
|
spi.engineRefresh();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This represents a marker interface for Policy parameters.
|
|
*
|
|
* @since 1.6
|
|
* @deprecated This class was only useful in conjunction with
|
|
* {@linkplain SecurityManager the Security Manager}, which is
|
|
* no longer supported. There is no replacement for the Security
|
|
* Manager or this class.
|
|
*/
|
|
@Deprecated(since="17", forRemoval=true)
|
|
public static interface Parameters { }
|
|
|
|
/**
|
|
* This class represents a read-only empty PermissionCollection object that
|
|
* is returned from the {@code getPermissions(CodeSource)} and
|
|
* {@code getPermissions(ProtectionDomain)}
|
|
* methods in the {@code Policy} class when those operations are not
|
|
* supported by the Policy implementation.
|
|
*/
|
|
private static class UnsupportedEmptyCollection
|
|
extends PermissionCollection {
|
|
|
|
@java.io.Serial
|
|
private static final long serialVersionUID = -8492269157353014774L;
|
|
|
|
private Permissions perms;
|
|
|
|
/**
|
|
* Create a read-only empty PermissionCollection object.
|
|
*/
|
|
public UnsupportedEmptyCollection() {
|
|
this.perms = new Permissions();
|
|
perms.setReadOnly();
|
|
}
|
|
|
|
/**
|
|
* Adds a permission object to the current collection of permission
|
|
* objects.
|
|
*
|
|
* @param permission the Permission object to add.
|
|
*
|
|
* @throws SecurityException if this PermissionCollection object
|
|
* has been marked readonly
|
|
*/
|
|
@Override public void add(Permission permission) {
|
|
perms.add(permission);
|
|
}
|
|
|
|
/**
|
|
* Checks to see if the specified permission is implied by the
|
|
* collection of Permission objects held in this PermissionCollection.
|
|
*
|
|
* @param permission the Permission object to compare.
|
|
*
|
|
* @return {@code true} if "permission" is implied by the permissions in
|
|
* the collection, {@code false} if not.
|
|
*/
|
|
@Override public boolean implies(Permission permission) {
|
|
return perms.implies(permission);
|
|
}
|
|
|
|
/**
|
|
* Returns an enumeration of all the Permission objects in the
|
|
* collection.
|
|
*
|
|
* @return an enumeration of all the Permissions.
|
|
*/
|
|
@Override public Enumeration<Permission> elements() {
|
|
return perms.elements();
|
|
}
|
|
|
|
/**
|
|
* If this object is readonly, no new objects can be added to it using {@code add}.
|
|
*
|
|
* @return {@code true} if this object is marked as readonly, {@code false} otherwise.
|
|
*/
|
|
@Override
|
|
public boolean isReadOnly() {
|
|
return perms.isReadOnly();
|
|
}
|
|
}
|
|
}
|