Sie sind auf Seite 1von 50

a f t

Dr

Java™ Remote
Method Invocation
Security Extension

This document is an early draft of a proposed standard extension to add


security to Java™ Remote Method Invocation (RMI). The specification is
incomplete, and will change to align with a future version of the Java™
platform. The document is being published at this time to provide the
community with an early look at our design and to solicit feedback on that
design, so that we can incorporate any changes as a result of that feedback
prior to any official public review. Comments about this draft should be sent
to rmi-security-comments@sun.com.

Early Look Draft 2


9/24/99

9/24/99
Copyright © 1999 Sun Microsystems, Inc.
901 San Antonio Road, Palo Alto, CA 94303 USA
All rights reserved. Copyright in this document is owned by Sun Microsystems, Inc.
Sun Microsystems, Inc. has patent and other intellectual property rights relating to implementations of the
technology described in this Specification ("Sun IPR"). Your limited right to use this Specification does not
grant you any right or license to Sun IPR.
THIS SPECIFICATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN
SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY YOU AS A RESULT OF USING THE
SPECIFICATION.
THIS SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL
ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION HEREIN; THESE
CHANGES WILL BE INCORPORATED IN NEW EDITIONS OF THE SPECIFICATION. SUN
MICROSYSTEMS, INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES IN THE
SPECIFICATIONS AT ANY TIME, IN ITS SOLE DISCRETION. SUN IS UNDER NO OBLIGATION TO
PRODUCE FURTHER VERSIONS OF THE SPECIFICATION OR ANY PRODUCT OR TECHNOLOGY
BASED UPON THE SPECIFICATION. NOR IS SUN UNDER ANY OBLIGATION TO LICENSE THE
SPECIFICATION OR ANY ASSOCIATED TECHNOLOGY, NOW OR IN THE FUTURE, FOR
PRODUCTIVE OR OTHER USE.
RESTRICTED RIGHTS LEGEND
Use, duplication, or disclosure by the U.S. Government is subject to restrictions of FAR 52.227-14(g)(2)(6/
87) and FAR 52.227-19(6/87), or DFAR 252.227-7015(b)(6/95) and DFAR 227.7202-1(a).
TRADEMARKS
Copyright © 1999 Sun Microsystems, Inc., All rights reserved.
Sun, Sun Microsystems, the Sun logo, and Java are trademarks or registered trademarks of Sun
Microsystems, Inc. in the U.S. and other countries.

REPORT
As an Evaluation Posting of this Specification, you may wish to report any ambiguities, inconsistencies, or inac-
curacies you may find in connection with your evaluation of the Specification (“Feedback”). To the extent that
you provide Sun with any Feedback, you hereby: (i) agree that such Feedback is provided on a non-proprietary
and non-confidential basis and (ii) grant to Sun a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable
license to incorporate, disclose, and use without limitation the Feedback for any purpose relating to the Specifi-
cation and future versions, implementations, and test suites thereof.

2
JAVA™ RMI SECURITY EXTENSION 3

Significant changes from previous draft:

◆ added getElementType to AlternativeSecurityConstraints


◆ removed SecureExportDesc parameter from register method of
SecureActivatable
◆ added port parameter to getClientFactory method of
SecureServerSocketFactory
◆ removed host and port parameters from createSocket method of
SecureClientSocketFactory
◆ allowed getActivatorConstraints method of ActivatorSecurity to be
specified in SecureExportDesc for secure activatable objects
◆ specified that default constraints in SecureExportDesc are used for DGC
◆ allow choosePreferences method of SecureClientSocketFactory to
throw IOException
◆ changed ActivatorSecurity to not extend Remote
◆ changed establishProxyTrust so that the object returned by
getSecureProxy does not have to be a secure RMI stub, and added search-
ing of security providers so that what’s trusted is extensible
◆ specified use of security providers to control what classes are trusted for
constraints, principals, and client socket factories
◆ augmented the provider search rules to support controlled ordering and sub-
sets
◆ removed doAsClientSubject methods from
SecureUnicastRemoteObject, and clarified delegation mechanics
◆ removed DelegationTimeException
◆ moved provider-related classes into javax.rmi.security.spi
◆ reflected JAAS change from JAAS-specific Action classes to those already
used by doPrivileged
◆ added checkConnect method to SecureClientSocketFactory
◆ fixed SecureSessionSocket to take client subject instead of server subject
◆ allow parameterTypes to be null in MethodConstraints and
RemoteSecurity
◆ changed description of remote call parameter unmarshalling to use the new
doAsPrivileged method of Subject

EARLY LOOK DRAFT 2


4 INTRODUCTION

Java™ RMI Security


Extension

1 Introduction
The Java™ 2 platform provides mechanisms for defining and using fine-grained
access control policies, built around the notion of what code is being executed.
Permission is granted to code, based on what location the code came from and
who signed that code.
Missing from the security architecture is any notion of who is executing the
code. The Java Authentication and Authorization Service (http://java.sun.com/
security/jaas) extends the security architecture, providing mechanisms to authenti-
cate subjects (login), execute code on behalf of subjects, and grant permissions to
subjects. The result is that access control policies can be based on both what code
is being executed and who is executing that code.
The RMI Security Extension further extends the security architecture to dis-
tributed systems, providing mechanisms to mutually authenticate client and server
subjects during a remote call, protect the communication from third parties, and
execute code in the server on behalf of the client’s subject.
The API for this extension is intentionally at a very high level; cryptographic
mechanisms and protocols are not exposed, so that code written to the API is more
portable. An underlying service provider interface allows specific mechanisms
and protocols to be configured into the framework.
Although this is an extension to RMI, the API is designed to be applicable
more generally to remote services that are defined in terms of interfaces. A remote
service has a front-end proxy object that implements one or more interfaces; the
proxy is downloaded into clients that want to use the service. An RMI stub is one
form of proxy, but a proxy may also be a more sophisticated object that performs
additional computation surrounding an RMI call, or one that uses alternate net-
work protocols.The proxy is responsible for network communication with the
back-end remote service, and the implementation of the proxy, including the
details of the protocol it uses to communicate with the remote service, can be spe-
cialized to the particular implementation of the service. The client does not know

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 5

about these implementation details; it only knows about the interfaces that define
the service.

1.1 Package

The new classes and interfaces defined here are in a new package,
javax.rmi.security, and in subpackages thereof.

1.2 Imports

The following imports are assumed throughout:


import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.net.ServerSocket;
import java.rmi.MarshalledObject;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.activation.ActivationException;
import java.rmi.activation.ActivationID;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteServer;
import java.rmi.server.ExportException;
import java.rmi.server.ServerNotActiveException;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.Set;
import javax.security.auth.Subject;

EARLY LOOK DRAFT 2


6 INTRODUCTION

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 7

2 Constraints

This extension allows both clients and servers to express security constraints to be
applied to remote calls. The basic security constraints are very simple:

◆ Communication integrity – making sure that the bits sent over the network
are not tampered with by third parties
◆ Server authentication – proving to the client that the server is executing on
behalf of some subject, so that the call can be terminated if the subject is not
trusted by the client
◆ Client authentication – proving to the server that the client is executing on
behalf of some subject, so that the server can perform only those tasks that
the subject is authorized for. The flip side of this is anonymity: allowing a
client to remain anonymous when it wants to be.
◆ Delegation – allowing the server to authenticate as the client, thus allowing
the server to act on a client’s behalf when dealing with third party remote
servers, in cases where the identity of the client (not the server) is what mat-
ters to the third party

Additional constraints can be placed on the use of delegation over time:

◆ Delegation duration – the delegation is valid only during a given duration,


measured from the start of the remote call
◆ Delegation end time – the delegation is valid only until a specific end time

Constraints can also be placed on which principals of a client or server subject


must be authenticated:

◆ Principal class – authentication can be restricted to principals that are


instances of specific classes
◆ Principal – authentication can be restricted to specific principals

EARLY LOOK DRAFT 2


8 CONSTRAINTS

The constraint mechanism is designed to be extensible; additional kinds of


constraints may be provided in specific implementations.
Constraints come in two basic flavors: requirements and preferences. A
requirement is a mandatory constraint that must be satisfied for the remote call. A
preference is a desired constraint, to be satisfied if possible, but it will not be satis-
fied if it conflicts with a requirement, and if two preferences conflict, it is gener-
ally arbitrary as to which one will be satisfied.
A server can specify different constraints for each remote method, if desired.
Clients can attach constraints directly to a proxy, in which case they apply to all
remote calls made through that proxy by any thread, or clients can specify con-
straints contextually, in which case they apply to all secure remote calls made any-
where within that scope by that thread.
Overall, constraints come from four sources:

◆ Server constraints attached to a proxy


◆ Client constraints attached to a proxy
◆ Client constraints specified contextually within the current thread’s stack
frames
◆ Client constraints attached to the thread (inherited from the creating thread)

The constraint mechanisms are designed such that a client cannot weaken
constraints set by the server, nested code cannot weaken constraints set by enclos-
ing code in the call chain, and code within a thread cannot weaken constraints
inherited by the thread. However, it is certainly possible to specify conflicting
requirements, in which case the remote call will not be made.
A secure remote call will be performed only if the server is capable of provid-
ing all of the client requirements (from all sources), and if all of the client and
server requirements are supported by the client’s underlying RMI implementation.
In addition, both client and server preferences will be satisfied, to the extent possi-
ble.

2.1 SecurityConstraint

Security constraints are represented as instances of classes that implement the fol-
lowing interface:
package javax.rmi.security;
public interface SecurityConstraint {
boolean implies(SecurityConstraint c);

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 9

Object COMPLEX_INTERSECT = new Object();


Object intersect(SecurityConstraint c);
}

In general, most developers do not need to be concerned with the detailed


semantics of these methods; they are primarily intended for use within the exten-
sion to reduce complex combinations of constraints into simpler forms for inter-
pretation by socket factories. As such, only the general semantics of these
methods are described here, and Sections 2.14 and 2.15 provide detailed seman-
tics for these methods with respect to each constraint class.
Given two SecurityConstraint instances c1 and c2, c1.implies(c2) is
true if every security configuration that could satisfy c1 also satisfies c2. Note that
c1.implies(c2) is sometimes true even if c1 and c2 are not instances of the
same class.
Given two SecurityConstraint instances c1 and c2, c1.intersect(c2)
returns the constraint c3 such that

◆ c3.implies(c1) is true, and


◆ c3.implies(c2) is true, and
◆ there is no other constraint c4 for which

c4.implies(c1) is true, and

c4.implies(c2) is true, and

c3.implies(c4) is true.

If such a constraint could exist in theory, but cannot be represented as an


instance of any existing constraint class, then COMPLEX_INTERSECT is returned. If
no such constraint could exist, then null is returned; in this case the two con-
straints are said to conflict. This method is symmetric: c1.intersect(c2) and
c2.intersect(c1) return the same result.

2.2 RelativeTimeConstraint

Constraints that are expressed in terms of relative time are represented as


instances of classes that implement the following interface:
package javax.rmi.security;
public interface RelativeTimeConstraint
extends SecurityConstraint

EARLY LOOK DRAFT 2


10 CONSTRAINTS

{
SecurityConstraint makeAbsolute(long baseTime);
}

The makeAbsolute method takes an absolute time, specified in milliseconds


from midnight, January 1, 1970 UTC, and returns a constraint that has the relative
times converted to absolute times using the specified absolute time as a base.

2.3 Basic Constraints

The basic security constraints are provided as constants of the following classes in
the javax.rmi.security package:
public final class Integrity
implements SecurityConstraint, Serializable
{
public static final Integrity YES;
public static final Integrity NO;
}

public final class AuthenticateClient


implements SecurityConstraint, Serializable
{
public static final AuthenticateClient YES;
public static final AuthenticateClient NO;
}
public final class AuthenticateServer
implements SecurityConstraint, Serializable
{
public static final AuthenticateServer YES;
public static final AuthenticateServer NO;
}
public final class Delegation
implements SecurityConstraint, Serializable
{
public static final Delegation YES;
public static final Delegation NO;
}

The semantics of these constraints are as follows:

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 11

◆ Integrity.YES – detect when message contents (both requests and replies)


have been altered, and refuse to process altered messages
◆ Integrity.NO – ensure that no integrity mechanism is used (normally this
constraint should not be used)
◆ AuthenticateClient.YES – authenticate the client to the server
◆ AuthenticateClient.NO – ensure that the client remains anonymous
◆ AuthenticateServer.YES – authenticate the server to the client
◆ AuthenticateServer.NO – ensure that the server remains anonymous
◆ Delegation.YES – if the client authenticates to the server, then delegate
from the client to the server, such that the server can authenticate using the
client’s identity
◆ Delegation.NO – ensure that the client does not delegate to the server

Delegation.YES does not directly imply an AuthenticateClient.YES con-


straint; that must be specified separately.
Serialization for these classes is guaranteed to produce instances that are com-
parable with ==.

2.4 DelegationDuration

Delegation duration constraints are represented with the following class:


package javax.rmi.security;
public final class DelegationDuration
implements RelativeTimeConstraint, Serializable
{
public DelegationDuration(long min, long max);
public long getMin();
public long getMax();
}

DelegationDuration represents a constraint that, if delegation is used, the


delegation be permitted for at least the min duration, but no longer than the max
duration (the range is inclusive at both ends). This constraint does not directly
imply a Delegation.YES constraint; that must be specified separately. Durations
are specified in milliseconds. Durations are translated into absolute end times at
the point of a remote call, by adding the caller’s current time to both min and max
values. As such, in order to accommodate clock skew between systems, negative
durations are permitted, and may be desirable for minimum durations.

EARLY LOOK DRAFT 2


12 CONSTRAINTS

The constructors throw IllegalArgumentException if max is less than min.


The makeAbsolute method returns a DelegationEndTime instance with the
base time parameter added to both min and max values.
Two DelegationDuration instances are equal if they have the same min and
max values.

2.5 DelegationEndTime

Delegation time constraints are represented with the following class:


package javax.rmi.security;
public final class DelegationEndTime
implements SecurityConstraint, Serializable
{
public DelegationEndTime(long min, long max);
public long getMin();
public long getMax();
}

DelegationEndTime represents a constraint that, if delegation is used, the


delegation be permitted until at least the min end time, but no longer than the max
end time (the range is inclusive at both ends). This constraint does not directly
imply a Delegation.YES constraint; that must be specified separately. End times
are specified in milliseconds from midnight, January 1, 1970 UTC. In order to
accommodate clock skew between systems, end times earlier than the current time
are permitted, and may be desirable for minimum end times.
The constructors throw IllegalArgumentException if max is less than min.
Two DelegationEndTime instances are equal if they have the same min and
max values.

2.6 ClientMinPrincipal

package javax.rmi.security;
public final class ClientMinPrincipal
implements SecurityConstraint, Serializable
{
public ClientMinPrincipal(Principal principal);
public ClientMinPrincipal(Principal[] principals);

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 13

public ClientMinPrincipal(Collection c);


public Set elements();
}

ClientMinPrincipal represents a constraint that, if the client authenticates


itself, then it must authenticate itself as at least all of the specified principals. This
constraint does not directly imply an AuthenticateClient.YES constraint; that
must be specified separately.
The first constructor is equivalent to calling the second constructor with a sin-
gle-element array containing the specified principal.
The second and third constructors throw NullPointerException if the
parameter is null, and throw IllegalArgumentException if the parameter is
empty or if the elements are not all instances of trusted principal classes (see Sec-
tion 2.13). The parameter passed to the constructor is not retained; subsequent
changes to that parameter have no effect on the instance created. Duplicate princi-
pals are removed.
The elements method returns an immutable set of all of the principals. Any
attempt to modify the set results in UnsupportedOperationException being
thrown.
Two ClientMinPrincipal instances are equal if they have equal principals
(ignoring order).

2.7 ClientMaxPrincipal

package javax.rmi.security;
public final class ClientMaxPrincipal
implements SecurityConstraint, Serializable
{
public ClientMaxPrincipal(Principal principal);
public ClientMaxPrincipal(Principal[] principals);
public ClientMaxPrincipal(Collection c);
public Set elements();
}

ClientMaxPrincipal represents a constraint that, if the client authenticates


itself, then it must authenticate itself as at most the specified principals. This con-
straint does not directly imply an AuthenticateClient.YES constraint; that must
be specified separately.
The first constructor is equivalent to calling the second constructor with a sin-
gle-element array containing the specified principal.

EARLY LOOK DRAFT 2


14 CONSTRAINTS

The second and third constructors throw NullPointerException if the


parameter is null, and throw IllegalArgumentException if the parameter is
empty or if the elements are not all instances of trusted principal classes (see Sec-
tion 2.13). The parameter passed to the constructor is not retained; subsequent
changes to that parameter have no effect on the instance created. Duplicate princi-
pals are removed.
The elements method returns an immutable set of all of the principals. Any
attempt to modify the set results in UnsupportedOperationException being
thrown.
Two ClientMaxPrincipal instances are equal if they have equal principals
(ignoring order).

2.8 ClientMinPrincipalType

package javax.rmi.security;
public final class ClientMinPrincipalType
implements SecurityConstraint, Serializable
{
public ClientMinPrincipalType(Class clazz);
public ClientMinPrincipalType(Class[] classes);
public ClientMinPrincipalType(Collection c);
public Set elements();
}

ClientMinPrincipalType represents a constraint that, if the client authenti-


cates itself, then it must authenticate itself such that, for each specified class, at
least one authenticated principal is an instance of that class. This constraint does
not directly imply an AuthenticateClient.YES constraint; that must be speci-
fied separately.
The first constructor is equivalent to calling the second constructor with a sin-
gle element array containing the specified class.
The second and third constructors throw NullPointerException if the
parameter is null, and throw IllegalArgumentException if the parameter is
empty or if the elements are not all trusted principal classes (see Section 2.13).
The parameter passed to the constructor is not retained; subsequent changes to
that parameter have no effect on the instance created. Redundant classes are
removed as follows: for any two specified classes c1 and c2, if
c1.isAssignableFrom(c2) is true, then c1 is removed.

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 15

The elements method returns an immutable set of all of the classes. Any
attempt to modify the set results in UnsupportedOperationException being
thrown.
Two ClientMinPrincipalType instances are equal if they have equal classes
(ignoring order).

2.9 ClientMaxPrincipalType

package javax.rmi.security;
public final class ClientMaxPrincipalType
implements SecurityConstraint, Serializable
{
public ClientMaxPrincipalType(Class clazz);
public ClientMaxPrincipalType(Class[] classes);
public ClientMaxPrincipalType(Collection c);
public Set elements();
}

ClientMaxPrincipalType represents a constraint that, if the client authenti-


cates itself, then each authenticated principal must be an instance of at least one of
the specified classes. This constraint does not directly imply an
AuthenticateClient.YES constraint; that must be specified separately.
The first constructor is equivalent to calling the second constructor with a sin-
gle element array containing the specified class.
The second and third constructors throw NullPointerException if the
parameter is null, and throw IllegalArgumentException if the parameter is
empty or if the elements are not all trusted principal classes (see Section 2.13).
The parameter passed to the constructor is not retained; subsequent changes to
that parameter have no effect on the instance created. Redundant classes are
removed as follows: for any two specified classes c1 and c2, if
c1.isAssignableFrom(c2) is true, then c2 is removed.
The elements method returns an immutable set of all of the classes. Any
attempt to modify the set results in UnsupportedOperationException being
thrown.
Two ClientMaxPrincipalType instances are equal if they have equal classes
(ignoring order).

EARLY LOOK DRAFT 2


16 CONSTRAINTS

2.10 ServerMinPrincipal

package javax.rmi.security;
public final class ServerMinPrincipal
implements SecurityConstraint, Serializable
{
public ServerMinPrincipal(Principal principal);
public ServerMinPrincipal(Principal[] principals);
public ServerMinPrincipal(Collection c);
public Set elements();
}

ServerMinPrincipal represents a constraint that, if the server authenticates


itself, then it must authenticate itself as at least all of the specified principals. This
constraint does not imply directly an AuthenticateServer.YES constraint; that
must be specified separately.
It is important to understand that specifying AuthenticateServer.YES as a
requirement does not, in and of itself, ensure that a server is to be trusted; it does
ensure that the server authenticates itself as someone, but it does not ensure that
the server authenticates itself as anyone in particular. Without knowing who the
server authenticated itself as, there is no basis for actually trusting the server. The
client generally needs to specify a ServerMinPrincipal requirement in addition,
or else verify that the server has specified a satisfactory ServerMinPrincipal
requirement for each of the methods that the client cares about.
The first constructor is equivalent to calling the second constructor with a sin-
gle element array containing the specified principal.
The second and third constructors throw NullPointerException if the
parameter is null, and throw IllegalArgumentException if the parameter is
empty or if the elements are not all instances of trusted principal classes (see Sec-
tion 2.13). The parameter passed to the constructor is not retained; subsequent
changes to that parameter have no effect on the instance created. Duplicate princi-
pals are removed.
The elements method returns an immutable set all of the principals. Any
attempt to modify this set results in UnsupportedOperationException being
thrown.
Two ServerMinPrincipal instances are equal if they have equal principals
(ignoring order).
Note that ServerMaxPrincipal, ServerMinPrincipalType, and
ServerMaxPrincipalType classes do not exist. A server can constrain the maxi-
mum set of principals it will authenticate as by explicitly specifying a subject at
export time. Restricting the class of a server principal is not useful, because ulti-

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 17

mately a client needs to specify exact principal instances that a server must
authenticate as, in order to establish any useful basis for trusting the server.

2.11 AlternativeSecurityConstraints

Alternative constraints can be aggregated into a single overall constraint using the
AlternativeSecurityConstraints class:

package javax.rmi.security;
public final class AlternativeSecurityConstraints
implements RelativeTimeConstraint, Serializable
{
public static SecurityConstraint create(
SecurityConstraint[] constraints);
public static SecurityConstraints create(Collection c);
public Set elements();
public Class getElementType();
public boolean impliedBy(SecurityConstraint c);
}

The semantics of this aggregate constraint is that at least one of the individual
constraints must be satisfied.
The create methods throw NullPointerException if the parameter value is
null. The methods throw IllegalArgumentException if: the parameter is
empty; or if any of the elements are instances of
AlternativeSecurityConstraints; or if the elements are not all instances of
the same concrete class; or if the elements are not all instances of trusted con-
straint classes (see Section 2.13). The parameter passed to the method is not
retained; subsequent changes to that parameter have no effect on the instance cre-
ated. Redundant constraints are removed as follows: for any two specified con-
straints c1 and c2, if c1.implies(c2) is true, then c1 is removed. If a single
constraint remains, then that constraint is returned, otherwise an instance of
AlternativeSecurityConstraints containing the resulting constraints is
returned.
Note that this class implements RelativeTimeConstraint even though the
constraint elements might not implement RelativeTimeConstraint. The
makeAbsolute method simply returns the AlternativeSecurityConstraints
instance if the constraint elements are not instances of
RelativeTimeConstraint, otherwise it converts the constraint elements using
their makeAbsolute method and returns the result of invoking the create method
of AlternativeSecurityConstraints with the converted constraints.

EARLY LOOK DRAFT 2


18 CONSTRAINTS

The elements method returns an immutable set of all the constraints. Any
attempt to modify this set results in UnsupportedOperationException being
thrown.
The getElementType method returns the class of the constraint elements.
Two AlternativeSecurityConstraints instances are equal if they have
equal constraints (ignoring order).
The semantics of the impliedBy method is described in Section 2.14.9.

2.12 SecurityConstraints

Constraints are aggregated using the SecurityConstraints class:


package javax.rmi.security;
public final class SecurityConstraints
implements Cloneable, Serializable
{
public static final SecurityConstraints EMPTY;
public SecurityConstraints();
public SecurityConstraints(SecurityConstraint req,
SecurityConstraint pref);
public SecurityConstraints(SecurityConstraint[] reqs,
SecurityConstraint[] prefs);
public SecurityConstraints(Collection reqs,
Collection prefs);
public SecurityConstraints(
SecurityConstraints constraints);
public Set requirements();
public Set preferences();
public boolean implies(SecurityConstraint c);
public boolean implies(SecurityConstraints constraints);
public void setReadOnly();
public boolean isReadOnly();
public boolean isEmpty();
public static SecurityConstraints copyReadOnly(
SecurityConstraints constraints);
public static SecurityConstraints combineAbsolute(
SecurityConstraints constraints1,
SecurityConstraints constraints2);
public Object clone();
}

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 19

A SecurityConstraints instance can be mutable or read-only (immutable).


Any attempt to alter a read-only instance will result in
UnsupportedOperationException being thrown. The implementation is not
synchronized; if multiple threads access a mutable instance concurrently, and at
least one of the threads modifies the instance, external synchronization must be
used. Only instances of trusted constraint classes (see Section 2.13) can be added
to a SecurityConstraints instance; attempts to add other objects will result in
IllegalArgumentException being thrown.
The static field EMPTY is an empty read-only instance, one that has no require-
ments and no preferences.
The first constructor creates an empty mutable instance.
The second constructor creates a read-only instance that has the first parame-
ter (if non-null) added as a requirement and has the second parameter (if non-null)
added as a preference.
The third and fourth constructors create a read-only instance that has all of the
constraints from the first parameter (if non-null) added as requirements and has all
of the constraints from the second parameter (if non-null) added as preferences.
The fifth constructor creates a mutable copy of the parameter, containing the
same requirements and preferences.
The requirements method returns the set of all requirements. The
preferences method returns the set of all preferences. The iterators of these sets
are fail-fast: if the set is modified after an iterator is created, the iterator will throw
ConcurrentModificationException. All Set methods are fully supported, but
adding a constraint to either set has special semantics.
Adding a new requirement c1 to the requirements set results in a simplifica-
tion of both the requirements and preferences sets, as follows. If any existing
requirement implies c1, then c1 is not actually added, and there is no other side
effect. Otherwise, for each existing requirement and each existing preference c2:

◆ if c1.implies(c2) is true, then c2 is removed, otherwise


◆ if c1.intersect(c2) returns null and c2 is a preference, then c2 is
removed, otherwise
◆ if c1.intersect(c2) returns a constraint (not COMPLEX_INTERSECT), then
c2 is removed and the returned constraint is added.

Finally, if none of the calls to intersect with an existing requirement


returned a constraint (or if no calls were made), then c1 is added to the require-
ments set.
Adding a new preference c1 to the preferences set results in a simplification
of the preferences set, as follows. If c1 is equal to any existing preference, or any

EARLY LOOK DRAFT 2


20 CONSTRAINTS

existing requirement implies c1, or the intersection of any existing requirement


with c1 is null, then c1 is not actually added, and there is no other side effect. If
there is any existing requirement c2 such that c1.intersect(c2) returns a con-
straint that is not equal to c1, then that constraint is added as a preference instead.
Otherwise, c1 is added as a preference.
SecurityConstraints instance s implies SecurityConstraint instance c
if there exists a requirement r in s such that r implies c.
For two SecurityConstraints instances c1 and c2, c1 implies c2 if c1
implies each requirement in c2.
The setReadOnly method makes the instance read only. It has no effect if the
instance is already read-only.
The isReadOnly method returns true if the instance is read only, and false
if the instance is mutable.
The isEmpty method returns true if the instance has no requirements and no
preferences, and returns false otherwise.
The copyReadOnly method returns a read-only instance that is equal to the
parameter, or a read-only empty instance if the parameter value is null.
The combineAbsolute method returns a read-only SecurityConstraints
instance with all of the requirements and preferences of both parameters added,
plus all of the requirements and preferences of the current context constraints (as
returned by Security.getContextConstraints, see Section 3.2) added, and
with every requirement and preference that is an instance of
RelativeTimeConstraint replaced by the result of invoking the constraint’s
makeAbsolute method with the current time (as returned by
System.currentTimeMillis). A null parameter value is treated the same as an
empty instance. This method can be used by a custom proxy implementation to
combine the current context constraints with the proxy’s client and server con-
straints, in preparation for a remote call.
Two SecurityConstraints instances are equal if they have equal require-
ments sets and equal preferences sets, independent of whether either or both
instances are mutable or read-only.
If the clone method is invoked on a read-only instance, the return value may
be the identical object.

2.13 Trusted Classes

The SecurityConstraint classes that are trusted can be extended beyond those
defined in this specification using security providers. A list of TrustVerifier
instances (see Section 5.1) is obtained as specified in Section 5. The
trustedConstraintClass method of each one is called with the constraint class.

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 21

If any method returns true, the class is trusted. If none of the methods returns
true, SecurityException is thrown.
The Principal classes that are trusted are defined in a similar fashion to con-
straint classes. The trustedPrincipalClass method of each TrustVerifier
instance is called with the principal class. If any method returns true, the class is
trusted. If none of the methods returns true, SecurityException is thrown.

2.14 Implies

The detailed semantics of the implies method for each constraint class, and the
impliedBy method of AlternativeSecurityConstraints, are given in this
Section. In general, application developers do not need to be concerned with the
details provided in this Section.

2.14.1 Basic Constraints

For each basic constraint class (those with YES and NO constants), instance c1 of
the class implies instance c2 of the same class if the two instances are equal.
AuthenticateClient.NO implies any instance of class Delegation,
DelegationDuration, DelegationEndTime, ClientMinPrincipal,
ClientMinPrincipalType, ClientMaxPrincipal, or
ClientMaxPrincipalType.
AuthenticateServer.NO implies any instance of class
ServerMinPrincipal.
Delegation.NO implies any instance of class DelegationDuration or
DelegationEndTime.
For each basic constraint class, instance c1 of the class implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.
For any other instance c2, c1.implies(c2) is false.

2.14.2 DelegationDuration

DelegationDuration instance c1 implies DelegationDuration instance c2 if


c1.getMin() >= c2.getMin() && c1.getMax() <= c2.getMax()

is true.
DelegationDuration instance c1 implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.
For any other instance c2, c1.implies(c2) is false.

EARLY LOOK DRAFT 2


22 CONSTRAINTS

2.14.3 DelegationEndTime

DelegationEndTime instance c1 implies DelegationEndTime instance c2 if


c1.getMin() >= c2.getMin() && c1.getMax() <= c2.getMax()

is true.
DelegationEndTime instance c1 implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.
For any other instance c2, c1.implies(c2) is false.

2.14.4 ClientMinPrincipal

ClientMinPrincipal instance c1 implies ClientMinPrincipal instance c2 if,


for each principal in c2, there exists an equal principal in c1.
ClientMinPrincipal instance c1 implies ClientMinPrincipalType
instance c2 if, for each class c in c2, there exists a principal p in c1 such that
c.isInstance(p) is true.
ClientMinPrincipal instance c1 implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.
For any other instance c2, c1.implies(c2) is false.

2.14.5 ClientMaxPrincipal

ClientMaxPrincipal instance c1 implies ClientMaxPrincipal instance c2 if,


for each principal in c1, there exists an equal principal in c2.
ClientMaxPrincipal instance c1 implies ClientMaxPrincipalType
instance c2 if, for each principal p in c1, there exists a class c in c2 such that
c.isInstance(p) is true.
ClientMaxPrincipal instance c1 implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.
For any other instance c2, c1.implies(c2) is false.

2.14.6 ClientMinPrincipalType

ClientMinPrincipalType instance c1 implies ClientMinPrincipalType


instance c2 if, for each class t2 in c2, there exists a class t1 in c1 such that
t2.isAssignableFrom(t1) is true.
ClientMinPrincipalType instance c1 implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 23

For any other instance c2, c1.implies(c2) is false.

2.14.7 ClientMaxPrincipalType

ClientMaxPrincipalType instance c1 implies ClientMaxPrincipalType


instance c2 if, for each class t1 in c1, there exists a class t2 in c2 such that
t2.isAssignableFrom(t1) is true.
ClientMaxPrincipalType instance c1 implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.
For any other instance c2, c1.implies(c2) is false.

2.14.8 ServerMinPrincipal

ServerMinPrincipal instance c1 implies ServerMinPrincipal instance c2 if,


for each principal in c2, there exists an equal principal in c1.
ServerMinPrincipal instance c1 implies
AlternativeSecurityConstraints instance c2 if c2.impliedBy(c1) is true.
For any other instance c2, c1.implies(c2) is false.

2.14.9 AlternativeSecurityConstraints

AlternativeSecurityConstraints instance c1 implies constraint c2 (of any


type, not just AlternativeSecurityConstraints) if for each constraint c in c1,
c.implies(c2) is true.
AlternativeSecurityConstraints instance c1 is implied by constraint c2
(that is, c1.impliedBy(c2) is true) if there exists at least one constraint c in c1
such that c2.implies(c) is true. This method exists primarily as a convenience
to help both specify and implement the implies methods of other constraint
classes when the method’s parameter is an instance of
AlternativeSecurityConstraints.

2.15 Intersect

The detailed semantics of the intersect method for each constraint class are
given in this Section. In general, application developers do not need to be con-
cerned with the details provided in this Section.

EARLY LOOK DRAFT 2


24 CONSTRAINTS

2.15.1 Basic Constraints

For any two instances c1 and c2 of the same basic constraint class (those with YES
and NO constants), c1.intersect(c2) returns c1 if the instances are equal, and
returns null otherwise.
For any Delegation instance c, c.intersect(AuthenticateClient.NO)
returns AuthenticateClient.NO.
For any other instance c1 of a basic constraint class and any other constraint
instance c2, c1.intersect(c2) returns c1 if c1.implies(c2) is true, and
returns COMPLEX_INTERSECT otherwise.

2.15.2 DelegationDuration

For DelegationDuration instances c1 and c2, c1.intersect(c2) returns a


DelegationDuration instance with a min duration of

Math.max(c1.getMin(), c2.getMin())

and a max duration of


Math.min(c1.getMax(), c2.getMax())

if the computed min is less than or equal to the computed max. Otherwise the
result is null.
For DelegationDuration instance c, c.intersect(Delegation.NO)
returns Delegation.NO and c.intersect(AuthenticateClient.NO) returns
AuthenticateClient.NO.
For DelegationDuration instance c1 and
AlternativeSecurityConstraints instance c2, the semantics of
c1.intersect(c2) is described under AlternativeSecurityConstraints for
the symmetric c2.intersect(c1).
For DelegationDuration instance c1 and any other constraint instance c2,
c1.intersect(c2) returns COMPLEX_INTERSECT.

2.15.3 DelegationEndTime

For DelegationEndTime instances c1 and c2, c1.intersect(c2) returns a


DelegationEndTime instance with a min end time of

Math.max(c1.getMin(), c2.getMin())

and a max end time of


Math.min(c1.getMax(), c2.getMax())

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 25

if the computed min is less than or equal to the computed max. Otherwise the
result is null.
For DelegationEndTime instance c, c.intersect(Delegation.NO) returns
Delegation.NO and c.intersect(AuthenticateClient.NO) returns
AuthenticateClient.NO.
For DelegationEndTime instance c1 and
AlternativeSecurityConstraints instance c2, the semantics of
c1.intersect(c2) is described under AlternativeSecurityConstraints for
the symmetric c2.intersect(c1).
For DelegationEndTime instance c1 and any other constraint instance c2,
c1.intersect(c2) returns COMPLEX_INTERSECT.

2.15.4 ClientMinPrincipal

For ClientMinPrincipal instances c1 and c2, c1.intersect(c2) returns a


ClientMinPrincipal constructed from the combined principals of both c1 and
c2.
For ClientMinPrincipal instance c1 and ClientMinPrincipalType
instance c2, if c1.implies(c2) is true, then the result of c1.intersect(c2) is
equal to c1, otherwise the result is COMPLEX_INTERSECT.
For ClientMinPrincipal instance c1 and ClientMaxPrincipal instance
c2, c1.intersect(c2) returns null if the principals in c1 are not a subset of the
principals in c2, and returns COMPLEX_INTERSECT otherwise.
For ClientMinPrincipal instance c1 and ClientMaxPrincipalType
instance c2, c1.intersect(c2) returns null if there exists a principal in c1 that
is not an instance of any class in c2, and returns COMPLEX_INTERSECT otherwise.
For ClientMinPrincipal instance c,
c.intersect(AuthenticateClient.NO) returns AuthenticateClient.NO.
For ClientMinPrincipal instance c1 and
AlternativeSecurityConstraints instance c2, the semantics of
c1.intersect(c2) is described under AlternativeSecurityConstraints for
the symmetric c2.intersect(c1).
For ClientMinPrincipal instance c1 and any other constraint instance c2,
c1.intersect(c2) returns COMPLEX_INTERSECT.

2.15.5 ClientMaxPrincipal

For ClientMaxPrincipal instances c1 and c2, c1.intersect(c2) returns a


ClientMaxPrincipal constructed from the principals common to both c1 and c2,
or null if there are no principals in common.

EARLY LOOK DRAFT 2


26 CONSTRAINTS

For ClientMaxPrincipal instance c1 and ClientMaxPrincipalType


instance c2, c1.intersect(c2) returns a ClientMaxPrincipal constructed
from the principals of c1 that are instances of at least one of the classes in c2, or
null if there are no such principals.
For ClientMaxPrincipal instance c1 and ClientMinPrincipal instance
c2, c1.intersect(c2) returns null if the principals in c2 are not a subset of the
principals in c1, and returns COMPLEX_INTERSECT otherwise.
For ClientMaxPrincipal instance c1 and ClientMinPrincipalType
instance c2, c1.intersect(c2) returns null if there exists a class in c2 such that
no principal in c1 is an instance of that class, and returns COMPLEX_INTERSECT
otherwise.
For ClientMaxPrincipal instance c,
c.intersect(AuthenticateClient.NO) returns AuthenticateClient.NO.
For ClientMaxPrincipal instance c1 and
AlternativeSecurityConstraints instance c2, the semantics of
c1.intersect(c2) is described under AlternativeSecurityConstraints for
the symmetric c2.intersect(c1).
For ClientMaxPrincipal instance c1 and any other constraint instance c2,
c1.intersect(c2) returns COMPLEX_INTERSECT.

2.15.6 ClientMinPrincipalType

For ClientMinPrincipalType instances c1 and c2, c1.intersect(c2) returns


a ClientMinPrincipalType constructed from the combined classes of both c1
and c2.
For ClientMinPrincipalType instance c1 and ClientMinPrincipal
instance c2, if c2.implies(c1) is true, then the result of c1.intersect(c2) is
equal to c2, otherwise the result is COMPLEX_INTERSECT.
For ClientMinPrincipalType instance c1 and ClientMaxPrincipal
instance c2, c1.intersect(c2) returns null if there exists a class in c1 such that
no principal in c2 is an instance of that class, and returns COMPLEX_INTERSECT
otherwise.
For ClientMinPrincipalType instance c1 and ClientMaxPrincipalType
instance c2, c1.intersect(c2) returns null if there exists a class t1 in c1 such
that for every class t2 in c2, t2.isAssignableFrom(t1) is false, and returns
COMPLEX_INTERSECT otherwise.
For ClientMinPrincipalType instance c,
c.intersect(AuthenticateClient.NO) returns AuthenticateClient.NO.
For ClientMinPrincipalType instance c1 and
AlternativeSecurityConstraints instance c2, the semantics of

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 27

c1.intersect(c2) is described under AlternativeSecurityConstraints for


the symmetric c2.intersect(c1).
For ClientMinPrincipalType instance c1 and any other constraint instance
c2, c1.intersect(c2) returns COMPLEX_INTERSECT.

2.15.7 ClientMaxPrincipalType

For ClientMaxPrincipalType instances c1 and c2, a reduced set of classes is


computed as follows: for each pair of class t1 in c1 and class t2 in c2, if
t1.isAssignableFrom(t2) then t2 is included in the reduced set, or if
t2.isAssignableFrom(t1) then t1 is included in the reduced set. If the reduced
set is empty, then the result of c1.intersect(c2) is null, otherwise the result is
a ClientMaxPrincipalType constructed from the reduced set.
For ClientMaxPrincipalType instance c1 and ClientMaxPrincipal
instance c2, c1.intersect(c2) returns a ClientMaxPrincipal constructed
from the principals of c2 that are instances of at least one of the classes in c1, or
null if there are no such principals.
For ClientMaxPrincipalType instance c1 and ClientMinPrincipal
instance c2, c1.intersect(c2) returns null if there exists a principal in c2 that
is not an instance of any class in c1, and returns COMPLEX_INTERSECT otherwise.
For ClientMaxPrincipalType instance c1 and ClientMinPrincipalType
instance c2, c1.intersect(c2) returns null if there exists a class t2 in c2 such
that for every class t1 in c1, t1.isAssignableFrom(t2) is false, and returns
COMPLEX_INTERSECT otherwise.
For ClientMaxPrincipalType instance c,
c.intersect(AuthenticateClient.NO) returns AuthenticateClient.NO.
For ClientMaxPrincipalType instance c1 and
AlternativeSecurityConstraints instance c2, the semantics of
c1.intersect(c2) is described under AlternativeSecurityConstraints for
the symmetric c2.intersect(c1).
For ClientMaxPrincipalType instance c1 and any other constraint instance
c2, c1.intersect(c2) returns COMPLEX_INTERSECT.

2.15.8 ServerMinPrincipal

For ServerMinPrincipal instances c1 and c2, c1.intersect(c2) returns a


ServerMinPrincipal constructed from the combined principals of both c1 and
c2.
For ServerMinPrincipal instance c,
c.intersect(AuthenticateServer.NO) returns AuthenticateServer.NO.

EARLY LOOK DRAFT 2


28 CONSTRAINTS

For ServerMinPrincipal instance c1 and


AlternativeSecurityConstraints instance c2, the semantics of
c1.intersect(c2) is described under AlternativeSecurityConstraints for
the symmetric c2.intersect(c1).
For ServerMinPrincipal instance c1 and any other constraint instance c2,
c1.intersect(c2) returns COMPLEX_INTERSECT.

2.15.9 AlternativeSecurityConstraints

For AlternativeSecurityConstraints instance c1 and any other constraint


instance c2 that is not itself an AlternativeSecurityConstraints instance, the
result of c1.intersect(c2) is obtained in the following manner. For each con-
straint c in c1, c.intersect(c2) is invoked. If any return value is
COMPLEX_INTERSECT, then the result of c1.intersect(c2) is
COMPLEX_INTERSECT. Otherwise, the null values are discarded and redundant con-
straints are removed from the non-null values in the same way as in the
AlternativeSecurityConstraints create method. If what remains is a single
constraint, then the result of c1.intersect(c2) is that single constraint. Other-
wise the result is an AlternativeSecurityConstraints instance containing the
remaining constraints.
For AlternativeSecurityConstraints instances c1 and c2, the result of
c1.intersect(c2) is obtained in the following manner. For each possible com-
bination of constraint x1 in c1 and constraint x2 in c2, x1.intersect(x2) is
invoked. If any return value is COMPLEX_INTERSECT, then the result of
c1.intersect(c2) is COMPLEX_INTERSECT. Otherwise, the null values are dis-
carded and redundant constraints are removed from the non-null values in the
same way as in the AlternativeSecurityConstraints create method. If what
remains is a single constraint, then the result of c1.intersect(c2) is that single
constraint. Otherwise the result is an AlternativeSecurityConstraints
instance containing the remaining constraints.

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 29

3 Client Interfaces

3.1 RemoteSecurity

Client security constraints can be attached to individual stubs, and server con-
straints can be queried, using the RemoteSecurity interface:
package javax.rmi.security;
public interface RemoteSecurity {
RemoteSecurity setClientConstraints(
SecurityConstraints constraints);
SecurityConstraints getClientConstraints();
SecurityConstraints getServerConstraints(String name,
Class[] parameterTypes)
throws NoSuchMethodException, RemoteException;
boolean equalsIgnoreConstraints(Object obj);
}

Secure RMI stubs implement this (local) RemoteSecurity interface. Servers


that define proxy interfaces to remote services are encouraged to implement this
interface as well, to give applications a uniform way to control security con-
straints.
The setClientConstraints method allows client constraints to be attached
to a copy of the proxy; these constraints completely replace (in the copy) any cur-
rent client constraints attached to the proxy. The constraints are copied at the time
it is passed in, and null is treated the same as an empty instance. The method
returns the new copy of the proxy.
The getClientConstraints method returns the current client constraints, as
a non-null read-only instance.
Client constraints attached to a proxy are included in the serialized state of the
proxy; this is to allow a service to be transparent to the client’s needs. For exam-
ple, if remote object S 1 obtains a proxy for remote object S 2 , and passes that
proxy to remote object S 3 , expecting S 3 to invoke a method on S 2 , then S 1 can
control the security of that call by attaching its constraints directly to the proxy
before passing it to S 3 . If a service does not wish to be transparent in this way,

EARLY LOOK DRAFT 2


30 CLIENT INTERFACES

then it should explicitly reset the constraints on received proxies to whatever is


appropriate to implement its own security policy.
The getServerConstraints method returns the server’s constraints. The
values can vary with the remote method, so the particular method must be speci-
fied by giving the method name and parameter types. The value of
parameterTypes can be null, which is treated the same as an empty array. The
method returns a non-null read-only instance. IllegalArgumentException is
thrown if the specified method exists but is not a remote method. For stubs created
using SecureUnicastRemoteObject (see Section 4.1), this method will never
actually throw RemoteException; the state is constant, and is maintained inside
the stub’s reference. For stubs created using SecureActivatable (see Section
4.2), this method can throw RemoteException, and the return values can change
over time; the state is maintained inside the transient live reference. Proxies that
implement RemoteSecurity can choose whether this state is constant or variable.
The equalsIgnoreConstraints method of a stub ignores both client and
server security constraints; it simply checks that the two stubs are for the same
remote object. The equals method includes both client and server constraints.
Proxy classes that implement RemoteSecurity should implement equivalent
semantics for equals and equalsIgnoreConstraints.

3.2 Security

The Security class provides methods for executing actions with contextual client
security constraints, and for establishing trust in downloaded stubs and proxies:
package javax.rmi.security;
public final class Security {
public static Object doConstrained(
PrivilegedAction action,
SecurityConstraints constraints);
public static Object doConstrained(
PrivilegedExceptionAction action,
SecurityConstraints constraints)
throws PrivilegedActionException;
public static SecurityConstraints getContextConstraints();
public static void establishProxyTrust(
Object proxy,
SecurityConstraints constraints)
throws RemoteException;
}

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 31

Client constraints can be set contextually using the doConstrained methods.


A null parameter will result in NullPointerException being thrown. Con-
straints set in this way will be applied to all secure RMI calls made by this thread
during execution of the action’s run method. The object returned by the run
method is returned by doConstrained. The constraints are effectively copied
before the action is performed; changes to the parameter instance while the action
is executing have no effect on the constraints applied to the action.
When a new thread is created, the active client constraints for the creating
thread become the base constraints for the new thread. When an RMI remote
object is exported, the active client constraints at the time of export become the
base constraints for all subsequent incoming remote calls to that object.
The getContextConstraints method returns all of the active client con-
straints for this thread, including all active doConstrained frames and any base
constraints for the thread. The method returns a non-null read-only instance.
The establishProxyTrust method should be called by a client with a down-
loaded proxy, before the client makes any other use of the proxy, in order to estab-
lish basic trust that the proxy will correctly implement the RemoteSecurity
interface. In the simplest case, the proxy is implemented using only trusted code,
and establishProxyTrust simply has to verify that the proxy code is in fact
trusted. In the more general case, the server should first be authenticated (using
code that is known to be trusted) as a subject trusted by the client, and then the
server is asked if it trusts the proxy code. If the server trusts the proxy, and the cli-
ent trusts the server, then the client can transitively trust the proxy. If the proxy
relies on activation, then the activator should be authenticated as a subject trusted
by the server, and it must be verified that all future calls to the activator will con-
tinue to authenticate the activator as a subject trusted by the server. If the server
trusts the activator, and the client trusts the server, then the client again can transi-
tively trust the activator.
A proxy is a secure RMI stub if Proxy.isProxyClass(proxy.getClass())
is true, and if its InvocationHandler instance is an instance of a class trusted by
the secure RMI implementation. (See http://java.sun.com/products/jdk/1.3/docs/
guide/reflection/proxy.html for the specification of Proxy and
InvocationHandler.)
The establishProxyTrust method first checks to see if the proxy imple-
ments RemoteSecurity. If it does not, SecurityException is thrown.
If the proxy is a secure RMI stub for a server exported as a
SecureUnicastRemoteObject (see Section 4.1), each
SecureClientSocketFactory instance (see Section 5.4) contained in the proxy
is checked to ensure it is an instance of a trusted class, by consulting a list of
TrustVerifier instances (see Section 5.1). The
trustedClientSocketFactoryClass method of each TrustVerifier instance

EARLY LOOK DRAFT 2


32 CLIENT INTERFACES

is called with the factory class as a parameter. If any method returns true, the
class is trusted. If none of the methods return true, SecurityException is
thrown. In this case, no remote communication takes place, and the constraints
passed as a parameter are not used.
If the proxy is a secure RMI stub for a server exported as a
SecureActivatable (see Section 4.2) the following checks are made:

◆ A remote call is made through the InvocationHandler instance for the


getActivatorConstraints method of the ActivatorSecurity interface
(see Section 4.3), activating the server as necessary. This call must return
normally. The client constraints used for the call are the constraints passed
as a parameter to establishProxyTrust. The caller is responsible for spec-
ifying AuthenticateServer.YES and an appropriate
ServerMinPrincipal instance as requirements, if it wants the server to be
authenticated. Prior to the call, each SecureClientSocketFactory
instance contained in the proxy is checked to ensure it is an instance of a
trusted class, in the same manner as described above.
◆ A call to establishProxyTrust, passing the ActivationID (as the proxy)
and the constraints returned by getActivatorConstraints, must return
normally. The server is responsible for specifying
AuthenticateServer.YES and an appropriate ServerMinPrincipal
instance as requirements in those constraints, if it wants the activator to be
authenticated.
◆ The constraints returned by getActivatorConstraints must be the same
as the client constraints obtained from the ActivationID using its
RemoteSecurity getClientConstraints method.

If these checks do not succeed, SecurityException is thrown. If the call to


getActivatorConstraints or the nested call to establishProxyTrust throws
an exception, that exception is thrown to the caller.
If the proxy is not a secure RMI stub, but the proxy’s class has a non-static
non-public declared (not inherited) method with signature
CheckProxySource getSecureProxy();
the following checks are made:

◆ The value returned by that getSecureProxy method must itself be trusted;


that is, a call to establishProxyTrust, passing that return value and the
same constraints parameter, must return normally.
◆ A call to that return value’s checkProxySource method (see Section 4.4),
passing the codebase and signers of the proxy’s class, must return normally;

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 33

the client constraints used for the call are the constraints passed as a param-
eter to establishProxyTrust. The client is responsible for specifying
AuthenticateServer.YES and an appropriate ServerMinPrincipal
instance as requirements, if it wants the server to be authenticated.

If these checks do not succeed, SecurityException is thrown. If the call to


checkProxySource or the nested call to establishProxyTrust throws an excep-
tion that is thrown to the caller.
If the proxy is not a secure RMI stub, and does not have the appropriate
getSecureProxy method, then an ordered list of TrustVerifier instances (see
Section 5.1) is obtained as specified in Section 5. The trustedProxy method of
each one is called (in order) with the proxy and constraints parameters. If any
method returns true, establishProxyTrust returns normally. If any method
throws an exception, that exception is thrown to the caller. If none of the methods
returns true, SecurityException is thrown.

3.3 UnsupportedSecurityException

There is one new security-related exception:


package javax.rmi.security;
public class UnsupportedSecurityException
extends RemoteException
{
public SecurityConstraints constraints;
public UnsupportedSecurityException(
SecurityConstraints constraints);
public UnsupportedSecurityException(
String s,
SecurityConstraints constraints);
}

This exception is only checked and thrown at the point a remote method is
invoked. For example, it is possible to attach a client requirement to a stub that is
not supported by the server, or that is not supported by the RMI implementation in
which the client is executing, without an exception immediately being thrown.
UnsupportedSecurityException can be thrown at the point a remote
method is invoked for any of the following reasons:

◆ A client requirement is not supported by the server.

EARLY LOOK DRAFT 2


34 CLIENT INTERFACES

◆ A client or server requirement conflicts with some other client or server


requirement.
◆ A client or server requirement cannot be satisfied by the RMI implementa-
tion in which the client is executing.
◆ For a client or server requirement, the RMI implementation in which the cli-
ent is executing does not implement any algorithm in common with the
server.
◆ A delegated remote call is being attempted, and the current time is either ear-
lier than the minimum granted delegation time or later than the maximum
granted delegation time.

The combined client and server constraints for the call are given as a non-null
read-only instance in a field of the exception. No specific indication is given as to
which requirements could not be satisfied.
The UnsupportedSecurityException constructor produces a non-null read-
only copy of the constraints (which can be null) passed as a parameter.

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 35

4 Server Interfaces

4.1 SecureUnicastRemoteObject

There is a new class for implementing secure unicast remote objects:


package javax.rmi.security.server;
public class SecureUnicastRemoteObject extends RemoteServer {
protected SecureUnicastRemoteObject(SecureExportDesc desc)
throws RemoteException;
public static Remote exportObject(Remote obj,
SecureExportDesc desc)
throws RemoteException;
public static SecurityConstraints getSecurityConstraints()
throws ServerNotActiveException;
public static Subject getClientSubject()
throws ServerNotActiveException;
}

As with UnicastRemoteObject, it is not necessary to extend


SecureUnicastRemoteObject; you can use the static exportObject method
instead.
An active remote method can use the getSecurityConstraints method to
obtain the constraints that are in force for the current call. A non-null read-only
instance is returned that has only requirements, no preferences, and no relative-
time constraints. ServerNotActiveException is thrown if the current thread is
not executing an incoming remote method.
An active remote method can use the getClientSubject method to obtain
the authenticated identity of the client for the current call. This requires a TBD
security permission. Null is returned if the client was not authenticated.
ServerNotActiveException is thrown if the current thread is not executing an
incoming remote method. If the client delegated to the server, then the returned
subject contains any derived delegation credentials. The server can then imperson-
ate the client by performing outbound secure calls (or by receiving incoming

EARLY LOOK DRAFT 2


36 SERVER INTERFACES

secure calls) in the context of a Subject.doAs invoked with the client subject as a
parameter.
The parameters passed to the remote method are automatically unmarshalled
within the scope of either a Subject.doAs or a Subject.doAsPrivileged with
the client subject. If the server implements CallAccessControl (see Section 4.5)
and the return value from its checkCallAccessControl method is true, then
doAsPrivileged is used, otherwise doAs is used.

4.2 SecureActivatable

There is a new class for implementing secure activatable objects:


package javax.rmi.security.activation;
public abstract class SecureActivatable extends RemoteServer {
protected SecureActivatable(
String location,
MarshalledObject data,
boolean restart,
SecureExportDesc desc,
SecurityConstraints activatorConstraints)
throws ActivationException, RemoteException;
protected SecureActivatable(
ActivationID id,
SecureExportDesc desc,
SecurityConstraints activatorConstraints)
throws RemoteException;
protected ActivationID getID();
public static Remote register(
ActivationDesc desc,
SecurityConstraints activatorConstraints)
throws ActivationException, RemoteException;
public static ActivationID exportObject(
Remote obj,
String location,
MarshalledObject data,
boolean restart,
SecureExportDesc desc,
SecurityConstraints activatorConstraints)
throws ActivationException, RemoteException;
public static Remote exportObject(

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 37

Remote obj,
ActivationID id,
SecureExportDesc desc)
throws RemoteException;
}

The first constructor can be used to register a new object and export it. A sub-
class of SecureActivatable must call this constructor to register and export the
object during initial construction.
The second constructor is used to activate and export an object that has
already been registered. A subclass of SecureActivatable must call this con-
structor when the object itself is activated using its special “activation” construc-
tor.
The getID method returns the object’s activation identifier. This activation
identifier implements RemoteSecurity, and the activator constraints passed to the
constructor will have been set as client constraints by the constructor. These con-
straints will also be set as client constraints in the ActivationID contained in the
stub for this activatable object.
The register method registers a new activatable object with the activation
system without having to first create that activatable object; it will subsequently
be activated on demand. The activator constraints are set as client constraints on
the ActivationID contained in the returned stub.
As with Activatable, it is not necessary to extend SecureActivatable; you
can use an exportObject method instead. The first exportObject method both
registers the object as a new activatable object, and exports it; the activator con-
straints are set as client constraints on the returned ActivationID, and will also
be set as client constraints in the ActivationID contained in the stub for this acti-
vatable object. The second exportObject method exports an activatable object
that has already been registered; it is assumed that any desired activator con-
straints have already been set as client constraints on the ActivationID.

4.3 ActivatorSecurity

The ActivatorSecurity interface is defined as:


package javax.rmi.security.activation;
public interface ActivatorSecurity {
SecurityConstraints getActivatorConstraints()
throws RemoteException;
}

EARLY LOOK DRAFT 2


38 SERVER INTERFACES

The getActivatorConstraints method returns a non-null read-only


instance.
An activatable object does not implement the ActivatorSecurity interface
directly. Instead, the dispatcher used to handle incoming remote calls will auto-
matically respond to the getActivatorConstraints method with the activator
constraints that were set as client constraints on the ActivationID when the
object was exported. However, the getActivatorConstraints method can be
specified in a MethodConstraints in the SecureExportDesc when exporting a
secure activatable object, and preinvocation access control (see Section 4.5) is
also supported for this method.

4.4 CheckProxySource

The CheckProxySource interface is defined as:


package javax.rmi.security.server;
public interface CheckProxySource extends Remote {
void checkProxySource(String codebase, Object[] signers)
throws RemoteException;
}

Remote objects that use specialized proxies (proxies that are not secure RMI
stubs) must implement this interface in order to allow clients to use
Security.establishProxyTrust.
Either or both parameters to the checkProxySource method may be null. If
these parameters identify proxy code that is considered trusted by the server, then
the method should just return normally. Otherwise it should throw an exception.

4.5 CallAccessControl

A remote object that exports itself as a SecureUnicastRemoteObject or


SecureActivatable can perform preinvocation access control, and exercise con-
trol over parameter unmarshalling, by implementing the CallAccessControl
interface:
package javax.rmi.security.server;
public interface CallAccessControl {
boolean checkCallAccessControl(Subject clientSubject,
Method method);
}

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 39

The checkCallAccessControl method will be called prior to each remote


method invocation, before the parameters of the call are unmarshalled. The first
parameter is the authenticated identity of the client, or null if the client was not
authenticated. The second parameter is the method that will be invoked. To pre-
vent the invocation, the method should throw a runtime exception; the exception
will be propagated back to the client. To allow the invocation to proceed, the
checkCallAccessControl method should return normally. The return value is
used as the privileged mode for unmarshalling parameters of the remote call (see
Section 4.1).
RemoteServer.getClientHost can be called from within
checkCallAccessControl.

4.6 SecureExportDesc

The SecureExportDesc class is defined as:


package javax.rmi.security.server;
public class SecureExportDesc {
public SecureExportDesc(
SecurityConstraints defaultConstraints)
throws UnsupportedSecurityException;
public SecureExportDesc(
SecurityConstraints defaultConstraints,
MethodConstraints[] methodConstraints,
Subject serverSubject)
throws UnsupportedSecurityException;
public SecureExportDesc(
SecurityConstraints defaultConstraints,
MethodConstraints[] methodConstraints,
Subject serverSubject,
Int[] ports,
SecureServerSocketFactory[] factories)
throws UnsupportedSecurityException;
public SecurityConstraints getDefaultConstraints();
public MethodConstraints[] getMethodConstraints();
public Subject getSubject();
public int[] getPorts();
public SecureServerSocketFactory[] getFactories();
}

The semantics of the constructor parameters are:

EARLY LOOK DRAFT 2


40 SERVER INTERFACES

◆ defaultConstraints – the default constraints for all DGC calls and for any
remote method that is not specified in methodConstraints. This value can
be null, which is treated the same as the empty instance.
◆ methodConstraints – constraints for specific remote methods. If null or
unspecified, defaults to the empty array. ExportException is thrown at
export time if any of the methods specified are not actually remote methods
for the exported object.
◆ serverSubject – the maximal subject that will be used when authenticating
the server to clients. The authenticated principals obtained by clients will
always be a subset of the principals in this subject. This value can be null.
If null or unspecified, defaults to the current executing subject (the value of
Subject.getSubject(AccessController.getContext())).
◆ ports – specific ports to export the object on. If null or unspecified, anon-
ymous ports are used as needed. If non-null, then factories must also be non-
null and the same length, or IllegalArgumentException is thrown. Each
port is paired with the corresponding server factory at the same index. A port
value of zero means that an anonymous port should be used. No two facto-
ries can be assigned the same non-zero port, or
IllegalArgumentException is thrown.
◆ factories – server factories (see Section 5.2) for generating secure sockets.
If null or unspecified, suitable factories are found as specified below.

In general, portable implementations will leave both ports and factories either
null or unspecified, and most developers do not need to be concerned with the
detailed semantics of socket factories.
Two SecureExportDesc instances are equal only if they are the identical (==)
object.
The getDefaultConstraints method returns a non-null read-only instance.
The getMethodConstraints method always returns a new non-null array
every time it is called.
Given a secure RMI stub for a remote object that was exported with this
export descriptor, the getServerConstraints method (see Section 3.1) of that
stub will return the constraints given in methodConstraints if there is a match,
otherwise the default constraints will be returned.
The getSubject method returns a non-null instance, or null if the
serverSubject was null or unspecified and the value of
Subject.getSubject(AccessController.getContext()) is null.
The getPorts method returns a new non-null array every time it is called. If
the ports constructor parameter was null or unspecified, this method returns an
array filled with zeros.

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 41

The getFactories method returns a new non-null array every time it is


called.
If server factories are not specified in the constructor, an ordered list of candi-
date factories is obtained as specified in Section 5. A factory is selected from this
list if there are constraints for at least one remote method such that the factory’s
supportsConstraints method returns true when invoked with the remote
method’s constraints and the serverSubject. The selected factories remain in
their original order in the list.
If server factories are specified in the constructor, then for each factory, there
must be at least one remote method such that the factory’s supportsConstraints
method returns true when invoked with the remote method’s constraints and the
serverSubject, or IllegalArgumentException is thrown.
Regardless of whether the server factories are specified or generated, it must
also be the case that for each remote method, there is at least one factory whose
supportsConstraints method returns true when invoked with the remote
method’s constraints and the serverSubject, or
UnsupportedSecurityException is thrown.
Multiple objects can be exported on the same port, provided that the server
factory and server subject are always the same (using the equals method).
The server factories are not transmitted in the remote reference; only the
derived client factories are transmitted. The order of factories is significant. When
a remote call is attempted, the “best” supported preferences are computed for each
derived client factory using the choosePreferences method (see Section 5.4).
The client factory used for the call will be the first client factory that supports all
of the requirements, and whose resulting constraints are either not implied by or
are equal to the resulting constraints of every other factory.

4.7 MethodConstraints

MethodConstraints is defined as:


package javax.rmi.security.server;
public class MethodConstraints implements Serializable {
public MethodConstraints(String name,
Class[] parameterTypes,
SecurityConstraints constraints);
public String getName();
public Class[] getParameterTypes();
public SecurityConstraints getConstraints();

EARLY LOOK DRAFT 2


42 SERVER INTERFACES

The name and parameterTypes specify the particular remote method to


which the specified security constraints apply. The constraints can be null, which
is treated the same as the empty instance. The value of parameterTypes can be
null, which is treated the same as an empty array.
The getParameterTypes method returns a new non-null array every time it is
called.
The getConstraints method returns a non-null read-only instance.
Two MethodConstraints instances are equal if they have equal names, equal
parameter types, and equal constraints.

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 43

5 Provider Interfaces

Security providers are specified in this section. In general, application developers


do not need to be concerned with the details provided in this section.
Security providers are used to obtain ordered lists of trust verifiers (see Sec-
tion 3.2) and socket factories (see Section 4.6). The general algorithm used to
obtain instances from providers is the same in both cases, and is based on a prop-
erty name prefix (prefix) and an interface (iface). For trust verifiers, the prefix is
“rmi.verifier” and the interface is TrustVerifier (see Section 5.1). For socket
factories, the prefix is “rmi.socket” and the interface is
SecureServerSocketFactory (see Section 5.2).
If there is a security property (as defined by the getProperty method of
java.security.Security) named “prefix.1”, then for each security property
named “prefix.n” (for sequential values of n starting from 1), if:

◆ the property value is of the form “name.type” such that the getProvider
method of java.security.Security returns a provider for name, and
◆ that provider has a property named “prefix.type”, and
◆ the value of that property is the name of a class that implements iface and
has a no-arg constructor, and
◆ no instance of that class already exists in the list,

then an instance of that class is created and added to the list. In this case, the order
of instances is given by the security property order.
If there is no security property named “prefix.1”, then each of the providers
returned by the getProviders method of java.security.Security is searched,
and for each property that a provider has with name prefixed by “prefix.”, if:

◆ the property value is the name of a class that implements iface and has a no-
arg constructor, and
◆ no instance of that class already exists in the list,

EARLY LOOK DRAFT 2


44 PROVIDER INTERFACES

then an instance of that class is created and added to the list. In this case, the order
of instances generated from a given provider is unspecified, but instances from
earlier providers precede instances from later providers in the resulting list.

5.1 TrustVerifier

TrustVerifier is defined as:


package javax.rmi.security.spi;
public interface TrustVerifier {
boolean trustedConstraintClass(Class c);
boolean trustedPrincipalClass(Class c);
boolean trustedClientSocketFactoryClass(Class c);
boolean trustedProxy(Object proxy,
SecurityConstraints constraints)
throws RemoteException;
}

The trustedConstraintClass method returns true if the given class is


known to be a trusted SecurityConstraint class, and false otherwise. This
method does not need to return true for the standard constraint classes defined in
Section 2.
The trustedPrincipalClass method returns true if the given class is
known to be a trusted Principal class for use in security constraints, and false
otherwise.
The trustedClientFactoryClass method returns true if the given class is
known to be a trusted SecureClientSocketFactory class, and false otherwise.
The trustedProxy method returns true if the given proxy is known to be
trusted to correctly implement the RemoteSecurity interface, and false other-
wise.

5.2 SecureServerSocketFactory

SecureServerSocketFactory is defined as:


package javax.rmi.security.spi;
public interface SecureServerSocketFactory {
SecureClientSocketFactory getClientFactory(int port);
boolean supportsConstraints(
SecurityConstraints constraints,

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 45

Subject serverSubject);
ServerSocket createServerSocket(Subject serverSubject,
int port)
throws IOException;
}

The getClientFactory method returns a SecureClientSocketFactory


that is compatible with a ServerSocket created by this
SecureServerSocketFactory for the specified port.
The supportsConstraints method returns true if the factory can support
the specified server constraints (any contained preferences are ignored) when cou-
pled with the specified server subject, and returns false otherwise.
The createServerSocket method returns a new ServerSocket that is lis-
tening on the specified port (or an anonymous port if the specified port is zero)
and that will authenticate as appropriate using the specified serverSubject.
Sockets created by the accept method of this ServerSocket must implement the
SecureSocket interface.
The equals method returns true if the parameter is a functionally equivalent
SecureServerSocketFactory instance.

5.3 SecureSocket

SecureSocket is defined as:


package javax.rmi.security.spi;
public interface SecureSocket {
SecurityConstraints getSecurityConstraints();
Subject getClientSubject();
}

The getSecurityConstraints method returns the constraints actually in use


on the socket. A non-null read-only instance is returned that has only require-
ments, no preferences, and no relative-time constraints.
The getClientSubject method returns the authenticated identity of the cli-
ent, or null if the client has not been authenticated.

EARLY LOOK DRAFT 2


46 PROVIDER INTERFACES

5.4 SecureClientSocketFactory

SecureClientSocketFactory is defined as:


package javax.rmi.security.spi;
public interface SecureClientSocketFactory {
SecurityConstraints choosePreferences(
SecurityConstraints constraints,
Subject clientSubject)
throws IOException;
Socket createSocket(SecurityConstraints constraints,
Subject clientSubject)
throws IOException;
void checkConnect();
}

Classes that implement this interface should be serializable.


The equals method returns true if the parameter is a functionally equivalent
SecureClientSocketFactory instance. All instances returned by repeated calls
to the getClientFactory method of a SecureServerSocketFactory with the
same port, and all serialized copies of them, must be equal.
The choosePreferences method chooses the “best” preferences (if any) that
can be supported by the factory while simultaneously supporting all of the speci-
fied requirements, given the specified client subject. It also chooses the “best”
constraints among any alternatives contained in instances of
AlternativeSecurityConstraints. The meaning of “best” is implementation
dependent. This method can assume that none of the constraints are based on rela-
tive time. The returned constraints must: imply all of the requirements from the
parameter passed in; include whatever additional requirements are selected to sat-
isfy the chosen preferences; and have no preferences and no instances of
AlternativeSecurityConstraints. If not all of the requirements can be sup-
ported in conjunction with the specified client subject, then null is returned.
The createSocket method returns a socket that will satisfy the specified
security requirements (any preferences can be ignored), authenticating as neces-
sary as the appropriate subset of the specified client subject. This method can
assume that none of the constraints are based on relative time. If not all of the
requirements can be supported, UnsupportedSecurityException is thrown.
If the socket returned by createSocket supports reuse with different con-
straints it should implement the SecureSessionSocket interface.
The checkConnect method throws SecurityException if the calling thread
does not have permission to call createSocket. In the usual case, this method

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 47

calls the checkConnect method of the installed security manager, passing the host
and port that would be used to create the socket.

5.5 SecureSessionSocket

SecureSessionSocket is defined as:


package javax.rmi.security.spi;
public interface SecureSessionSocket {
boolean supportsConstraints(
SecurityConstraints constraints,
Subject clientSubject);
void switchConstraints(SecurityConstraints constraints,
Subject clientSubject)
throws IOException;
}

The supportsConstraints method returns true if the socket supports


switching to the specified constraints (any contained preferences are ignored) cou-
pled with the specified client subject, and returns false otherwise.
The switchConstraints method causes the socket to actually switch to the
specified constraints (any contained preferences are ignored) and client subject. If
not all of the requirements can be supported, UnsupportedSecurityException
is thrown.

EARLY LOOK DRAFT 2


48 PROVIDER INTERFACES

EARLY LOOK DRAFT 2


JAVA™ RMI SECURITY EXTENSION 49

6 Serialization

The InvocationHandler classes used in secure RMI stubs are implementation


specific. The class used for a server exported as a SecureUnicastRemoteObject
must have a writeReplace method that returns an instance of
SecureUnicastData:

package javax.rmi.security.ref;
public class SecureUnicastData implements Serializable {
public SecurityConstraints clientConstraints;
public SecurityConstraints defaultConstraints;
public long[] methodHashes;
public SecurityConstraints[] methodConstraints;
public SecureClientSocketFactory[] factories;
public ObjID id;
}

The implementation of SecureUnicastData must have a readResolve method


that returns an equivalent instance of the same InvocationHandler class.
Similarly, the class used for a server exported as a SecureActivatable must
have a writeReplace method that returns an instance of
SecureActivatableData:

package javax.rmi.security.ref;
public class SecureActivatableData extends SecureUnicastData {
public ActivationID aid;
}

The implementation of SecureActivatableData must have a readResolve


method that returns an equivalent instance of the same InvocationHandler class.
The fields of SecureUnicastData and SecureActivatableData hold the
following data:

◆ clientConstraints - the client constraints as would be returned by the


RemoteSecurity getClientConstraints method on the proxy

EARLY LOOK DRAFT 2


50 SERIALIZATION

◆ defaultConstraints - the default server constraints specified in the


SecureExportDesc when the object was exported
◆ methodHashes - RMI method hashes for all of the methods specified in
MethodConstraints in the SecureExportDesc when the object was
exported, in arbitrary order
◆ methodConstraints - the constraints specified in the MethodConstraints
for the corresponding index of methodHashes
◆ factories - the ordered list of client socket factories obtained from the
server socket factories specified in the SecureExportDesc when the object
was exported
◆ id - the identifier for the server
◆ aid - the activation identifier for the server

For SecureUnicastData instances, the factories and id fields must be non-


null. For SecureActivatableData instances, the aid field must be non-null.

EARLY LOOK DRAFT 2

Das könnte Ihnen auch gefallen