net.jini.jeri.kerberos
Class KerberosServerEndpoint

java.lang.Object
  extended by net.jini.jeri.kerberos.KerberosServerEndpoint
All Implemented Interfaces:
ServerCapabilities, ServerEndpoint

public final class KerberosServerEndpoint
extends Object
implements ServerEndpoint

A ServerEndpoint implementation that uses Kerberos as the underlying network security protocol to support security related invocation constraints for remote requests. Instances of this class are referred to as the server endpoints of the Kerberos provider, while instances of KerberosEndpoint are referred to as the endpoints of the provider.

Instances of this class are intended to be created for use with the BasicJeriExporter class. Calls to enumerateListenEndpoints return instances of KerberosEndpoint.

This class supports at least the following standard constraints:

To get an instance of KerberosServerEndpoint, one of the getInstance methods of the class has to be invoked. The returned server endpoint instance encapsulates a set of properties that it will later use to receive and dispatch inbound requests. The following describes how some of these properties are chosen:

This class permits specifying a SocketFactory for creating the Socket instances that the associated KerberosEndpoint instances use to make remote connections back to the server, and a ServerSocketFactory for creating the ServerSocket instances that the server endpoint uses to accept remote connections.

A SocketFactory used with instances of this class should be serializable, and should implement Object.equals to return true when passed an instance that represents the same (functionally equivalent) socket factory. A ServerSocketFactory used with instances of this class should implement Object.equals to return true when passed an instance that represents the same (functionally equivalent) server socket factory.

This class uses the Jini extensible remote invocation (Jini ERI) multiplexing protocol to map outgoing requests to the underlying secure connection streams.

The secure connection streams in this provider are implemented using the Kerberos Version 5 GSS-API Mechanism, defined in RFC 1964, over socket connections between client and server endpoints.

Note that, because Kerberos inherently requires client authentication, this transport provider does not support distributed garbage collection (DGC); if DGC is enabled using BasicJeriExporter, all DGC remote calls through this provider will silently fail.

Since:
2.0
Author:
Sun Microsystems, Inc.
See Also:
KerberosEndpoint, KerberosTrustVerifier
Implementation Specifics:
This class uses the following Logger to log information at the following logging levels:

net.jini.jeri.kerberos.server
Level Description
WARNING unexpected failure while accepting connections on the created ServerSocket.
FAILED problems with permission checking, server principal and Kerberos key presence checking, GSSCredential creation, socket connect acception, GSSContext establishment, credential expiration, or wrap/unwrap GSS tokens
HANDLED failure to set TCP no delay or keep alive properties on sockets
FINE server endpoint creation, checkConstraints results, server socket creation, socket connect acceptance, server connection creation/destruction, GSSContext establishment
FINEST data message encoding/decoding using GSSContext

When the ListenEndpoint.listen method of this implementation is invoked, a search is conducted on the private credentials of the serverSubject, the first valid KerberosKey whose principal equals to the serverPrincipal is chosen as the server credential for the listen operation. The presence of this server credential in the serverSubject as well as its validity are checked both when a new incoming connection is received and a new request arrives on an established connection; if the checks fail, the listen operation or the connection will be aborted permanently.

This implementation uses the standard Java(TM) GSS-API. Additionally, for each inbound connection established, it invokes GSSUtil.createSubject to construct a Subject instance, which encapsulates the principal and delegated credential, if any, of the corresponding remote caller.


Nested Class Summary
 
Nested classes/interfaces inherited from interface net.jini.jeri.ServerEndpoint
ServerEndpoint.ListenContext, ServerEndpoint.ListenCookie, ServerEndpoint.ListenEndpoint, ServerEndpoint.ListenHandle
 
Method Summary
 InvocationConstraints checkConstraints(InvocationConstraints constraints)
          Verifies that this instance supports the transport layer aspects of all of the specified requirements (both in general and in the current security context), and returns the requirements that must be at least partially implemented by higher layers in order to fully satisfy all of the specified requirements.
 Endpoint enumerateListenEndpoints(ServerEndpoint.ListenContext listenContext)
          Passes the ListenEndpoint for this KerberosServerEndpoint to listenContext, which will ensure an active listen operation on the endpoint, and returns a KerberosEndpoint instance corresponding to the listen operation chosen by listenContext.
 boolean equals(Object obj)
          Two instances of this class are equal if they have server subjects that compare equal using ==; have the same server principal; have the same values for server host and port; have socket factories that are either both null, or have the same actual class and are equal; and have server socket factories that are either both null, or have the same actual class and are equal.
 String getHost()
          Returns the host name that will be used in KerberosEndpoint instances created by listening on this object.
static KerberosServerEndpoint getInstance(int port)
          Returns a KerberosServerEndpoint instance with the specified port, using the default server subject, server principal, and server host.
static KerberosServerEndpoint getInstance(String serverHost, int port)
          Returns a KerberosServerEndpoint instance with the specified server host and port, using the default server subject and server principal.
static KerberosServerEndpoint getInstance(String serverHost, int port, SocketFactory csf, ServerSocketFactory ssf)
          Returns a KerberosServerEndpoint instance with the specified server host, port, and socket factories, using the default server subject and server principal.
static KerberosServerEndpoint getInstance(Subject serverSubject, KerberosPrincipal serverPrincipal, String serverHost, int port)
          Returns a KerberosServerEndpoint instance with the specified server subject, server principal, server host, and port.
static KerberosServerEndpoint getInstance(Subject serverSubject, KerberosPrincipal serverPrincipal, String serverHost, int port, SocketFactory csf, ServerSocketFactory ssf)
          Returns a KerberosServerEndpoint instance with the specified server subject, server principal, server host, port, and socket factories.
 int getPort()
          Returns the TCP port that the ListenEndpoints created by this server endpoint listen on.
 KerberosPrincipal getPrincipal()
          Returns the principal that this server endpoint will authenticate itself as.
 ServerSocketFactory getServerSocketFactory()
          Returns the server socket factory that this server endpoint uses to create ServerSocket instances, or null if it uses default server sockets.
 SocketFactory getSocketFactory()
          Returns the socket factory that the associated KerberosEndpoint instances, which are created by listening on the ListenEndpoint instances of this server endpoint, use to create Socket instances, or null if they use default sockets.
 int hashCode()
          Returns a hash code value for this object.
 String toString()
          Returns a string representation of this object.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Method Detail

getInstance

public static KerberosServerEndpoint getInstance(int port)
                                          throws UnsupportedConstraintException
Returns a KerberosServerEndpoint instance with the specified port, using the default server subject, server principal, and server host.

Parameters:
port - the port this server endpoint will listen on, 0 to use any free port
Returns:
a KerberosServerEndpoint instance
Throws:
UnsupportedConstraintException - if the caller has not been granted the right AuthenticationPermission, or there is no default server subject (serverSubject.getSubject(AccessController.getContext()) returns null), or no appropriate Kerberos principal and corresponding Kerberos key can be found in the server subject
SecurityException - if there is a security manager and the following condition is true:
  • The caller has been granted AuthPermission("getSubject") , but no listen AuthenticationPermission whose local principal is a principal in the server subject's principal set, which is required for accessing any private credentials corresponding to the principal in the server subject.
IllegalArgumentException - if serverPort is not in the range of 0 to 65535

getInstance

public static KerberosServerEndpoint getInstance(String serverHost,
                                                 int port)
                                          throws UnsupportedConstraintException
Returns a KerberosServerEndpoint instance with the specified server host and port, using the default server subject and server principal.

Parameters:
serverHost - the name or IP address of the server host the KerberosEndpoint instances created by this server endpoint will connect to. If null, the default server host will be used.
port - the port this server endpoint will listen on, 0 to use any free port
Returns:
a KerberosServerEndpoint instance
Throws:
UnsupportedConstraintException - if the caller has not been granted the right AuthenticationPermission, or there is no default server subject (serverSubject.getSubject(AccessController.getContext()) returns null), or no appropriate Kerberos principal and corresponding Kerberos key can be found in the server subject
SecurityException - if there is a security manager and the following condition is true:
  • The caller has been granted AuthPermission("getSubject") , but no listen AuthenticationPermission whose local principal is a principal in the server subject's principal set, which is required for accessing any private credentials corresponding to the principal in the server subject.
IllegalArgumentException - if serverPort is not in the range of 0 to 65535

getInstance

public static KerberosServerEndpoint getInstance(String serverHost,
                                                 int port,
                                                 SocketFactory csf,
                                                 ServerSocketFactory ssf)
                                          throws UnsupportedConstraintException
Returns a KerberosServerEndpoint instance with the specified server host, port, and socket factories, using the default server subject and server principal.

Parameters:
serverHost - the name or IP address of the server host the KerberosEndpoint instances created by this server endpoint will connect to. If null, the default server host will be used.
port - the port this server endpoint will listen on, 0 to use any free port
csf - the SocketFactory to be used by the KerberosEndpoint created by this server endpoint to create sockets, or null to let the KerberosEndpoint create Sockets directly.
ssf - the ServerSocketFactory to use for this KerberosServerEndpoint, or null to let the KerberosServerEndpoint create ServerSockets directly.
Returns:
a KerberosServerEndpoint instance
Throws:
UnsupportedConstraintException - if the caller has not been granted the right AuthenticationPermission, or there is no default server subject (serverSubject.getSubject(AccessController.getContext()) returns null), or no appropriate Kerberos principal and corresponding Kerberos key can be found in the server subject
SecurityException - if there is a security manager and the following condition is true:
  • The caller has been granted AuthPermission("getSubject") , but no listen AuthenticationPermission whose local principal is a principal in the server subject's principal set, which is required for accessing any private credentials corresponding to the principal in the server subject.
IllegalArgumentException - if serverPort is not in the range of 0 to 65535

getInstance

public static KerberosServerEndpoint getInstance(Subject serverSubject,
                                                 KerberosPrincipal serverPrincipal,
                                                 String serverHost,
                                                 int port)
                                          throws UnsupportedConstraintException
Returns a KerberosServerEndpoint instance with the specified server subject, server principal, server host, and port.

Parameters:
serverSubject - the server subject to use for authenticating the server. If null, the subject associated with the current access control context will be used.
serverPrincipal - the principal server should authenticate as. If null, then the default server principal will be used.
serverHost - the name or IP address of the server host the KerberosEndpoint instances created by this server endpoint will connect to. If null, the default server host will be used.
port - the port this server endpoint will listen on, 0 to use any free port
Returns:
a KerberosServerEndpoint instance
Throws:
UnsupportedConstraintException - if the caller has not been granted the right AuthenticationPermission, or there is no default server subject (serverSubject.getSubject(AccessController.getContext()) returns null), or no appropriate Kerberos principal and corresponding Kerberos key can be found in the server subject
SecurityException - if there is a security manager and the following condition is true:
  • The passed in serverPrincipal is null, the caller has the AuthPermission("getSubject") , but no listen AuthenticationPermission whose local principal is a principal in the server subject's principal set, which is required for accessing any private credentials corresponding to the principal in the server subject.
IllegalArgumentException - if serverPort is not in the range of 0 to 65535

getInstance

public static KerberosServerEndpoint getInstance(Subject serverSubject,
                                                 KerberosPrincipal serverPrincipal,
                                                 String serverHost,
                                                 int port,
                                                 SocketFactory csf,
                                                 ServerSocketFactory ssf)
                                          throws UnsupportedConstraintException
Returns a KerberosServerEndpoint instance with the specified server subject, server principal, server host, port, and socket factories.

Parameters:
serverSubject - the server subject to use for authenticating the server. If null, the subject associated with the current access control context will be used.
serverPrincipal - the principal server should authenticate as. If null, then the default server principal will be used.
serverHost - the name or IP address of the server host the KerberosEndpoint instances created by this server endpoint will connect to. If null, the default server host will be used.
port - the port this server endpoint will listen on, 0 to use any free port
csf - the SocketFactory to be used by the KerberosEndpoint created by this server endpoint to create sockets, or null to let the KerberosEndpoint create Sockets directly.
ssf - the ServerSocketFactory to use for this KerberosServerEndpoint, or null to let the KerberosServerEndpoint create ServerSockets directly.
Returns:
a KerberosServerEndpoint instance
Throws:
UnsupportedConstraintException - if the caller has not been granted the right AuthenticationPermission, or there is no default server subject (serverSubject.getSubject(AccessController.getContext()) returns null), or no appropriate Kerberos principal and corresponding Kerberos key can be found in the server subject
SecurityException - if there is a security manager and the following condition is true:
  • The passed in serverPrincipal is null, the caller has the AuthPermission("getSubject") , but no listen AuthenticationPermission whose local principal is a principal in the server subject's principal set, which is required for accessing any private credentials corresponding to the principal in the server subject.
IllegalArgumentException - if serverPort is not in the range of 0 to 65535

getHost

public String getHost()
Returns the host name that will be used in KerberosEndpoint instances created by listening on this object.

Returns:
the host name to use in KerberosEndpoint instances created by listening on this object

getPort

public int getPort()
Returns the TCP port that the ListenEndpoints created by this server endpoint listen on.

Returns:
the TCP port that the endpoints listen on

getPrincipal

public KerberosPrincipal getPrincipal()
Returns the principal that this server endpoint will authenticate itself as.

Returns:
the principal that this server endpoint will authenticate as

getSocketFactory

public SocketFactory getSocketFactory()
Returns the socket factory that the associated KerberosEndpoint instances, which are created by listening on the ListenEndpoint instances of this server endpoint, use to create Socket instances, or null if they use default sockets.

Returns:
the socket factory that associated endpoints use to create sockets, or null if they use default sockets

getServerSocketFactory

public ServerSocketFactory getServerSocketFactory()
Returns the server socket factory that this server endpoint uses to create ServerSocket instances, or null if it uses default server sockets.

Returns:
the server socket factory that this server endpoint uses to create server sockets, or null if it uses default server sockets

checkConstraints

public InvocationConstraints checkConstraints(InvocationConstraints constraints)
                                       throws UnsupportedConstraintException
Description copied from interface: ServerCapabilities
Verifies that this instance supports the transport layer aspects of all of the specified requirements (both in general and in the current security context), and returns the requirements that must be at least partially implemented by higher layers in order to fully satisfy all of the specified requirements. This method may also return preferences that must be at least partially implemented by higher layers in order to fully satisfy some of the specified preferences.

For any given constraint, there must be a clear delineation of which aspects (if any) must be implemented by the transport layer. This method must not return a constraint (as a requirement or a preference, directly or as an element of another constraint) unless this instance can implement all of those aspects. Also, this method must not return a constraint for which all aspects must be implemented by the transport layer. Most of the constraints in the net.jini.core.constraint package must be fully implemented by the transport layer and thus must not be returned by this method; the one exception is Integrity, for which the transport layer is responsible for the data integrity aspect and higher layers are responsible for the code integrity aspect.

For any ConstraintAlternatives in the specified constraints, this method should only return a corresponding constraint if all of the alternatives supported by this instance need to be at least partially implemented by higher layers in order to be fully satisfied.

The constraints passed to this method may include constraints based on relative time.

Specified by:
checkConstraints in interface ServerCapabilities
Parameters:
constraints - the constraints that must be supported
Returns:
the constraints that must be at least partially implemented by higher layers
Throws:
UnsupportedConstraintException - if the transport layer aspects of any of the specified requirements are not supported by this instance (either in general or in the current security context)

enumerateListenEndpoints

public Endpoint enumerateListenEndpoints(ServerEndpoint.ListenContext listenContext)
                                  throws IOException
Passes the ListenEndpoint for this KerberosServerEndpoint to listenContext, which will ensure an active listen operation on the endpoint, and returns a KerberosEndpoint instance corresponding to the listen operation chosen by listenContext.

If this server endpoint's server host is null, then the endpoint returned will contain the default server host. This method computes the default by invoking InetAddress.getLocalHost to obtain an InetAddress for the local host. If InetAddress.getLocalHost throws an UnknownHostException, this method throws an UnknownHostException. The default host name will be the string returned by invoking getHostAddress on the obtained InetAddress. If there is a security manager, its checkConnect method will be invoked with the string returned by invoking getHostName on that same InetAddress as the host argument and -1 as the port argument; this could result in a SecurityException.

This method invokes addListenEndpoint on listenContext once, passing a ListenEndpoint as described below. If addListenEndpoint throws an exception, then this method throws that exception. Otherwise, this method returns a KerberosEndpoint instance with the host name described above, the TCP port number bound by the listen operation represented by the ListenHandle returned by addListenEndpoint, and the same server principal and SocketFactory as this KerberosServerEndpoint.

The ListenEndpoint passed to addListenEndpoint represents the server subject, server principal, TCP port number, and ServerSocketFactory of this KerberosServerEndpoint. Its methods behave as follows:

ListenHandle listen(RequestDispatcher):

Listens for requests received on this endpoint's TCP port, dispatching them to the supplied RequestDispatcher in the form of InboundRequest instances.

When the implementation of this method needs to create a new ServerSocket, it will do so by invoking one of the createServerSocket methods that returns a bound server socket on the contained ServerSocketFactory if non-null, or it will create a ServerSocket directly otherwise.

If there is a security manager, its checkListen method will be invoked with this endpoint's TCP port; this could result in a SecurityException. In addition, the security manager's checkPermission method will be invoked with an AuthenticationPermission containing the server principal of this endpoint and the listen action; this could also result in a SecurityException. Furthermore, before a given InboundRequest gets dispatched to the supplied request dispatcher, the security manager's checkAccept method must have been successfully invoked in the security context of this listen invocation with the remote IP address and port of the Socket used to receive the request, and the security manager's checkPermission method must have been successfully invoked in the same context with an AuthenticationPermission containing the server principal of this endpoint as local principal, the client's authenticated principal as peer principal, and the accept action. The checkPermissions method of the dispatched InboundRequest also performs these latter security checks. (Note that in some cases, the implementation may carry out some of these security checks indirectly, such as through invocations of ServerSocket's constructors or accept method.)

Once a ListenEndpoint of this provider starts to listen, each time a new inbound request comes in, it verifies that the serverSubject of the corresponding server endpoint still holds a valid KerberosKey corresponding to its serverPrincipal. It rejects the request if the verification fails. This guarantees that as soon as the KerberosKey for the principal in the Subject is destroyed (logout) or expired, no more new requests will be accepted.

Requests will be dispatched in a PrivilegedAction wrapped by a SecurityContext obtained when this method was invoked, with the AccessControlContext of that SecurityContext in effect.

Dispatched requests will implement populateContext to populate the given collection with an element that implements the ClientHost interface, and an element that implements the ClientSubject interface. The ClientHost element implements getClientHost to return the IP address of the Socket that the request was received over (see Socket.getInetAddress()).

Throws IOException if an I/O exception occurs while performing this operation, such as if the TCP port is already in use.

Throws SecurityException if there is a security manager and an invocation of its checkListen or checkPermission method fails.

Throws NullPointerException if requestDispatcher is null

void checkPermissions():
Verifies that the current security context has all of the security permissions necessary to listen for requests on this endpoint.

If there is a security manager, its checkListen method will be invoked with this endpoint's TCP port; this could result in a SecurityException. In addition, the security manager's checkPermission method will be invoked with an AuthenticationPermission containing the server principal of this endpoint and the listen action; this could also result in a SecurityException.

Throws SecurityException if there is a security manager and an invocation of its checkListen or checkPermission method fails.

boolean equals(Object):
Compares the specified object with this ListenEndpoint for equality.

This method returns true if and only if the specified object is also a ListenEndpoint produced by a KerberosServerEndpoint, and the two listen endpoints both have server subjects that compare equal using ==; have the same server principal; have the same values for TCP port; and have server socket factories that are either both null, or have the same actual class and are equal.

Specified by:
enumerateListenEndpoints in interface ServerEndpoint
Parameters:
listenContext - the ListenContext to pass this ServerEndpoint's ListenEndpoint instances to
Returns:
the Endpoint instance for sending requests to this ServerEndpoint's communication endpoints being listened on
Throws:
SecurityException - if there is a security manager, and either its checkListen method fails, or serverHost is null and the security manager's checkConnect method fails; or if the calling thread does not have permission to authenticate as the endpoint's server principal when listening for connections
IllegalArgumentException - if an invocation of the addListenEndpoint method on the supplied ListenContext returns a ListenCookie that does not correspond to the ListenEndpoint that was passed to it
NullPointerException - if listenContext is null
UnknownHostException - if this instance's server host is null and InetAddress.getLocalHost throws an UnknownHostException
UnsupportedConstraintException - if the server subject is missing any of the endpoint's server principals or the associated credentials
IOException - if an I/O exception occurs while attempting to listen for requests on the communication endpoints represented by this ServerEndpoint. This could occur, for example, if an I/O resource associated with one of the communication endpoints is already in exclusive use, or if there are insufficient I/O resources for the operation.

hashCode

public int hashCode()
Returns a hash code value for this object.

Overrides:
hashCode in class Object

equals

public boolean equals(Object obj)
Two instances of this class are equal if they have server subjects that compare equal using ==; have the same server principal; have the same values for server host and port; have socket factories that are either both null, or have the same actual class and are equal; and have server socket factories that are either both null, or have the same actual class and are equal.

Overrides:
equals in class Object

toString

public String toString()
Returns a string representation of this object.

Overrides:
toString in class Object


Copyright 2007, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.