/* Sasl.java -- 
   Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.security.sasl;

import java.security.Provider;
import java.security.Security;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import javax.security.auth.callback.CallbackHandler;

/**
 * <p>A static class for creating SASL clients and servers.</p>
 *
 * <p>This class defines the policy of how to locate, load, and instantiate SASL
 * clients and servers.</p>
 *
 * <p>For example, an application or library gets a SASL client instance by
 * doing something like:</p>
 *
 * <pre>
 *SaslClient sc =
 *      Sasl.createSaslClient(mechanisms, authorizationID, protocol,
 *                            serverName, props, callbackHandler);
 * </pre>
 *
 * <p>It can then proceed to use the instance to create an authenticated
 * connection.</p>
 *
 * <p>Similarly, a server gets a SASL server instance by using code that looks
 * as follows:</p>
 *
 * <pre>
 *SaslServer ss =
 *      Sasl.createSaslServer(mechanism, protocol, serverName, props,
 *                            callbackHandler);
 * </pre>
 */
public class Sasl
{

  // Constants and variables
  // -------------------------------------------------------------------------

  /**
   * <p>The name of a property that specifies the quality-of-protection to use.
   * The property contains a comma-separated, ordered list of quality-of-
   * protection values that the client or server is willing to support. A qop
   * value is one of:</p>
   *
   * <ul>
   *    <li><code>"auth"</code> - authentication only,</li>
   *    <li><code>"auth-int"</code> - authentication plus integrity
   *    protection,</li>
   *    <li><code>"auth-conf"</code> - authentication plus integrity and
   *    confidentiality protection.</li>
   * </ul>
   *
   * <p>The order of the list specifies the preference order of the client or
   * server.</p>
   *
   * <p>If this property is absent, the default qop is <code>"auth"</code>.</p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.qop"</code>.</p>
   */
  public static final String QOP = "javax.security.sasl.qop";

  /**
   * <p>The name of a property that specifies the cipher strength to use. The
   * property contains a comma-separated, ordered list of cipher strength
   * values that the client or server is willing to support. A strength value
   * is one of:</p>
   *
   * <ul>
   *    <li><code>"low"</code>,</li>
   *    <li><code>"medium"</code>,</li>
   *    <li><code>"high"</code>.</li>
   * </ul>
   *
   * <p>The order of the list specifies the preference order of the client or
   * server. An implementation should allow configuration of the meaning of
   * these values. An application may use the Java Cryptography Extension (JCE)
   * with JCE-aware mechanisms to control the selection of cipher suites that
   * match the strength values.</p>
   *
   * <p>If this property is absent, the default strength is
   * <code>"high,medium,low"</code>.</p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.strength"</code>.
   * </p>
   */
  public static final String STRENGTH = "javax.security.sasl.strength";

  /**
   * <p>The name of a property that specifies whether the server must authenticate
   * to the client. The property contains <code>"true"</code> if the server
   * must authenticate the to client; <code>"false"</code> otherwise. The
   * default is <code>"false"</code>.</p>
   *
   * <p>The value of this constant is
   * <code>"javax.security.sasl.server.authentication"</code>.</p>
   */
  public static final String SERVER_AUTH = "javax.security.sasl.server.authentication";

  /**
   * <p>The name of a property that specifies the maximum size of the receive
   * buffer in bytes of {@link SaslClient}/{@link SaslServer}. The property
   * contains the string representation of an integer.</p>
   *
   * <p>If this property is absent, the default size is defined by the
   * mechanism.</p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.maxbuffer"</code>.
   * </p>
   */
  public static final String MAX_BUFFER = "javax.security.sasl.maxbuffer";

  /**
   * <p>The name of a property that specifies the maximum size of the raw send
   * buffer in bytes of {@link SaslClient}/{@link SaslServer}. The property
   * contains the string representation of an integer. The value of this
   * property is negotiated between the client and server during the
   * authentication exchange.</p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.rawsendsize"</code>.
   * </p>
   */
  public static final String RAW_SEND_SIZE = "javax.security.sasl.rawsendsize";

  /**
   * <p>The name of a property that specifies whether mechanisms susceptible
   * to simple plain passive attacks (e.g., "PLAIN") are not permitted. The
   * property contains <code>"true"</code> if such mechanisms are not
   * permitted; <code>"false"</code> if such mechanisms are permitted. The
   * default is <code>"false"</code>.</p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.policy.noplaintext"</code>.
   * </p>
   */
  public static final String POLICY_NOPLAINTEXT = "javax.security.sasl.policy.noplaintext";

  /**
   * <p>The name of a property that specifies whether mechanisms susceptible to
   * active (non-dictionary) attacks are not permitted. The property contains
   * <code>"true"</code> if mechanisms susceptible to active attacks are not
   * permitted; <code>"false"</code> if such mechanisms are permitted. The
   * default is <code>"false"</code>.</p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.policy.noactive"</code>.
   * </p>
   */
  public static final String POLICY_NOACTIVE = "javax.security.sasl.policy.noactive";

  /**
   * <p>The name of a property that specifies whether mechanisms susceptible to
   * passive dictionary attacks are not permitted. The property contains
   * <code>"true"</code> if mechanisms susceptible to dictionary attacks are
   * not permitted; <code>"false"</code> if such mechanisms are permitted. The
   * default is <code>"false"</code>.</p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.policy.nodictionary"</code>.
   * </p>
   */
  public static final String POLICY_NODICTIONARY = "javax.security.sasl.policy.nodictionary";

  /**
   * <p>The name of a property that specifies whether mechanisms that accept
   * anonymous login are not permitted. The property contains <code>"true"</code>
   * if mechanisms that accept anonymous login are not permitted; <code>"false"
   * </code> if such mechanisms are permitted. The default is <code>"false"</code>.
   * </p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.policy.noanonymous"</code>.
   * </p>
   */
  public static final String POLICY_NOANONYMOUS = "javax.security.sasl.policy.noanonymous";

  /**
   * The name of a property that specifies whether mechanisms that implement
   * forward secrecy between sessions are required. Forward secrecy means that
   * breaking into one session will not automatically provide information for
   * breaking into future sessions. The property contains <code>"true"</code>
   * if mechanisms that implement forward secrecy between sessions are
   * required; <code>"false"</code> if such mechanisms are not required. The
   * default is <code>"false"</code>.
   *
   * <p>The value of this constant is <code>"javax.security.sasl.policy.forward"</code>.
   * </p>
   */
  public static final String POLICY_FORWARD_SECRECY = "javax.security.sasl.policy.forward";

  /**
   * The name of a property that specifies whether mechanisms that pass client
   * credentials are required. The property contains <code>"true"</code> if
   * mechanisms that pass client credentials are required; <code>"false"</code>
   * if such mechanisms are not required. The default is <code>"false"</code>.
   *
   * <p>The value of this constant is <code>"javax.security.sasl.policy.credentials"</code>.
   * </p>
   */
  public static final String POLICY_PASS_CREDENTIALS = "javax.security.sasl.policy.credentials";

  /**
   * <p>The name of a property that specifies whether to reuse previously
   * authenticated session information. The property contains <code>"true"</code>
   * if the mechanism implementation may attempt to reuse previously
   * authenticated session information; it contains <code>"false"</code> if the
   * implementation must not reuse previously authenticated session information.
   * A setting of <code>"true"</code> serves only as a hint; it does not
   * necessarily entail actual reuse because reuse might not be possible due to
   * a number of reasons, including, but not limited to, lack of mechanism
   * support for reuse, expiration of reusable information, and the peer's
   * refusal to support reuse. The property's default value is <code>"false"</code>.
   * </p>
   *
   * <p>The value of this constant is <code>"javax.security.sasl.reuse"</code>.
   * Note that all other parameters and properties required to create a SASL
   * client/server instance must be provided regardless of whether this
   * property has been supplied. That is, you cannot supply any less
   * information in anticipation of reuse. Mechanism implementations that
   * support reuse might allow customization of its implementation for factors
   * such as cache size, timeouts, and criteria for reuseability. Such
   * customizations are implementation-dependent.</p>
   */
  public static final String REUSE = "javax.security.sasl.reuse";

  private static final String CLIENT_FACTORY_SVC = "SaslClientFactory.";
  private static final String SERVER_FACTORY_SVC = "SaslServerFactory.";
  private static final String ALIAS = "Alg.Alias.";

  // Constructor(s)
  // -------------------------------------------------------------------------

  private Sasl()
  {
    super();
  }

  // Class methods
  // -------------------------------------------------------------------------

  /**
   * Creates a {@link SaslClient} for the specified mechanism.
   *
   * <p>This method uses the JCA Security Provider Framework, described in the
   * "Java Cryptography Architecture API Specification &amp; Reference", for
   * locating and selecting a {@link SaslClient} implementation.</p>
   *
   * <p>First, it obtains an ordered list of {@link SaslClientFactory}
   * instances from the registered security providers for the
   * <code>"SaslClientFactory"</code> service and the specified mechanism. It
   * then invokes <code>createSaslClient()</code> on each factory instance on
   * the list until one produces a non-null {@link SaslClient} instance. It
   * returns the non-null {@link SaslClient} instance, or <code>null</code> if
   * the search fails to produce a non-null {@link SaslClient} instance.</p>
   *
   * <p>A security provider for <code>SaslClientFactory</code> registers with
   * the JCA Security Provider Framework keys of the form:</p>
   *
   * <pre>
   *    SaslClientFactory.mechanism_name
   * </pre>
   *
   * <p>and values that are class names of implementations of {@link
   * SaslClientFactory}.</p>
   *
   * <p>For example, a provider that contains a factory class,
   * <code>com.wiz.sasl.digest.ClientFactory</code>, that supports the
   * <code>"DIGEST-MD5"</code> mechanism would register the following entry
   * with the JCA:</p>
   *
   * <pre>
   *    SaslClientFactory.DIGEST-MD5     com.wiz.sasl.digest.ClientFactory
   * </pre>
   *
   * <p>See the "Java Cryptography Architecture API Specification &amp;
   * Reference" for information about how to install and configure security
   * service providers.</p>
   *
   * @param mechanisms the non-null list of mechanism names to try. Each is the
   * IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5").
   * @param authorizationID the possibly <code>null</code> protocol-dependent
   * identification to be used for authorization. If <code>null</code> or
   * empty, the server derives an authorization ID from the client's
   * authentication credentials. When the SASL authentication completes
   * successfully, the specified entity is granted access.
   * @param protocol the non-null string name of the protocol for which the
   * authentication is being performed (e.g. "ldap").
   * @param serverName the non-null fully-qualified host name of the server to
   * authenticate to.
   * @param props the possibly null set of properties used to select the SASL
   * mechanism and to configure the authentication exchange of the selected
   * mechanism. For example, if props contains the {@link Sasl#POLICY_NOPLAINTEXT}
   * property with the value <code>"true"</code>, then the selected SASL
   * mechanism must not be susceptible to simple plain passive attacks. In
   * addition to the standard properties declared in this class, other,
   * possibly mechanism-specific, properties can be included. Properties not
   * relevant to the selected mechanism are ignored.
   * @param cbh the possibly <code>null</code> callback handler to used by the
   * SASL mechanisms to get further information from the application/library to
   * complete the authentication. For example, a SASL mechanism might require
   * the authentication ID, password and realm from the caller. The
   * authentication ID is requested by using a
   * {@link javax.security.auth.callback.NameCallback}. The password is
   * requested by using a {@link javax.security.auth.callback.PasswordCallback}.
   * The realm is requested by using a {@link RealmChoiceCallback} if there is
   * a list of realms to choose from, and by using a {@link RealmCallback} if
   * the realm must be entered.
   * @return a possibly <code>null</code> {@link SaslClient} created using the
   * parameters supplied. If <code>null</code>, the method could not find a
   * {@link SaslClientFactory} that will produce one.
   * @throws SaslException if a {@link SaslClient} cannot be created because
   * of an error.
   */
  public static SaslClient createSaslClient(String[] mechanisms,
                                            String authorizationID,
                                            String protocol,
                                            String serverName, Map props,
                                            CallbackHandler cbh)
    throws SaslException
  {
    if (mechanisms == null)
      {
        return null;
      }
    Provider[] providers = Security.getProviders();
    if (providers == null || providers.length == 0)
      {
        return null;
      }

    SaslClient result = null;
    SaslClientFactory factory = null;
    String m, clazz = null, upper, alias;
    int j;
    Provider p;
    for (int i = 0; i < mechanisms.length; i++)
      {
        m = mechanisms[i];
        if (m == null)
          continue;
        for (j = 0; j < providers.length; j++)
          {
            p = providers[j];
            if (p != null)
              {
                // try the name as is
                clazz = p.getProperty(CLIENT_FACTORY_SVC + m);
                if (clazz == null) // try all uppercase
                  {
                    upper = m.toUpperCase();
                    clazz = p.getProperty(CLIENT_FACTORY_SVC + upper);
                    if (clazz == null) // try if it's an alias
                      {
                        alias = p.getProperty(ALIAS + CLIENT_FACTORY_SVC + m);
                        if (alias == null) // try all-uppercase alias name
                          {
                            alias = p.getProperty(ALIAS + CLIENT_FACTORY_SVC + upper);
                            if (alias == null) // spit the dummy
                              continue;
                          }
                        clazz = p.getProperty(CLIENT_FACTORY_SVC + alias);
                      }
                  }
                if (clazz == null)
                  continue;
                else
                  clazz = clazz.trim();
              }

            try
              {
                result = null;
                factory = (SaslClientFactory) Class.forName(clazz).newInstance();
                result = factory.createSaslClient(mechanisms, authorizationID,
                                                  protocol, serverName, props, cbh);
              }
            catch (ClassCastException ignored) // ignore instantiation exceptions
              {
              }
            catch (ClassNotFoundException ignored)
              {
              }
            catch (InstantiationException ignored)
              {
              }
            catch (IllegalAccessException ignored)
              {
              }
            if (result != null)
              return result;
          }
      }
    return null;
  }

  /**
   * Gets an enumeration of known factories for producing a {@link SaslClient}
   * instance. This method uses the same sources for locating factories as
   * <code>createSaslClient()</code>.
   *
   * @return a non-null {@link Enumeration} of known factories for producing a
   * {@link SaslClient} instance.
   * @see #createSaslClient(String[],String,String,String,Map,CallbackHandler)
   */
  public static Enumeration getSaslClientFactories()
  {
    Vector result = new Vector();
    HashSet names = new HashSet();
    Provider[] providers = Security.getProviders();
    Iterator it;
    if (providers == null)
      {
        Provider p;
        String key;
        for (int i = 0; i < providers.length; i++)
          {
            p = providers[i];
            for (it = p.keySet().iterator(); it.hasNext(); )
              {
                key = (String) it.next();
                // add key's binding (a) it is a class of a client factory,
                // and (b) the key does not include blanks
                if (key.startsWith(CLIENT_FACTORY_SVC) && key.indexOf(" ") == -1)
                  {
                    names.add(p.getProperty(key));
                    break;
                  }
              }
          }
      }
    // we have the factory class names in names; instantiate and enumerate
    String c;
    for (it = names.iterator(); it.hasNext(); )
      {
        c = (String) it.next();
        try
          {
            SaslClientFactory f = (SaslClientFactory) Class.forName(c).newInstance();
            if (f != null)
              result.add(f);
          } catch (ClassCastException ignored) { // ignore instantiation exceptions
          } catch (ClassNotFoundException ignored) {
          } catch (InstantiationException ignored) {
          } catch (IllegalAccessException ignored) {
          }
      }

    return result.elements();
  }

  /**
   * Creates a {@link SaslServer} for the specified mechanism.
   *
   * <p>This method uses the JCA Security Provider Framework, described in the
   * "Java Cryptography Architecture API Specification &amp; Reference", for
   * locating and selecting a SaslServer implementation.</p>
   *
   * <p>First, it obtains an ordered list of {@link SaslServerFactory}
   * instances from the registered security providers for the
   * <code>"SaslServerFactory"</code> service and the specified mechanism. It
   * then invokes <code>createSaslServer()</code> on each factory instance on
   * the list until one produces a non-null {@link SaslServer} instance. It
   * returns the non-null {@link SaslServer} instance, or <code>null</code> if
   * the search fails to produce a non-null {@link SaslServer} instance.</p>
   *
   * <p>A security provider for {@link SaslServerFactory} registers with the
   * JCA Security Provider Framework keys of the form:</p>
   *
   * <pre>
   *    SaslServerFactory.mechanism_name
   * </pre>
   *
   * <p>and values that are class names of implementations of {@link
   * SaslServerFactory}.</p>
   *
   * <p>For example, a provider that contains a factory class,
   * <code>com.wiz.sasl.digest.ServerFactory</code>, that supports the
   * <code>"DIGEST-MD5"</code> mechanism would register the following entry
   * with the JCA:</p>
   *
   * <pre>
   *    SaslServerFactory.DIGEST-MD5     com.wiz.sasl.digest.ServerFactory
   * </pre>
   *
   * <p>See the "Java Cryptography Architecture API Specification &amp;
   * Reference" for information about how to install and configure security
   * service providers.</p>
   *
   * @param mechanism the non-null mechanism name. It must be an
   * IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5").
   * @param protocol the non-null string name of the protocol for which the
   * authentication is being performed (e.g. "ldap").
   * @param serverName the non-null fully qualified host name of the server.
   * @param props the possibly <code>null</code> set of properties used to
   * select the SASL mechanism and to configure the authentication exchange of
   * the selected mechanism. For example, if props contains the {@link
   * Sasl#POLICY_NOPLAINTEXT} property with the value <code>"true"</code>, then
   * the selected SASL mechanism must not be susceptible to simple plain
   * passive attacks. In addition to the standard properties declared in this
   * class, other, possibly mechanism-specific, properties can be included.
   * Properties not relevant to the selected mechanism are ignored.
   * @param cbh the possibly <code>null</code> callback handler to used by the
   * SASL mechanisms to get further information from the application/library to
   * complete the authentication. For example, a SASL mechanism might require
   * the authentication ID, password and realm from the caller. The
   * authentication ID is requested by using a
   * {@link javax.security.auth.callback.NameCallback}. The password is
   * requested by using a {@link javax.security.auth.callback.PasswordCallback}.
   * The realm is requested by using a {@link RealmChoiceCallback} if there is
   * a list of realms to choose from, and by using a {@link RealmCallback} if
   * the realm must be entered.
   * @return a possibly <code>null</code> {@link SaslServer} created using the
   * parameters supplied. If <code>null</code>, the method cannot find a
   * {@link SaslServerFactory} instance that will produce one.
   * @throws SaslException if a {@link SaslServer} instance cannot be created
   * because of an error.
   */
  public static SaslServer createSaslServer(String mechanism, String protocol,
                                            String serverName,
                                            Map props, CallbackHandler cbh)
    throws SaslException
  {
    if (mechanism == null)
      return null;
    Provider[] providers = Security.getProviders();
    if (providers == null || providers.length == 0)
      return null;

    SaslServer result = null;
    SaslServerFactory factory = null;
    String clazz = null, upper, alias = null;
    int j;
    Provider p;
    for (j = 0; j < providers.length; j++)
      {
        p = providers[j];
        if (p != null)
          {
            // try the name as is
            clazz = p.getProperty(SERVER_FACTORY_SVC + mechanism);
            if (clazz == null) // try all uppercase
              {
                upper = mechanism.toUpperCase();
                clazz = p.getProperty(SERVER_FACTORY_SVC + upper);
                if (clazz == null) // try if it's an alias
                  {
                    alias = p.getProperty(ALIAS + SERVER_FACTORY_SVC + mechanism);
                    if (alias == null) // try all-uppercase alias name
                      {
                        alias = p.getProperty(ALIAS + SERVER_FACTORY_SVC + upper);
                        if (alias == null) // spit the dummy
                          continue;
                      }
                  }
                clazz = p.getProperty(SERVER_FACTORY_SVC + alias);
              }
          }
        if (clazz == null)
          continue;
        else
          clazz = clazz.trim();

        try
          {
            result = null;
            factory = (SaslServerFactory) Class.forName(clazz).newInstance();
            result =
              factory.createSaslServer(mechanism, protocol, serverName, props, cbh);
          }
        catch (ClassCastException ignored) // ignore instantiation exceptions
          {
          }
        catch (ClassNotFoundException ignored)
          {
          }
        catch (InstantiationException ignored)
          {
          }
        catch (IllegalAccessException ignored)
          {
          }
        if (result != null)
          return result;
      }
    return null;
  }

  /**
   * Gets an enumeration of known factories for producing a {@link SaslServer}
   * instance. This method uses the same sources for locating factories as
   * <code>createSaslServer()</code>.
   *
   * @return a non-null {@link Enumeration} of known factories for producing a
   * {@link SaslServer} instance.
   * @see #createSaslServer(String,String,String,Map,CallbackHandler)
   */
  public static Enumeration getSaslServerFactories()
  {
    Vector result = new Vector();
    HashSet names = new HashSet();
    Provider[] providers = Security.getProviders();
    Iterator it;
    if (providers == null)
      {
        Provider p;
        String key;
        for (int i = 0; i < providers.length; i++)
          {
            p = providers[i];
            for (it = p.keySet().iterator(); it.hasNext(); )
              {
                key = (String) it.next();
                // add key's binding (a) it is a class of a server factory,
                // and (b) the key does not include blanks
                if (key.startsWith(SERVER_FACTORY_SVC) && key.indexOf(" ") == -1)
                  {
                    names.add(p.getProperty(key));
                    break;
                  }
              }
          }
      }
    // we have the factory class names in names; instantiate and enumerate
    String c;
    for (it = names.iterator(); it.hasNext(); )
      {
        c = (String) it.next();
        try
          {
            SaslServerFactory f = (SaslServerFactory) Class.forName(c).newInstance();
            if (f != null)
              result.add(f);
          }
        catch (ClassCastException ignored) // ignore instantiation exceptions
          {
          }
        catch (ClassNotFoundException ignored)
          {
          }
        catch (InstantiationException ignored)
          {
          }
        catch (IllegalAccessException ignored)
          {
          }
      }

    return result.elements();
  }
}
