View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2001-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: SslHttpJndiInitialContextFactory.java,v 1.8 2003/08/07 13:32:58 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * $Date        jimm    Created
47   */
48  package org.exolab.jms.jndi.http;
49  
50  import java.security.Provider;
51  import java.security.Security;
52  import java.util.Hashtable;
53  
54  import javax.naming.ConfigurationException;
55  import javax.naming.Context;
56  import javax.naming.NamingException;
57  
58  import org.apache.commons.logging.Log;
59  import org.apache.commons.logging.LogFactory;
60  
61  import org.exolab.core.http.HttpClient;
62  import org.exolab.core.util.URI;
63  import org.exolab.jms.jndi.JndiConstants;
64  
65  
66  /***
67   * This is the client side helper class that retrieves the root context
68   * of the JNDI server. This class implements the InitialContextFactory
69   * interface.
70   *
71   * @version     $Revision: 1.8 $ $Date: 2003/08/07 13:32:58 $
72   * @author      <a href="mailto:mourikis@exolab.org">Jim Mourikis</a>
73   */
74  public class SslHttpJndiInitialContextFactory
75      extends HttpJndiInitialContextFactory {
76  
77      /***
78       * Indicates if SSL has been initialized
79       */
80      private boolean _sslInitialized = false;
81  
82      /***
83       * The https protocol identifier
84       */
85      private static final String HTTPS_SCHEME = "https";
86  
87      /***
88       * The logger
89       */
90      private static final Log _log
91          = LogFactory.getLog(SslHttpJndiInitialContextFactory.class);
92  
93      /***
94       * Default constructor
95       */
96      public SslHttpJndiInitialContextFactory() {
97      }
98  
99      /***
100      * Returns the JNDI provider URL
101      *
102      * @return the JNDI provider URL
103      * @throws NamingException if the URL cannot be determined
104      */
105     protected String getProviderURL(Hashtable environment)
106         throws NamingException {
107 
108         if (environment == null) {
109             throw new ConfigurationException(
110                 "Cannot connect to JNDI provider - environment not set");
111         }
112         String url = (String) environment.get(Context.PROVIDER_URL);
113         if (url != null) {
114             URI uri;
115             try {
116                 uri = new URI(url);
117             } catch (URI.MalformedURIException exception) {
118                 throw new ConfigurationException(
119                     "Malformed JNDI provider URL: " + url);
120             }
121             if (!HTTPS_SCHEME.equals(uri.getScheme())) {
122                 throw new ConfigurationException(
123                     "URL=" + url + " has an invalid scheme");
124             }
125             String path = uri.getPath();
126             if (path == null || path.length() == 0) {
127                 url += "/" + SERVLET;
128             } else if (path.equals("/")) {
129                 url += SERVLET;
130             }
131         } else {
132             url = getDeprecatedEnvironment(environment);
133         }
134         return url;
135     }
136 
137     /***
138      * Get a connection to the JNDI provider
139      *
140      * @param url the JNDI provider URL
141      * @return a connection to the JNDI provider
142      * @throws NamingException if a connection cannot be established
143      */
144     protected HttpClient openConnection(String url) throws NamingException {
145         HttpClient client;
146         initSSL();
147         try {
148             client = new HttpClient(url, "SslHttpJndiInitialContextFactory");
149         } catch (Exception exception) {
150             NamingException error = new NamingException(
151                 "Failed to connect to JNDI provider");
152             error.setRootCause(exception);
153             throw error;
154         }
155         return client;
156     }
157 
158     /***
159      * Initialises SSL
160      *
161      * @throws NamingException if SSL can't be initialised
162      */
163     private synchronized void initSSL() throws NamingException {
164         if (!_sslInitialized) {
165             try {
166                 System.setProperty(
167                     "java.protocol.handler.pkgs",
168                     "com.sun.net.ssl.internal.www.protocol");
169                 Class providerClass =
170                     Class.forName("com.sun.net.ssl.internal.ssl.Provider");
171                 Provider provider = (Provider) providerClass.newInstance();
172                 Security.addProvider(provider);
173                 _sslInitialized = true;
174             } catch (Exception exception) {
175                 NamingException error = new ConfigurationException(
176                     "Failed to initialise SSL");
177                 error.setRootCause(exception);
178                 throw error;
179             }
180         }
181     }
182 
183     /***
184      * Returns the https url using the old environment properties, logging a
185      * warning. This method will be removed in future releases
186      */
187     private String getDeprecatedEnvironment(Hashtable environment) {
188         _log.warn(
189             getClass().getName()
190             + ": using deprecated environment. Use Context.PROVIDER_URL");
191 
192         StringBuffer url = new StringBuffer(HTTPS_SCHEME);
193         String host = (String) environment.get(JndiConstants.HOST_PROPERTY);
194         Integer port = (Integer) environment.get(
195             JndiConstants.PORT_NUMBER_PROPERTY);
196 
197         // if the host is specified then use it, otherwise use localhost
198         if (host != null) {
199             url.append(host);
200         } else {
201             url.append("localhost");
202         }
203 
204         // if the port has been specified then use it
205         if (port != null) {
206             url.append(":");
207             url.append(port.toString());
208         }
209 
210         url.append("/");
211         url.append(SERVLET);
212 
213         return url.toString();
214     }
215 
216 } //-- SslHttpJndiInitialContextFactory