Home » openjdk-7 » javax » naming » ldap » [javadoc | source]

    1   /*
    2    * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.naming.ldap;
   27   
   28   import java.util.Iterator;
   29   import java.security.AccessController;
   30   import java.security.PrivilegedAction;
   31   import javax.naming.ConfigurationException;
   32   import javax.naming.NamingException;
   33   import com.sun.naming.internal.VersionHelper;
   34   import java.util.ServiceLoader;
   35   import java.util.ServiceConfigurationError;
   36   
   37   /**
   38    * This class implements the LDAPv3 Extended Request for StartTLS as
   39    * defined in
   40    * <a href="http://www.ietf.org/rfc/rfc2830.txt">Lightweight Directory
   41    * Access Protocol (v3): Extension for Transport Layer Security</a>
   42    *
   43    * The object identifier for StartTLS is 1.3.6.1.4.1.1466.20037
   44    * and no extended request value is defined.
   45    *<p>
   46    * <tt>StartTlsRequest</tt>/<tt>StartTlsResponse</tt> are used to establish
   47    * a TLS connection over the existing LDAP connection associated with
   48    * the JNDI context on which <tt>extendedOperation()</tt> is invoked.
   49    * Typically, a JNDI program uses these classes as follows.
   50    * <blockquote><pre>
   51    * import javax.naming.ldap.*;
   52    *
   53    * // Open an LDAP association
   54    * LdapContext ctx = new InitialLdapContext();
   55    *
   56    * // Perform a StartTLS extended operation
   57    * StartTlsResponse tls =
   58    *     (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());
   59    *
   60    * // Open a TLS connection (over the existing LDAP association) and get details
   61    * // of the negotiated TLS session: cipher suite, peer certificate, etc.
   62    * SSLSession session = tls.negotiate();
   63    *
   64    * // ... use ctx to perform protected LDAP operations
   65    *
   66    * // Close the TLS connection (revert back to the underlying LDAP association)
   67    * tls.close();
   68    *
   69    * // ... use ctx to perform unprotected LDAP operations
   70    *
   71    * // Close the LDAP association
   72    * ctx.close;
   73    * </pre></blockquote>
   74    *
   75    * @since 1.4
   76    * @see StartTlsResponse
   77    * @author Vincent Ryan
   78    */
   79   public class StartTlsRequest implements ExtendedRequest {
   80   
   81       // Constant
   82   
   83       /**
   84        * The StartTLS extended request's assigned object identifier
   85        * is 1.3.6.1.4.1.1466.20037.
   86        */
   87       public static final String OID = "1.3.6.1.4.1.1466.20037";
   88   
   89   
   90       // Constructors
   91   
   92       /**
   93        * Constructs a StartTLS extended request.
   94        */
   95       public StartTlsRequest() {
   96       }
   97   
   98   
   99       // ExtendedRequest methods
  100   
  101       /**
  102        * Retrieves the StartTLS request's object identifier string.
  103        *
  104        * @return The object identifier string, "1.3.6.1.4.1.1466.20037".
  105        */
  106       public String getID() {
  107           return OID;
  108       }
  109   
  110       /**
  111        * Retrieves the StartTLS request's ASN.1 BER encoded value.
  112        * Since the request has no defined value, null is always
  113        * returned.
  114        *
  115        * @return The null value.
  116        */
  117       public byte[] getEncodedValue() {
  118           return null;
  119       }
  120   
  121       /**
  122        * Creates an extended response object that corresponds to the
  123        * LDAP StartTLS extended request.
  124        * <p>
  125        * The result must be a concrete subclass of StartTlsResponse
  126        * and must have a public zero-argument constructor.
  127        * <p>
  128        * This method locates the implementation class by locating
  129        * configuration files that have the name:
  130        * <blockquote><tt>
  131        *     META-INF/services/javax.naming.ldap.StartTlsResponse
  132        * </tt></blockquote>
  133        * The configuration files and their corresponding implementation classes must
  134        * be accessible to the calling thread's context class loader.
  135        * <p>
  136        * Each configuration file should contain a list of fully-qualified class
  137        * names, one per line.  Space and tab characters surrounding each name, as
  138        * well as blank lines, are ignored.  The comment character is <tt>'#'</tt>
  139        * (<tt>0x23</tt>); on each line all characters following the first comment
  140        * character are ignored.  The file must be encoded in UTF-8.
  141        * <p>
  142        * This method will return an instance of the first implementation
  143        * class that it is able to load and instantiate successfully from
  144        * the list of class names collected from the configuration files.
  145        * This method uses the calling thread's context classloader to find the
  146        * configuration files and to load the implementation class.
  147        * <p>
  148        * If no class can be found in this way, this method will use
  149        * an implementation-specific way to locate an implementation.
  150        * If none is found, a NamingException is thrown.
  151        *
  152        * @param id         The object identifier of the extended response.
  153        *                   Its value must be "1.3.6.1.4.1.1466.20037" or null.
  154        *                   Both values are equivalent.
  155        * @param berValue   The possibly null ASN.1 BER encoded value of the
  156        *                   extended response. This is the raw BER bytes
  157        *                   including the tag and length of the response value.
  158        *                   It does not include the response OID.
  159        *                   Its value is ignored because a Start TLS response
  160        *                   is not expected to contain any response value.
  161        * @param offset     The starting position in berValue of the bytes to use.
  162        *                   Its value is ignored because a Start TLS response
  163        *                   is not expected to contain any response value.
  164        * @param length     The number of bytes in berValue to use.
  165        *                   Its value is ignored because a Start TLS response
  166        *                   is not expected to contain any response value.
  167        * @return           The StartTLS extended response object.
  168        * @exception        NamingException If a naming exception was encountered
  169        *                   while creating the StartTLS extended response object.
  170        */
  171       public ExtendedResponse createExtendedResponse(String id, byte[] berValue,
  172           int offset, int length) throws NamingException {
  173   
  174           // Confirm that the object identifier is correct
  175           if ((id != null) && (!id.equals(OID))) {
  176               throw new ConfigurationException(
  177                   "Start TLS received the following response instead of " +
  178                   OID + ": " + id);
  179           }
  180   
  181           StartTlsResponse resp = null;
  182   
  183           ServiceLoader<StartTlsResponse> sl = ServiceLoader.load(
  184                   StartTlsResponse.class, getContextClassLoader());
  185           Iterator<StartTlsResponse> iter = sl.iterator();
  186   
  187           while (resp == null && privilegedHasNext(iter)) {
  188               resp = iter.next();
  189           }
  190           if (resp != null) {
  191               return resp;
  192           }
  193           try {
  194               VersionHelper helper = VersionHelper.getVersionHelper();
  195               Class clas = helper.loadClass(
  196                   "com.sun.jndi.ldap.ext.StartTlsResponseImpl");
  197   
  198               resp = (StartTlsResponse) clas.newInstance();
  199   
  200           } catch (IllegalAccessException e) {
  201               throw wrapException(e);
  202   
  203           } catch (InstantiationException e) {
  204               throw wrapException(e);
  205   
  206           } catch (ClassNotFoundException e) {
  207               throw wrapException(e);
  208           }
  209   
  210           return resp;
  211       }
  212   
  213       /*
  214        * Wrap an exception, thrown while attempting to load the StartTlsResponse
  215        * class, in a configuration exception.
  216        */
  217       private ConfigurationException wrapException(Exception e) {
  218           ConfigurationException ce = new ConfigurationException(
  219               "Cannot load implementation of javax.naming.ldap.StartTlsResponse");
  220   
  221           ce.setRootCause(e);
  222           return ce;
  223       }
  224   
  225       /*
  226        * Acquire the class loader associated with this thread.
  227        */
  228       private final ClassLoader getContextClassLoader() {
  229           return (ClassLoader) AccessController.doPrivileged(
  230               new PrivilegedAction() {
  231                   public Object run() {
  232                       return Thread.currentThread().getContextClassLoader();
  233                   }
  234               }
  235           );
  236       }
  237   
  238       private final static boolean privilegedHasNext(final Iterator iter) {
  239           Boolean answer = (Boolean) AccessController.doPrivileged(
  240               new PrivilegedAction() {
  241               public Object run() {
  242                   return Boolean.valueOf(iter.hasNext());
  243               }
  244           });
  245           return answer.booleanValue();
  246       }
  247   
  248       private static final long serialVersionUID = 4441679576360753397L;
  249   }

Home » openjdk-7 » javax » naming » ldap » [javadoc | source]