001 /*
002 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.net.ssl;
027
028 import java.io.IOException;
029 import java.net.InetAddress;
030 import java.net.ServerSocket;
031 import java.net.SocketException;
032 import javax.net.ServerSocketFactory;
033 import java.security.*;
034
035 /**
036 * <code>SSLServerSocketFactory</code>s create
037 * <code>SSLServerSocket</code>s.
038 *
039 * @since 1.4
040 * @see SSLSocket
041 * @see SSLServerSocket
042 * @version 1.33
043 * @author David Brownell
044 */
045 public abstract class SSLServerSocketFactory extends
046 ServerSocketFactory {
047 private static SSLServerSocketFactory theFactory;
048
049 private static boolean propertyChecked;
050
051 private static void log(String msg) {
052 if (SSLSocketFactory.DEBUG) {
053 System.out.println(msg);
054 }
055 }
056
057 /**
058 * Constructor is used only by subclasses.
059 */
060 protected SSLServerSocketFactory() { /* NOTHING */
061 }
062
063 /**
064 * Returns the default SSL server socket factory.
065 *
066 * <p>The first time this method is called, the security property
067 * "ssl.ServerSocketFactory.provider" is examined. If it is non-null, a
068 * class by that name is loaded and instantiated. If that is successful and
069 * the object is an instance of SSLServerSocketFactory, it is made the
070 * default SSL server socket factory.
071 *
072 * <p>Otherwise, this method returns
073 * <code>SSLContext.getDefault().getServerSocketFactory()</code>. If that
074 * call fails, an inoperative factory is returned.
075 *
076 * @return the default <code>ServerSocketFactory</code>
077 * @see SSLContext#getDefault
078 */
079 public static synchronized ServerSocketFactory getDefault() {
080 if (theFactory != null) {
081 return theFactory;
082 }
083
084 if (propertyChecked == false) {
085 propertyChecked = true;
086 String clsName = SSLSocketFactory
087 .getSecurityProperty("ssl.ServerSocketFactory.provider");
088 if (clsName != null) {
089 log("setting up default SSLServerSocketFactory");
090 try {
091 Class cls = null;
092 try {
093 cls = Class.forName(clsName);
094 } catch (ClassNotFoundException e) {
095 ClassLoader cl = ClassLoader
096 .getSystemClassLoader();
097 if (cl != null) {
098 cls = cl.loadClass(clsName);
099 }
100 }
101 log("class " + clsName + " is loaded");
102 SSLServerSocketFactory fac = (SSLServerSocketFactory) cls
103 .newInstance();
104 log("instantiated an instance of class " + clsName);
105 theFactory = fac;
106 return fac;
107 } catch (Exception e) {
108 log("SSLServerSocketFactory instantiation failed: "
109 + e);
110 theFactory = new DefaultSSLServerSocketFactory(e);
111 return theFactory;
112 }
113 }
114 }
115
116 try {
117 return SSLContext.getDefault().getServerSocketFactory();
118 } catch (NoSuchAlgorithmException e) {
119 return new DefaultSSLServerSocketFactory(e);
120 }
121 }
122
123 /**
124 * Returns the list of cipher suites which are enabled by default.
125 * Unless a different list is enabled, handshaking on an SSL connection
126 * will use one of these cipher suites. The minimum quality of service
127 * for these defaults requires confidentiality protection and server
128 * authentication (that is, no anonymous cipher suites).
129 *
130 * @see #getSupportedCipherSuites()
131 * @return array of the cipher suites enabled by default
132 */
133 public abstract String[] getDefaultCipherSuites();
134
135 /**
136 * Returns the names of the cipher suites which could be enabled for use
137 * on an SSL connection created by this factory.
138 * Normally, only a subset of these will actually
139 * be enabled by default, since this list may include cipher suites which
140 * do not meet quality of service requirements for those defaults. Such
141 * cipher suites are useful in specialized applications.
142 *
143 * @return an array of cipher suite names
144 * @see #getDefaultCipherSuites()
145 */
146 public abstract String[] getSupportedCipherSuites();
147 }
148
149 //
150 // The default factory does NOTHING.
151 //
152 class DefaultSSLServerSocketFactory extends SSLServerSocketFactory {
153
154 private final Exception reason;
155
156 DefaultSSLServerSocketFactory(Exception reason) {
157 this .reason = reason;
158 }
159
160 private ServerSocket throwException() throws SocketException {
161 throw (SocketException) new SocketException(reason.toString())
162 .initCause(reason);
163 }
164
165 public ServerSocket createServerSocket() throws IOException {
166 return throwException();
167 }
168
169 public ServerSocket createServerSocket(int port) throws IOException {
170 return throwException();
171 }
172
173 public ServerSocket createServerSocket(int port, int backlog)
174 throws IOException {
175 return throwException();
176 }
177
178 public ServerSocket createServerSocket(int port, int backlog,
179 InetAddress ifAddress) throws IOException {
180 return throwException();
181 }
182
183 public String[] getDefaultCipherSuites() {
184 return new String[0];
185 }
186
187 public String[] getSupportedCipherSuites() {
188 return new String[0];
189 }
190 }
|