Path: blob/master/src/java.security.sasl/share/classes/javax/security/sasl/SaslServer.java
41159 views
/*1* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.security.sasl;2627/**28* Performs SASL authentication as a server.29* <p>30* A server such an LDAP server gets an instance of this31* class in order to perform authentication defined by a specific SASL32* mechanism. Invoking methods on the {@code SaslServer} instance33* generates challenges according to the SASL34* mechanism implemented by the {@code SaslServer}.35* As the authentication proceeds, the instance36* encapsulates the state of a SASL server's authentication exchange.37* <p>38* Here's an example of how an LDAP server might use a {@code SaslServer}.39* It first gets an instance of a {@code SaslServer} for the SASL mechanism40* requested by the client:41* <blockquote><pre>42* SaslServer ss = Sasl.createSaslServer(mechanism,43* "ldap", myFQDN, props, callbackHandler);44* </pre></blockquote>45* It can then proceed to use the server for authentication.46* For example, suppose the LDAP server received an LDAP BIND request47* containing the name of the SASL mechanism and an (optional) initial48* response. It then might use the server as follows:49* <blockquote><pre>{@code50* while (!ss.isComplete()) {51* try {52* byte[] challenge = ss.evaluateResponse(response);53* if (ss.isComplete()) {54* status = ldap.sendBindResponse(mechanism, challenge, SUCCESS);55* } else {56* status = ldap.sendBindResponse(mechanism, challenge,57* SASL_BIND_IN_PROGRESS);58* response = ldap.readBindRequest();59* }60* } catch (SaslException e) {61* status = ldap.sendErrorResponse(e);62* break;63* }64* }65* if (ss.isComplete() && status == SUCCESS) {66* String qop = (String) sc.getNegotiatedProperty(Sasl.QOP);67* if (qop != null68* && (qop.equalsIgnoreCase("auth-int")69* || qop.equalsIgnoreCase("auth-conf"))) {70*71* // Use SaslServer.wrap() and SaslServer.unwrap() for future72* // communication with client73* ldap.in = new SecureInputStream(ss, ldap.in);74* ldap.out = new SecureOutputStream(ss, ldap.out);75* }76* }77* }</pre></blockquote>78*79* @since 1.580*81* @see Sasl82* @see SaslServerFactory83*84* @author Rosanna Lee85* @author Rob Weltman86*/87public abstract interface SaslServer {8889/**90* Returns the IANA-registered mechanism name of this SASL server.91* (e.g. "CRAM-MD5", "GSSAPI").92* @return A non-null string representing the IANA-registered mechanism name.93*/94public abstract String getMechanismName();9596/**97* Evaluates the response data and generates a challenge.98*99* If a response is received from the client during the authentication100* process, this method is called to prepare an appropriate next101* challenge to submit to the client. The challenge is null if the102* authentication has succeeded and no more challenge data is to be sent103* to the client. It is non-null if the authentication must be continued104* by sending a challenge to the client, or if the authentication has105* succeeded but challenge data needs to be processed by the client.106* {@code isComplete()} should be called107* after each call to {@code evaluateResponse()},to determine if any further108* response is needed from the client.109*110* @param response The non-null (but possibly empty) response sent111* by the client.112*113* @return The possibly null challenge to send to the client.114* It is null if the authentication has succeeded and there is115* no more challenge data to be sent to the client.116* @exception SaslException If an error occurred while processing117* the response or generating a challenge.118*/119public abstract byte[] evaluateResponse(byte[] response)120throws SaslException;121122/**123* Determines whether the authentication exchange has completed.124* This method is typically called after each invocation of125* {@code evaluateResponse()} to determine whether the126* authentication has completed successfully or should be continued.127* @return true if the authentication exchange has completed; false otherwise.128*/129public abstract boolean isComplete();130131/**132* Reports the authorization ID in effect for the client of this133* session.134* This method can only be called if isComplete() returns true.135* @return The authorization ID of the client.136* @exception IllegalStateException if this authentication session has not completed137*/138public String getAuthorizationID();139140/**141* Unwraps a byte array received from the client.142* This method can be called only after the authentication exchange has143* completed (i.e., when {@code isComplete()} returns true) and only if144* the authentication exchange has negotiated integrity and/or privacy145* as the quality of protection; otherwise,146* an {@code IllegalStateException} is thrown.147* <p>148* {@code incoming} is the contents of the SASL buffer as defined in RFC 2222149* without the leading four octet field that represents the length.150* {@code offset} and {@code len} specify the portion of {@code incoming}151* to use.152*153* @param incoming A non-null byte array containing the encoded bytes154* from the client.155* @param offset The starting position at {@code incoming} of the bytes to use.156* @param len The number of bytes from {@code incoming} to use.157* @return A non-null byte array containing the decoded bytes.158* @exception SaslException if {@code incoming} cannot be successfully159* unwrapped.160* @exception IllegalStateException if the authentication exchange has161* not completed, or if the negotiated quality of protection162* has neither integrity nor privacy163*/164public abstract byte[] unwrap(byte[] incoming, int offset, int len)165throws SaslException;166167/**168* Wraps a byte array to be sent to the client.169* This method can be called only after the authentication exchange has170* completed (i.e., when {@code isComplete()} returns true) and only if171* the authentication exchange has negotiated integrity and/or privacy172* as the quality of protection; otherwise, a {@code SaslException} is thrown.173* <p>174* The result of this method175* will make up the contents of the SASL buffer as defined in RFC 2222176* without the leading four octet field that represents the length.177* {@code offset} and {@code len} specify the portion of {@code outgoing}178* to use.179*180* @param outgoing A non-null byte array containing the bytes to encode.181* @param offset The starting position at {@code outgoing} of the bytes to use.182* @param len The number of bytes from {@code outgoing} to use.183* @return A non-null byte array containing the encoded bytes.184* @exception SaslException if {@code outgoing} cannot be successfully185* wrapped.186* @exception IllegalStateException if the authentication exchange has187* not completed, or if the negotiated quality of protection has188* neither integrity nor privacy.189*/190public abstract byte[] wrap(byte[] outgoing, int offset, int len)191throws SaslException;192193/**194* Retrieves the negotiated property.195* This method can be called only after the authentication exchange has196* completed (i.e., when {@code isComplete()} returns true); otherwise, an197* {@code IllegalStateException} is thrown.198* <p>199* The {@link Sasl} class includes several well-known property names200* (For example, {@link Sasl#QOP}). A SASL provider can support other201* properties which are specific to the vendor and/or a mechanism.202*203* @param propName the property204* @return The value of the negotiated property. If null, the property was205* not negotiated or is not applicable to this mechanism.206* @exception IllegalStateException if this authentication exchange has not completed207*/208209public abstract Object getNegotiatedProperty(String propName);210211/**212* Disposes of any system resources or security-sensitive information213* the SaslServer might be using. Invoking this method invalidates214* the SaslServer instance. This method is idempotent.215* @throws SaslException If a problem was encountered while disposing216* the resources.217*/218public abstract void dispose() throws SaslException;219}220221222