Class Sasl2TaskManager
java.lang.Object
org.jivesoftware.openfire.sasl.task.Sasl2TaskManager
Registry for
Sasl2TaskProvider implementations, and driver of the SASL2 <continue/> flow that is
defined in XEP-0388 § 2.5.
Registration
Third-party code registers a provider once, typically from a plugin:
public void initializePlugin(PluginManager manager, File pluginDirectory) {
provider = new MyTaskProvider();
Sasl2TaskManager.getInstance().register(provider);
}
public void destroyPlugin() {
Sasl2TaskManager.getInstance().unregister(provider);
}
Unregistering a provider does not disturb negotiations that are already in progress: they hold direct references to
the provider and to its tasks.
Flow
addStreamFeatures(LocalSession, Element)lets providers advertise opt-in features.onAuthenticateElement(LocalSession, Element, String)starts a negotiation and lets providers read the peer's<authenticate/>element.offerTasks(LocalSession, String, String, byte[])is invoked once the SASL exchange has succeeded. If any task is eligible, it sends<continue/>and returns true, and the SASL2 negotiation is suspended.handleTaskElement(LocalSession, Element)processes the peer's<next/>and<task-data/>elements until every eligible task has completed.endNegotiation(LocalSession, boolean)tears the state down.
LocalClientSessions: the flow has no meaning for server-to-server or component
connections.- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumThe outcome of processing one protocol element in the task flow. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringSession data key under which the stream feature elements that each provider advertised are stored, as a Map of provider identifier to a List of Elements.static final SystemProperty<List<String>>Identifiers (seeSasl2TaskProvider.getIdentifier()) of providers that are registered but must not be consulted.static final SystemProperty<Boolean>Controls whether SASL2 tasks are processed at all.static final SystemProperty<Integer>The maximum number of<continue/>elements that are sent during one negotiation.static final StringSession data key under which theSasl2Negotiationof the session's current SASL2 negotiation is stored. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddStreamFeatures(LocalSession session, org.dom4j.Element authenticationFeature) Adds every registered provider's opt-in elements to the SASL2<authentication/>stream feature, and records on the session what was advertised.endNegotiation(LocalSession session, boolean successful) Ends the negotiation, if one is in progress: aborts any task that is still running, notifies every provider that participated, and removes all state from the session.protected List<Sasl2TaskProvider>The providers that are eligible to be consulted, in the order in which they are to be consulted.static Sasl2TaskManagergetNegotiation(LocalSession session) The negotiation that is in progress for the given session, if any.All registered providers, including those that are disabled by configuration.handleTaskElement(LocalSession session, org.dom4j.Element element) Processes a<next/>or<task-data/>element received from the peer.booleanofferTasks(LocalSession session, String authorizationIdentity, String saslMechanismName, byte[] saslSuccessData) Determines whether any task is to be performed before the SASL2 negotiation can be concluded, and if so, sends a<continue/>element to the peer.voidonAuthenticateElement(LocalSession session, org.dom4j.Element authenticate, String mechanismName) Starts a task negotiation for a SASL2 authentication attempt, and lets every provider inspect the peer's<authenticate/>element.voidregister(Sasl2TaskProvider provider) Registers a provider of SASL2 tasks.voidreset(LocalSession session) Discards any task negotiation state on the session, without notifying providers of a completed negotiation.booleanunregister(String identifier) Removes a previously registered provider.booleanunregister(Sasl2TaskProvider provider) Removes a previously registered provider.
-
Field Details
-
ENABLED
Controls whether SASL2 tasks are processed at all. When disabled, no task is advertised or offered, and a peer that sends<next/>or<task-data/>has its negotiation failed. This is the kill switch for deployments that run into trouble with a third-party provider. -
DISABLED_PROVIDERS
Identifiers (seeSasl2TaskProvider.getIdentifier()) of providers that are registered but must not be consulted. Lets an administrator disable one provider without unloading the plugin that supplies it. -
MAX_ROUNDS
The maximum number of<continue/>elements that are sent during one negotiation. This bounds the effect of a provider that keeps offering a task that never becomes ineligible, which would otherwise let a peer loop indefinitely. -
NEGOTIATION_KEY
Session data key under which theSasl2Negotiationof the session's current SASL2 negotiation is stored.- See Also:
-
ADVERTISED_KEY
Session data key under which the stream feature elements that each provider advertised are stored, as a Map of provider identifier to a List of Elements.- See Also:
-
-
Constructor Details
-
Sasl2TaskManager
protected Sasl2TaskManager()
-
-
Method Details
-
getInstance
-
register
Registers a provider of SASL2 tasks.- Parameters:
provider- the provider to register (cannot be null).- Throws:
IllegalArgumentException- if the provider is invalid, or if its identifier or one of its task names is already taken by another registered provider.
-
unregister
Removes a previously registered provider. Negotiations that are already in progress are unaffected.- Parameters:
provider- the provider to remove (cannot be null).- Returns:
- true if the provider was registered.
-
unregister
Removes a previously registered provider. Negotiations that are already in progress are unaffected.- Parameters:
identifier- the identifier of the provider to remove (cannot be null).- Returns:
- true if a provider was registered under this identifier.
-
getProviders
All registered providers, including those that are disabled by configuration.- Returns:
- an immutable collection of providers (never null).
-
getEnabledProviders
The providers that are eligible to be consulted, in the order in which they are to be consulted.- Returns:
- an ordered list of providers (never null, possibly empty).
-
addStreamFeatures
public void addStreamFeatures(@Nonnull LocalSession session, @Nonnull org.dom4j.Element authenticationFeature) Adds every registered provider's opt-in elements to the SASL2<authentication/>stream feature, and records on the session what was advertised. Invoke this while assembling the<authentication xmlns='urn:xmpp:sasl:2'/>feature, after the<mechanism/>elements have been added.- Parameters:
session- the session that features are being advertised to (cannot be null).authenticationFeature- the<authentication/>element being assembled (cannot be null).
-
onAuthenticateElement
public void onAuthenticateElement(@Nonnull LocalSession session, @Nonnull org.dom4j.Element authenticate, @Nonnull String mechanismName) throws SaslFailureException Starts a task negotiation for a SASL2 authentication attempt, and lets every provider inspect the peer's<authenticate/>element. Any state left over from an earlier attempt on the same session is discarded first.- Parameters:
session- the session that is authenticating (cannot be null).authenticate- the peer's<authenticate/>element (cannot be null).mechanismName- the name of the SASL mechanism that the peer selected (cannot be null).- Throws:
SaslFailureException- if a provider rejects the request.
-
offerTasks
public boolean offerTasks(@Nonnull LocalSession session, @Nullable String authorizationIdentity, @Nonnull String saslMechanismName, @Nullable byte[] saslSuccessData) throws SaslFailureException Determines whether any task is to be performed before the SASL2 negotiation can be concluded, and if so, sends a<continue/>element to the peer. Invoke this once the SASL exchange has succeeded and before the session is authenticated. When this returns true, the caller must suspend the negotiation and wait for the peer's next element; when it returns false, nothing has been sent and the caller proceeds as it would without tasks.- Parameters:
session- the session that is authenticating (cannot be null).authorizationIdentity- the authenticated username, or null for an anonymous authentication.saslMechanismName- the mechanism name as reported by the SaslServer (cannot be null).saslSuccessData- the success data produced by the SASL mechanism, or null. When a<continue/>is sent, this data is delivered in that element (XEP-0388 § 2.5), which is why the caller must not also place it in a<success/>element.- Returns:
- true if a
<continue/>was sent, false if no task applies. - Throws:
SaslFailureException- if the maximum number of<continue/>rounds (MAX_ROUNDS) was exceeded, or if an unexpected internal error occurred while assembling the round. A provider's own failure to determine its eligible tasks is isolated and logged, and does not, by itself, cause this. The negotiation is torn down (as if byendNegotiation(LocalSession, boolean)withsuccessful=false) before this exception propagates.
-
handleTaskElement
@Nonnull public Sasl2TaskManager.Outcome handleTaskElement(@Nonnull LocalSession session, @Nonnull org.dom4j.Element element) throws SaslFailureException Processes a<next/>or<task-data/>element received from the peer.- Parameters:
session- the session that is authenticating (cannot be null).element- the received element (cannot be null).- Returns:
- whether the negotiation can now be concluded, or more is expected from the peer.
- Throws:
SaslFailureException- if the element is unexpected or malformed, or if a task failed.
-
endNegotiation
Ends the negotiation, if one is in progress: aborts any task that is still running, notifies every provider that participated, and removes all state from the session.- Parameters:
session- the session (cannot be null).successful- true if the SASL2 negotiation completed successfully.- Returns:
- the negotiation that was ended, or null if none was in progress.
-
reset
Discards any task negotiation state on the session, without notifying providers of a completed negotiation. Invoked when a new authentication attempt starts.- Parameters:
session- the session (cannot be null).
-
getNegotiation
The negotiation that is in progress for the given session, if any.- Parameters:
session- the session (cannot be null).- Returns:
- a negotiation, or null.
-