/* * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package org.ietf.jgss; import java.security.Provider; /** * This class serves as a factory for other important * GSS-API classes and also provides information about the mechanisms that * are supported. It can create instances of classes * implementing the following three GSS-API interfaces: {@link * GSSName GSSName}, {@link GSSCredential GSSCredential}, and {@link * GSSContext GSSContext}. It also has methods to query for the list * of available mechanisms and the nametypes that each mechanism * supports.
*
* An instance of the default GSSManager
subclass
* may be obtained through the static method {@link #getInstance()
* getInstance}, but applications are free to instantiate other subclasses
* of GSSManager
. The default GSSManager
instance
* will support the Kerberos v5 GSS-API mechanism in addition to any
* others. This mechanism is identified by the Oid "1.2.840.113554.1.2.2"
* and is defined in RFC 1964.
*
* A subclass extending the GSSManager
abstract class may be
* implemented as a modular provider based layer that utilizes some well
* known service provider specification. The GSSManager
API
* allows the application to set provider preferences on
* such an implementation. These methods also allow the implementation to
* throw a well-defined exception in case provider based configuration is
* not supported. Applications that expect to be portable should be aware
* of this and recover cleanly by catching the exception.
* * It is envisioned that there will be three most common ways in which * providers will be used:
*
*
* The GSSManager
class has two methods that enable these modes of
* usage: {@link #addProviderAtFront(Provider, Oid) addProviderAtFront} and
* {@link #addProviderAtEnd(Provider, Oid) addProviderAtEnd}. These methods
* have the effect of creating an ordered list of <provider,
* oid> pairs where each pair indicates a preference of provider
* for a given oid.
*
* It is important to note that there are certain interactions
* between the different GSS-API objects that are created by a
* GSSManager, where the provider that is used for a particular mechanism
* might need to be consistent across all objects. For instance, if a
* GSSCredential contains elements from a provider p for a mechanism
* m, it should generally be passed in to a GSSContext that will use
* provider p for the mechanism m. A simple rule of thumb
* that will maximize portability is that objects created from different
* GSSManager's should not be mixed, and if possible, a different
* GSSManager instance should be created if the application wants to invoke
* the addProviderAtFront
method on a GSSManager that has
* already created an object.
* * Here is some sample code showing how the GSSManager might be used:
*
* GSSManager manager = GSSManager.getInstance(); * * Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2"); * Oid krb5PrincipalNameType = new Oid("1.2.840.113554.1.2.2.1"); * * // Identify who the client wishes to be * GSSName userName = manager.createName("duke", GSSName.NT_USER_NAME); * * // Identify the name of the server. This uses a Kerberos specific * // name format. * GSSName serverName = manager.createName("nfs/foo.sun.com", * krb5PrincipalNameType); * * // Acquire credentials for the user * GSSCredential userCreds = manager.createCredential(userName, * GSSCredential.DEFAULT_LIFETIME, * krb5Mechanism, * GSSCredential.INITIATE_ONLY); * * // Instantiate and initialize a security context that will be * // established with the server * GSSContext context = manager.createContext(serverName, * krb5Mechanism, * userCreds, * GSSContext.DEFAULT_LIFETIME); *
* * The server side might use the following variation of this source:
* *
* // Acquire credentials for the server * GSSCredential serverCreds = manager.createCredential(serverName, * GSSCredential.DEFAULT_LIFETIME, * krb5Mechanism, * GSSCredential.ACCEPT_ONLY); * * // Instantiate and initialize a security context that will * // wait for an establishment request token from the client * GSSContext context = manager.createContext(serverCreds); ** * @author Mayank Upadhyay * @see GSSName * @see GSSCredential * @see GSSContext * @since 1.4 */ public abstract class GSSManager { /** * Returns the default GSSManager implementation. * * @return a GSSManager implementation */ public static GSSManager getInstance() { return new sun.security.jgss.GSSManagerImpl(); } /** * Returns a list of mechanisms that are available to GSS-API callers * through this GSSManager. The default GSSManager obtained from the * {@link #getInstance() getInstance()} method includes the Oid * "1.2.840.113554.1.2.2" in its list. This Oid identifies the Kerberos * v5 GSS-API mechanism that is defined in RFC 1964. * * @return an array of Oid objects corresponding to the mechanisms that * are available. A
null
value is returned when no
* mechanism are available (an example of this would be when mechanism
* are dynamically configured, and currently no mechanisms are
* installed).
*/
public abstract Oid[] getMechs();
/**
* Returns then name types supported by the indicated mechanism.* * The default GSSManager instance includes support for the Kerberos v5 * mechanism. When this mechanism ("1.2.840.113554.1.2.2") is indicated, * the returned list will contain at least the following nametypes: * {@link GSSName#NT_HOSTBASED_SERVICE GSSName.NT_HOSTBASED_SERVICE}, * {@link GSSName#NT_EXPORT_NAME GSSName.NT_EXPORT_NAME}, and the * Kerberos v5 specific Oid "1.2.840.113554.1.2.2.1". The namespace for * the Oid "1.2.840.113554.1.2.2.1" is defined in RFC 1964. * * @return an array of Oid objects corresponding to the name types that * the mechanism supports. * @param mech the Oid of the mechanism to query * * @see #getMechsForName(Oid) * * @throws GSSException containing the following * major error codes: * {@link GSSException#BAD_MECH GSSException.BAD_MECH} * {@link GSSException#FAILURE GSSException.FAILURE} */ public abstract Oid[] getNamesForMech(Oid mech) throws GSSException; /** * Returns a list of mechanisms that support the indicated name type.
*
* The Kerberos v5 mechanism ("1.2.840.113554.1.2.2") will always be
* returned in this list when the indicated nametype is one of
* {@link GSSName#NT_HOSTBASED_SERVICE GSSName.NT_HOSTBASED_SERVICE},
* {@link GSSName#NT_EXPORT_NAME GSSName.NT_EXPORT_NAME}, or
* "1.2.840.113554.1.2.2.1".
*
* @return an array of Oid objects corresponding to the mechanisms that
* support the specified name type. null
is returned when no
* mechanisms are found to support the specified name type.
* @param nameType the Oid of the name type to look for
*
* @see #getNamesForMech(Oid)
*/
public abstract Oid[] getMechsForName(Oid nameType);
/**
* Factory method to convert a string name from the
* specified namespace to a GSSName object. In general, the
* GSSName
object created will contain multiple
* representations of the name, one for each mechanism that is
* supported; two examples that are exceptions to this are when
* the namespace type parameter indicates NT_EXPORT_NAME or when the
* GSS-API implementation is not multi-mechanism. It is
* not recommended to use this method with a NT_EXPORT_NAME type because
* representing a previously exported name consisting of abitrary bytes
* as a String might cause problems with character encoding schemes. In
* such cases it is recommended that the bytes be passed in directly to
* the overloaded form of this method {@link #createName(byte[],
* Oid) createName}.
*
* @param nameStr the string representing a printable form of the name to
* create.
* @param nameType the Oid specifying the namespace of the printable name
* supplied. null
can be used to specify
* that a mechanism specific default printable syntax should
* be assumed by each mechanism that examines nameStr.
* It is not advisable to use the nametype NT_EXPORT_NAME with this
* method.
* @return a GSSName representing the indicated principal
*
* @see GSSName
* @see GSSName#NT_EXPORT_NAME
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},
* {@link GSSException#BAD_NAME GSSException.BAD_NAME},
* {@link GSSException#BAD_MECH GSSException.BAD_MECH},
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSName createName(String nameStr, Oid nameType)
throws GSSException;
/**
* Factory method to convert a byte array containing a
* name from the specified namespace to a GSSName object. In general,
* the GSSName
object created will contain multiple
* representations of the name, one for each mechanism that is
* supported; two examples that are exceptions to this are when the
* namespace type parameter indicates NT_EXPORT_NAME or when the
* GSS-API implementation is not multi-mechanism. The bytes that are
* passed in are interpreted by each underlying mechanism according to
* some encoding scheme of its choice for the given nametype.
*
* @param name the byte array containing the name to create
* @param nameType the Oid specifying the namespace of the name supplied
* in the byte array. null
can be used to specify that a
* mechanism specific default syntax should be assumed by each mechanism
* that examines the byte array.
* @return a GSSName representing the indicated principal
*
* @see GSSName
* @see GSSName#NT_EXPORT_NAME
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},
* {@link GSSException#BAD_NAME GSSException.BAD_NAME},
* {@link GSSException#BAD_MECH GSSException.BAD_MECH},
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSName createName(byte name[], Oid nameType)
throws GSSException;
/**
* Factory method to convert a string name from the
* specified namespace to a GSSName object and canonicalize it at the
* same time for a mechanism. In other words, this method is
* a utility that does the equivalent of two steps: the {@link
* #createName(String, Oid) createName} and then also the {@link
* GSSName#canonicalize(Oid) GSSName.canonicalize}.
*
* @param nameStr the string representing a printable form of the name to
* create.
* @param nameType the Oid specifying the namespace of the printable name
* supplied. null
can be used to specify
* that a mechanism specific default printable syntax should
* be assumed by each mechanism that examines nameStr.
* It is not advisable to use the nametype NT_EXPORT_NAME with this
* method.
* @param mech Oid specifying the mechanism for which the name should be
* canonicalized
* @return a GSSName representing the indicated principal
*
* @see GSSName#canonicalize(Oid)
* @see GSSName#NT_EXPORT_NAME
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},
* {@link GSSException#BAD_NAME GSSException.BAD_NAME},
* {@link GSSException#BAD_MECH GSSException.BAD_MECH},
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSName createName(String nameStr, Oid nameType,
Oid mech) throws GSSException;
/**
* Factory method to convert a byte array containing a
* name from the specified namespace to a GSSName object and canonicalize
* it at the same time for a mechanism. In other words, this method is a
* utility that does the equivalent of two steps: the {@link
* #createName(byte[], Oid) createName} and then also {@link
* GSSName#canonicalize(Oid) GSSName.canonicalize}.
*
* @param name the byte array containing the name to create
* @param nameType the Oid specifying the namespace of the name supplied
* in the byte array. null
can be used to specify that a
* mechanism specific default syntax should be assumed by each mechanism
* that examines the byte array.
* @param mech Oid specifying the mechanism for which the name should be
* canonicalized
* @return a GSSName representing the indicated principal
*
* @see GSSName#canonicalize(Oid)
* @see GSSName#NT_EXPORT_NAME
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},
* {@link GSSException#BAD_NAME GSSException.BAD_NAME},
* {@link GSSException#BAD_MECH GSSException.BAD_MECH},
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSName createName(byte name[], Oid nameType, Oid mech)
throws GSSException;
/**
* Factory method for acquiring default credentials. This will cause
* the GSS-API to use system specific defaults for the set of mechanisms,
* name, and lifetime.
* * GSS-API mechanism providers must impose a local access-control * policy on callers to prevent unauthorized callers from acquiring * credentials to which they are not entitled. The kinds of permissions * needed by different mechanism providers will be documented on a * per-mechanism basis. A failed permission check might cause a {@link * java.lang.SecurityException SecurityException} to be thrown from * this method. * * @param usage The intended usage for this credential object. The value * of this parameter must be one of: * {@link GSSCredential#INITIATE_AND_ACCEPT * GSSCredential.INITIATE_AND_ACCEPT}, * {@link GSSCredential#ACCEPT_ONLY GSSCredential.ACCEPT_ONLY}, and * {@link GSSCredential#INITIATE_ONLY GSSCredential.INITIATE_ONLY}. * @return a GSSCredential of the requested type. * * @see GSSCredential * * @throws GSSException containing the following * major error codes: * {@link GSSException#BAD_MECH GSSException.BAD_MECH}, * {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE}, * {@link GSSException#BAD_NAME GSSException.BAD_NAME}, * {@link GSSException#CREDENTIALS_EXPIRED * GSSException.CREDENTIALS_EXPIRED}, * {@link GSSException#NO_CRED GSSException.NO_CRED}, * {@link GSSException#FAILURE GSSException.FAILURE} */ public abstract GSSCredential createCredential (int usage) throws GSSException; /** * Factory method for acquiring a single mechanism credential.
* * GSS-API mechanism providers must impose a local access-control * policy on callers to prevent unauthorized callers from acquiring * credentials to which they are not entitled. The kinds of permissions * needed by different mechanism providers will be documented on a * per-mechanism basis. A failed permission check might cause a {@link * java.lang.SecurityException SecurityException} to be thrown from * this method.
* * Non-default values for lifetime cannot always be honored by the * underlying mechanisms, thus applications should be prepared to call * {@link GSSCredential#getRemainingLifetime() getRemainingLifetime} * on the returned credential.
*
* @param name the name of the principal for whom this credential is to be
* acquired. Use null
to specify the default principal.
* @param lifetime The number of seconds that credentials should remain
* valid. Use {@link GSSCredential#INDEFINITE_LIFETIME
* GSSCredential.INDEFINITE_LIFETIME} to request that the credentials
* have the maximum permitted lifetime. Use {@link
* GSSCredential#DEFAULT_LIFETIME GSSCredential.DEFAULT_LIFETIME} to
* request default credential lifetime.
* @param mech the Oid of the desired mechanism. Use (Oid) null
*
to request the default mechanism.
* @param usage The intended usage for this credential object. The value
* of this parameter must be one of:
* {@link GSSCredential#INITIATE_AND_ACCEPT
* GSSCredential.INITIATE_AND_ACCEPT},
* {@link GSSCredential#ACCEPT_ONLY GSSCredential.ACCEPT_ONLY}, and
* {@link GSSCredential#INITIATE_ONLY GSSCredential.INITIATE_ONLY}.
* @return a GSSCredential of the requested type.
*
* @see GSSCredential
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#BAD_MECH GSSException.BAD_MECH},
* {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},
* {@link GSSException#BAD_NAME GSSException.BAD_NAME},
* {@link GSSException#CREDENTIALS_EXPIRED
* GSSException.CREDENTIALS_EXPIRED},
* {@link GSSException#NO_CRED GSSException.NO_CRED},
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSCredential createCredential (GSSName name,
int lifetime, Oid mech, int usage)
throws GSSException;
/**
* Factory method for acquiring credentials over a set of
* mechanisms. This method attempts to acquire credentials for
* each of the mechanisms specified in the array called mechs. To
* determine the list of mechanisms for which the acquisition of
* credentials succeeded, the caller should use the {@link
* GSSCredential#getMechs() GSSCredential.getMechs} method.
* * GSS-API mechanism providers must impose a local access-control * policy on callers to prevent unauthorized callers from acquiring * credentials to which they are not entitled. The kinds of permissions * needed by different mechanism providers will be documented on a * per-mechanism basis. A failed permission check might cause a {@link * java.lang.SecurityException SecurityException} to be thrown from * this method.
* * Non-default values for lifetime cannot always be honored by the * underlying mechanisms, thus applications should be prepared to call * {@link GSSCredential#getRemainingLifetime() getRemainingLifetime} * on the returned credential.
*
* @param name the name of the principal for whom this credential is to
* be acquired. Use null
to specify the default
* principal.
* @param lifetime The number of seconds that credentials should remain
* valid. Use {@link GSSCredential#INDEFINITE_LIFETIME
* GSSCredential.INDEFINITE_LIFETIME} to request that the credentials
* have the maximum permitted lifetime. Use {@link
* GSSCredential#DEFAULT_LIFETIME GSSCredential.DEFAULT_LIFETIME} to
* request default credential lifetime.
* @param mechs an array of Oid's indicating the mechanisms over which
* the credential is to be acquired. Use (Oid[]) null
for
* requesting a system specific default set of mechanisms.
* @param usage The intended usage for this credential object. The value
* of this parameter must be one of:
* {@link GSSCredential#INITIATE_AND_ACCEPT
* GSSCredential.INITIATE_AND_ACCEPT},
* {@link GSSCredential#ACCEPT_ONLY GSSCredential.ACCEPT_ONLY}, and
* {@link GSSCredential#INITIATE_ONLY GSSCredential.INITIATE_ONLY}.
* @return a GSSCredential of the requested type.
*
* @see GSSCredential
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#BAD_MECH GSSException.BAD_MECH},
* {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},
* {@link GSSException#BAD_NAME GSSException.BAD_NAME},
* {@link GSSException#CREDENTIALS_EXPIRED
* GSSException.CREDENTIALS_EXPIRED},
* {@link GSSException#NO_CRED GSSException.NO_CRED},
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSCredential createCredential(GSSName name,
int lifetime, Oid mechs[], int usage)
throws GSSException;
/**
* Factory method for creating a context on the initiator's
* side.
*
* Some mechanism providers might require that the caller be granted
* permission to initiate a security context. A failed permission check
* might cause a {@link java.lang.SecurityException SecurityException}
* to be thrown from this method.
* * Non-default values for lifetime cannot always be honored by the * underlying mechanism, thus applications should be prepared to call * {@link GSSContext#getLifetime() getLifetime} on the returned * context.
*
* @param peer the name of the target peer.
* @param mech the Oid of the desired mechanism. Use null
* to request the default mechanism.
* @param myCred the credentials of the initiator. Use
* null
to act as the default initiator principal.
* @param lifetime the lifetime, in seconds, requested for the
* context. Use {@link GSSContext#INDEFINITE_LIFETIME
* GSSContext.INDEFINITE_LIFETIME} to request that the context have the
* maximum permitted lifetime. Use {@link GSSContext#DEFAULT_LIFETIME
* GSSContext.DEFAULT_LIFETIME} to request a default lifetime for the
* context.
* @return an unestablished GSSContext
*
* @see GSSContext
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#NO_CRED GSSException.NO_CRED}
* {@link GSSException#CREDENTIALS_EXPIRED
* GSSException.CREDENTIALS_EXPIRED}
* {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE}
* {@link GSSException#BAD_MECH GSSException.BAD_MECH}
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSContext createContext(GSSName peer, Oid mech,
GSSCredential myCred, int lifetime)
throws GSSException;
/**
* Factory method for creating a context on the acceptor' side. The
* context's properties will be determined from the input token supplied
* to the accept method.
*
* Some mechanism providers might require that the caller be granted
* permission to accept a security context. A failed permission check
* might cause a {@link java.lang.SecurityException SecurityException}
* to be thrown from this method.
*
* @param myCred the credentials for the acceptor. Use
* null
to act as a default acceptor principal.
* @return an unestablished GSSContext
*
* @see GSSContext
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#NO_CRED GSSException.NO_CRED}
* {@link GSSException#CREDENTIALS_EXPIRED
* GSSException.CREDENTIALS_EXPIRED}
* {@link GSSException#BAD_MECH GSSException.BAD_MECH}
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSContext createContext(GSSCredential myCred)
throws GSSException;
/**
* Factory method for creating a previously exported context. The
* context properties will be determined from the input token and
* cannot be modified through the set methods.
*
* Implementations are not required to support the inter-process
* transfer of security contexts. Before exporting a context, calling
* the {@link GSSContext#isTransferable() GSSContext.isTransferable}
* will indicate if the context is transferable. Calling this method in
* an implementation that does not support it will result in a
* GSSException
with the error
* code {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE}.
*
* Some mechanism providers might require that the caller be granted
* permission to initiate or accept a security context. A failed
* permission check might cause a {@link java.lang.SecurityException
* SecurityException} to be thrown from this method.
*
* @param interProcessToken the token previously emitted from the
* export method.
* @return the previously established GSSContext
*
* @see GSSContext
*
* @throws GSSException containing the following
* major error codes:
* {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT},
* {@link GSSException#DEFECTIVE_TOKEN GSSException.DEFECTIVE_TOKEN},
* {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE},
* {@link GSSException#UNAUTHORIZED GSSException.UNAUTHORIZED},
* {@link GSSException#FAILURE GSSException.FAILURE}
*/
public abstract GSSContext createContext(byte [] interProcessToken)
throws GSSException;
/**
* This method is used to indicate to the GSSManager that the
* application would like a particular provider to be used ahead of all
* others when support is desired for the given mechanism. When a value
* of null is used instead of an Oid
for the mechanism,
* the GSSManager must use the indicated provider ahead of all others
* no matter what the mechanism is. Only when the indicated provider
* does not support the needed mechanism should the GSSManager move on
* to a different provider.
*
* Calling this method repeatedly preserves the older settings but
* lowers them in preference thus forming an ordered list of provider
* and Oid
pairs that grows at the top.
*
* Calling addProviderAtFront with a null Oid
will remove
* all previous preferences that were set for this provider in the
* GSSManager instance. Calling addProviderAtFront with a non-null
* Oid
will remove any previous preference that was set
* using this mechanism and this provider together.
* * If the GSSManager implementation does not support an SPI with a * pluggable provider architecture it should throw a GSSException with * the status code GSSException.UNAVAILABLE to indicate that the * operation is unavailable.
* * Suppose an application desired that the provider A always be checked * first when any mechanism is needed, it would call:
*
* GSSManager mgr = GSSManager.getInstance(); * // mgr may at this point have its own pre-configured list * // of provider preferences. The following will prepend to * // any such list: * * mgr.addProviderAtFront(A, null); ** Now if it also desired that the mechanism of Oid m1 always be * obtained from the provider B before the previously set A was checked, * it would call:
*
* mgr.addProviderAtFront(B, m1); ** The GSSManager would then first check with B if m1 was needed. In * case B did not provide support for m1, the GSSManager would continue * on to check with A. If any mechanism m2 is needed where m2 is * different from m1 then the GSSManager would skip B and check with A * directly.
* * Suppose at a later time the following call is made to the same * GSSManager instance:
*
* mgr.addProviderAtFront(B, null) ** then the previous setting with the pair (B, m1) is subsumed by this * and should be removed. Effectively the list of preferences now * becomes {(B, null), (A, null), * ... //followed by the pre-configured list.
* * Please note, however, that the following call: *
* mgr.addProviderAtFront(A, m3) ** does not subsume the previous setting of (A, null) and the list will * effectively become {(A, m3), (B, null), (A, null), ...} * * @param p the provider instance that should be used whenever support * is needed for mech. * @param mech the mechanism for which the provider is being set * * @throws GSSException containing the following * major error codes: * {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE}, * {@link GSSException#FAILURE GSSException.FAILURE} */ public abstract void addProviderAtFront(Provider p, Oid mech) throws GSSException; /** * This method is used to indicate to the GSSManager that the * application would like a particular provider to be used if no other * provider can be found that supports the given mechanism. When a value * of null is used instead of an Oid for the mechanism, the GSSManager * must use the indicated provider for any mechanism.
* * Calling this method repeatedly preserves the older settings but * raises them above newer ones in preference thus forming an ordered * list of providers and Oid pairs that grows at the bottom. Thus the * older provider settings will be utilized first before this one is.
* * If there are any previously existing preferences that conflict with * the preference being set here, then the GSSManager should ignore this * request.
* * If the GSSManager implementation does not support an SPI with a * pluggable provider architecture it should throw a GSSException with * the status code GSSException.UNAVAILABLE to indicate that the * operation is unavailable.
* * Suppose an application desired that when a mechanism of Oid m1 is * needed the system default providers always be checked first, and only * when they do not support m1 should a provider A be checked. It would * then make the call:
*
* GSSManager mgr = GSSManager.getInstance(); * mgr.addProviderAtEnd(A, m1); ** Now, if it also desired that for all mechanisms the provider B be * checked after all configured providers have been checked, it would * then call:
*
* mgr.addProviderAtEnd(B, null); ** Effectively the list of preferences now becomes {..., (A, m1), (B, * null)}.
* * Suppose at a later time the following call is made to the same * GSSManager instance:
*
* mgr.addProviderAtEnd(B, m2) ** then the previous setting with the pair (B, null) subsumes this and * therefore this request should be ignored. The same would happen if a * request is made for the already existing pairs of (A, m1) or (B, * null).
* * Please note, however, that the following call:
*
* mgr.addProviderAtEnd(A, null) ** is not subsumed by the previous setting of (A, m1) and the list will * effectively become {..., (A, m1), (B, null), (A, null)} * * @param p the provider instance that should be used whenever support * is needed for mech. * @param mech the mechanism for which the provider is being set * * @throws GSSException containing the following * major error codes: * {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE}, * {@link GSSException#FAILURE GSSException.FAILURE} */ public abstract void addProviderAtEnd(Provider p, Oid mech) throws GSSException; }