/*
 * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.security.sasl;

/**
 * Performs SASL authentication as a server.
 *<p>
 * A server such an LDAP server gets an instance of this
 * class in order to perform authentication defined by a specific SASL
 * mechanism. Invoking methods on the <tt>SaslServer</tt> instance
 * generates challenges according to the SASL
 * mechanism implemented by the <tt>SaslServer</tt>.
 * As the authentication proceeds, the instance
 * encapsulates the state of a SASL server's authentication exchange.
 *<p>
 * Here's an example of how an LDAP server might use a <tt>SaslServer</tt>.
 * It first gets an instance of a <tt>SaslServer</tt> for the SASL mechanism
 * requested by the client:
 *<blockquote><pre>
 * SaslServer ss = Sasl.createSaslServer(mechanism,
 *     "ldap", myFQDN, props, callbackHandler);
 *</pre></blockquote>
 * It can then proceed to use the server for authentication.
 * For example, suppose the LDAP server received an LDAP BIND request
 * containing the name of the SASL mechanism and an (optional) initial
 * response. It then might use the server as follows:
 *<blockquote><pre>
 * while (!ss.isComplete()) {
 *     try {
 *         byte[] challenge = ss.evaluateResponse(response);
 *         if (ss.isComplete()) {
 *             status = ldap.sendBindResponse(mechanism, challenge, SUCCESS);
 *         } else {
 *             status = ldap.sendBindResponse(mechanism, challenge,
                   SASL_BIND_IN_PROGRESS);
 *             response = ldap.readBindRequest();
 *         }
 *     } catch (SaslException e) {
 *          status = ldap.sendErrorResponse(e);
 *          break;
 *     }
 * }
 * if (ss.isComplete() && status == SUCCESS) {
 *    String qop = (String) sc.getNegotiatedProperty(Sasl.QOP);
 *    if (qop != null
 *        && (qop.equalsIgnoreCase("auth-int")
 *            || qop.equalsIgnoreCase("auth-conf"))) {
 *
 *      // Use SaslServer.wrap() and SaslServer.unwrap() for future
 *      // communication with client
 *      ldap.in = new SecureInputStream(ss, ldap.in);
 *      ldap.out = new SecureOutputStream(ss, ldap.out);
 *    }
 * }
 *</pre></blockquote>
 *
 * @since 1.5
 *
 * @see Sasl
 * @see SaslServerFactory
 *
 * @author Rosanna Lee
 * @author Rob Weltman
 */
public abstract interface SaslServer {

    /**
     * Returns the IANA-registered mechanism name of this SASL server.
     * (e.g. "CRAM-MD5", "GSSAPI").
     * @return A non-null string representing the IANA-registered mechanism name.
     */
    public abstract String getMechanismName();

    /**
     * Evaluates the response data and generates a challenge.
     *
     * If a response is received from the client during the authentication
     * process, this method is called to prepare an appropriate next
     * challenge to submit to the client. The challenge is null if the
     * authentication has succeeded and no more challenge data is to be sent
     * to the client. It is non-null if the authentication must be continued
     * by sending a challenge to the client, or if the authentication has
     * succeeded but challenge data needs to be processed by the client.
     * <tt>isComplete()</tt> should be called
     * after each call to <tt>evaluateResponse()</tt>,to determine if any further
     * response is needed from the client.
     *
     * @param response The non-null (but possibly empty) response sent
     * by the client.
     *
     * @return The possibly null challenge to send to the client.
     * It is null if the authentication has succeeded and there is
     * no more challenge data to be sent to the client.
     * @exception SaslException If an error occurred while processing
     * the response or generating a challenge.
     */
    public abstract byte[] evaluateResponse(byte[] response)
        throws SaslException;

    /**
      * Determines whether the authentication exchange has completed.
      * This method is typically called after each invocation of
      * <tt>evaluateResponse()</tt> to determine whether the
      * authentication has completed successfully or should be continued.
      * @return true if the authentication exchange has completed; false otherwise.
      */
    public abstract boolean isComplete();

    /**
     * Reports the authorization ID in effect for the client of this
     * session.
     * This method can only be called if isComplete() returns true.
     * @return The authorization ID of the client.
     * @exception IllegalStateException if this authentication session has not completed
     */
    public String getAuthorizationID();

    /**
     * Unwraps a byte array received from the client.
     * This method can be called only after the authentication exchange has
     * completed (i.e., when <tt>isComplete()</tt> returns true) and only if
     * the authentication exchange has negotiated integrity and/or privacy
     * as the quality of protection; otherwise,
     * an <tt>IllegalStateException</tt> is thrown.
     *<p>
     * <tt>incoming</tt> is the contents of the SASL buffer as defined in RFC 2222
     * without the leading four octet field that represents the length.
     * <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>incoming</tt>
     * to use.
     *
     * @param incoming A non-null byte array containing the encoded bytes
     *                from the client.
     * @param offset The starting position at <tt>incoming</tt> of the bytes to use.
     * @param len The number of bytes from <tt>incoming</tt> to use.
     * @return A non-null byte array containing the decoded bytes.
     * @exception SaslException if <tt>incoming</tt> cannot be successfully
     * unwrapped.
     * @exception IllegalStateException if the authentication exchange has
     * not completed, or if the negotiated quality of protection
     * has neither integrity nor privacy
     */
    public abstract byte[] unwrap(byte[] incoming, int offset, int len)
        throws SaslException;

    /**
     * Wraps a byte array to be sent to the client.
     * This method can be called only after the authentication exchange has
     * completed (i.e., when <tt>isComplete()</tt> returns true) and only if
     * the authentication exchange has negotiated integrity and/or privacy
     * as the quality of protection; otherwise, a <tt>SaslException</tt> is thrown.
     *<p>
     * The result of this method
     * will make up the contents of the SASL buffer as defined in RFC 2222
     * without the leading four octet field that represents the length.
     * <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>outgoing</tt>
     * to use.
     *
     * @param outgoing A non-null byte array containing the bytes to encode.
     * @param offset The starting position at <tt>outgoing</tt> of the bytes to use.
     * @param len The number of bytes from <tt>outgoing</tt> to use.
     * @return A non-null byte array containing the encoded bytes.
     * @exception SaslException if <tt>outgoing</tt> cannot be successfully
     * wrapped.
     * @exception IllegalStateException if the authentication exchange has
     * not completed, or if the negotiated quality of protection has
     * neither integrity nor privacy.
     */
    public abstract byte[] wrap(byte[] outgoing, int offset, int len)
        throws SaslException;

    /**
     * Retrieves the negotiated property.
     * This method can be called only after the authentication exchange has
     * completed (i.e., when <tt>isComplete()</tt> returns true); otherwise, an
     * <tt>IllegalStateException</tt> is thrown.
     *
     * @param propName the property
     * @return The value of the negotiated property. If null, the property was
     * not negotiated or is not applicable to this mechanism.
     * @exception IllegalStateException if this authentication exchange has not completed
     */

    public abstract Object getNegotiatedProperty(String propName);

     /**
      * Disposes of any system resources or security-sensitive information
      * the SaslServer might be using. Invoking this method invalidates
      * the SaslServer instance. This method is idempotent.
      * @throws SaslException If a problem was encountered while disposing
      * the resources.
      */
    public abstract void dispose() throws SaslException;
}
