History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/rmi/ssl/SslRMIServerSocketFactory.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/rmi/ssl/SslRMIServerSocketFactory.java+378−0
@@ -0,0 +1,378 @@
1/*
2 * Copyright (c) 2003, 2008, 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
26package javax.rmi.ssl;
27
28import java.io.IOException;
29import java.net.ServerSocket;
30import java.net.Socket;
31import java.rmi.server.RMIServerSocketFactory;
32import java.util.Arrays;
33import java.util.List;
34import javax.net.ssl.SSLContext;
35import javax.net.ssl.SSLServerSocketFactory;
36import javax.net.ssl.SSLSocket;
37import javax.net.ssl.SSLSocketFactory;
38
39/**
40 * <p>An <code>SslRMIServerSocketFactory</code> instance is used by the RMI
41 * runtime in order to obtain server sockets for RMI calls via SSL.</p>
42 *
43 * <p>This class implements <code>RMIServerSocketFactory</code> over
44 * the Secure Sockets Layer (SSL) or Transport Layer Security (TLS)
45 * protocols.</p>
46 *
47 * <p>This class creates SSL sockets using the default
48 * <code>SSLSocketFactory</code> (see {@link
49 * SSLSocketFactory#getDefault}) or the default
50 * <code>SSLServerSocketFactory</code> (see {@link
51 * SSLServerSocketFactory#getDefault}) unless the
52 * constructor taking an <code>SSLContext</code> is
53 * used in which case the SSL sockets are created using
54 * the <code>SSLSocketFactory</code> returned by
55 * {@link SSLContext#getSocketFactory} or the
56 * <code>SSLServerSocketFactory</code> returned by
57 * {@link SSLContext#getServerSocketFactory}.
58 *
59 * When an <code>SSLContext</code> is not supplied all the instances of this
60 * class share the same keystore, and the same truststore (when client
61 * authentication is required by the server). This behavior can be modified
62 * by supplying an already initialized <code>SSLContext</code> instance.
63 *
64 * @see javax.net.ssl.SSLSocketFactory
65 * @see javax.net.ssl.SSLServerSocketFactory
66 * @see javax.rmi.ssl.SslRMIClientSocketFactory
67 * @since 1.5
68 */
69public class SslRMIServerSocketFactory implements RMIServerSocketFactory {
70
71 /**
72 * <p>Creates a new <code>SslRMIServerSocketFactory</code> with
73 * the default SSL socket configuration.</p>
74 *
75 * <p>SSL connections accepted by server sockets created by this
76 * factory have the default cipher suites and protocol versions
77 * enabled and do not require client authentication.</p>
78 */
79 public SslRMIServerSocketFactory() {
80 this(null, null, false);
81 }
82
83 /**
84 * <p>Creates a new <code>SslRMIServerSocketFactory</code> with
85 * the specified SSL socket configuration.</p>
86 *
87 * @param enabledCipherSuites names of all the cipher suites to
88 * enable on SSL connections accepted by server sockets created by
89 * this factory, or <code>null</code> to use the cipher suites
90 * that are enabled by default
91 *
92 * @param enabledProtocols names of all the protocol versions to
93 * enable on SSL connections accepted by server sockets created by
94 * this factory, or <code>null</code> to use the protocol versions
95 * that are enabled by default
96 *
97 * @param needClientAuth <code>true</code> to require client
98 * authentication on SSL connections accepted by server sockets
99 * created by this factory; <code>false</code> to not require
100 * client authentication
101 *
102 * @exception IllegalArgumentException when one or more of the cipher
103 * suites named by the <code>enabledCipherSuites</code> parameter is
104 * not supported, when one or more of the protocols named by the
105 * <code>enabledProtocols</code> parameter is not supported or when
106 * a problem is encountered while trying to check if the supplied
107 * cipher suites and protocols to be enabled are supported.
108 *
109 * @see SSLSocket#setEnabledCipherSuites
110 * @see SSLSocket#setEnabledProtocols
111 * @see SSLSocket#setNeedClientAuth
112 */
113 public SslRMIServerSocketFactory(
114 String[] enabledCipherSuites,
115 String[] enabledProtocols,
116 boolean needClientAuth)
117 throws IllegalArgumentException {
118 this(null, enabledCipherSuites, enabledProtocols, needClientAuth);
119 }
120
121 /**
122 * <p>Creates a new <code>SslRMIServerSocketFactory</code> with the
123 * specified <code>SSLContext</code> and SSL socket configuration.</p>
124 *
125 * @param context the SSL context to be used for creating SSL sockets.
126 * If <code>context</code> is null the default <code>SSLSocketFactory</code>
127 * or the default <code>SSLServerSocketFactory</code> will be used to
128 * create SSL sockets. Otherwise, the socket factory returned by
129 * <code>SSLContext.getSocketFactory()</code> or
130 * <code>SSLContext.getServerSocketFactory()</code> will be used instead.
131 *
132 * @param enabledCipherSuites names of all the cipher suites to
133 * enable on SSL connections accepted by server sockets created by
134 * this factory, or <code>null</code> to use the cipher suites
135 * that are enabled by default
136 *
137 * @param enabledProtocols names of all the protocol versions to
138 * enable on SSL connections accepted by server sockets created by
139 * this factory, or <code>null</code> to use the protocol versions
140 * that are enabled by default
141 *
142 * @param needClientAuth <code>true</code> to require client
143 * authentication on SSL connections accepted by server sockets
144 * created by this factory; <code>false</code> to not require
145 * client authentication
146 *
147 * @exception IllegalArgumentException when one or more of the cipher
148 * suites named by the <code>enabledCipherSuites</code> parameter is
149 * not supported, when one or more of the protocols named by the
150 * <code>enabledProtocols</code> parameter is not supported or when
151 * a problem is encountered while trying to check if the supplied
152 * cipher suites and protocols to be enabled are supported.
153 *
154 * @see SSLSocket#setEnabledCipherSuites
155 * @see SSLSocket#setEnabledProtocols
156 * @see SSLSocket#setNeedClientAuth
157 * @since 1.7
158 */
159 public SslRMIServerSocketFactory(
160 SSLContext context,
161 String[] enabledCipherSuites,
162 String[] enabledProtocols,
163 boolean needClientAuth)
164 throws IllegalArgumentException {
165 // Initialize the configuration parameters.
166 //
167 this.enabledCipherSuites = enabledCipherSuites == null ?
168 null : enabledCipherSuites.clone();
169 this.enabledProtocols = enabledProtocols == null ?
170 null : enabledProtocols.clone();
171 this.needClientAuth = needClientAuth;
172
173 // Force the initialization of the default at construction time,
174 // rather than delaying it to the first time createServerSocket()
175 // is called.
176 //
177 this.context = context;
178 final SSLSocketFactory sslSocketFactory =
179 context == null ?
180 getDefaultSSLSocketFactory() : context.getSocketFactory();
181 SSLSocket sslSocket = null;
182 if (this.enabledCipherSuites != null || this.enabledProtocols != null) {
183 try {
184 sslSocket = (SSLSocket) sslSocketFactory.createSocket();
185 } catch (Exception e) {
186 final String msg = "Unable to check if the cipher suites " +
187 "and protocols to enable are supported";
188 throw (IllegalArgumentException)
189 new IllegalArgumentException(msg).initCause(e);
190 }
191 }
192
193 // Check if all the cipher suites and protocol versions to enable
194 // are supported by the underlying SSL/TLS implementation and if
195 // true create lists from arrays.
196 //
197 if (this.enabledCipherSuites != null) {
198 sslSocket.setEnabledCipherSuites(this.enabledCipherSuites);
199 enabledCipherSuitesList = Arrays.asList(this.enabledCipherSuites);
200 }
201 if (this.enabledProtocols != null) {
202 sslSocket.setEnabledProtocols(this.enabledProtocols);
203 enabledProtocolsList = Arrays.asList(this.enabledProtocols);
204 }
205 }
206
207 /**
208 * <p>Returns the names of the cipher suites enabled on SSL
209 * connections accepted by server sockets created by this factory,
210 * or <code>null</code> if this factory uses the cipher suites
211 * that are enabled by default.</p>
212 *
213 * @return an array of cipher suites enabled, or <code>null</code>
214 *
215 * @see SSLSocket#setEnabledCipherSuites
216 */
217 public final String[] getEnabledCipherSuites() {
218 return enabledCipherSuites == null ?
219 null : enabledCipherSuites.clone();
220 }
221
222 /**
223 * <p>Returns the names of the protocol versions enabled on SSL
224 * connections accepted by server sockets created by this factory,
225 * or <code>null</code> if this factory uses the protocol versions
226 * that are enabled by default.</p>
227 *
228 * @return an array of protocol versions enabled, or
229 * <code>null</code>
230 *
231 * @see SSLSocket#setEnabledProtocols
232 */
233 public final String[] getEnabledProtocols() {
234 return enabledProtocols == null ?
235 null : enabledProtocols.clone();
236 }
237
238 /**
239 * <p>Returns <code>true</code> if client authentication is
240 * required on SSL connections accepted by server sockets created
241 * by this factory.</p>
242 *
243 * @return <code>true</code> if client authentication is required
244 *
245 * @see SSLSocket#setNeedClientAuth
246 */
247 public final boolean getNeedClientAuth() {
248 return needClientAuth;
249 }
250
251 /**
252 * <p>Creates a server socket that accepts SSL connections
253 * configured according to this factory's SSL socket configuration
254 * parameters.</p>
255 */
256 public ServerSocket createServerSocket(int port) throws IOException {
257 final SSLSocketFactory sslSocketFactory =
258 context == null ?
259 getDefaultSSLSocketFactory() : context.getSocketFactory();
260 return new ServerSocket(port) {
261 public Socket accept() throws IOException {
262 Socket socket = super.accept();
263 SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
264 socket, socket.getInetAddress().getHostName(),
265 socket.getPort(), true);
266 sslSocket.setUseClientMode(false);
267 if (enabledCipherSuites != null) {
268 sslSocket.setEnabledCipherSuites(enabledCipherSuites);
269 }
270 if (enabledProtocols != null) {
271 sslSocket.setEnabledProtocols(enabledProtocols);
272 }
273 sslSocket.setNeedClientAuth(needClientAuth);
274 return sslSocket;
275 }
276 };
277 }
278
279 /**
280 * <p>Indicates whether some other object is "equal to" this one.</p>
281 *
282 * <p>Two <code>SslRMIServerSocketFactory</code> objects are equal
283 * if they have been constructed with the same SSL context and
284 * SSL socket configuration parameters.</p>
285 *
286 * <p>A subclass should override this method (as well as
287 * {@link #hashCode()}) if it adds instance state that affects
288 * equality.</p>
289 */
290 public boolean equals(Object obj) {
291 if (obj == null) return false;
292 if (obj == this) return true;
293 if (!(obj instanceof SslRMIServerSocketFactory))
294 return false;
295 SslRMIServerSocketFactory that = (SslRMIServerSocketFactory) obj;
296 return (getClass().equals(that.getClass()) && checkParameters(that));
297 }
298
299 private boolean checkParameters(SslRMIServerSocketFactory that) {
300 // SSL context
301 //
302 if (context == null ? that.context != null : !context.equals(that.context))
303 return false;
304
305 // needClientAuth flag
306 //
307 if (needClientAuth != that.needClientAuth)
308 return false;
309
310 // enabledCipherSuites
311 //
312 if ((enabledCipherSuites == null && that.enabledCipherSuites != null) ||
313 (enabledCipherSuites != null && that.enabledCipherSuites == null))
314 return false;
315 if (enabledCipherSuites != null && that.enabledCipherSuites != null) {
316 List<String> thatEnabledCipherSuitesList =
317 Arrays.asList(that.enabledCipherSuites);
318 if (!enabledCipherSuitesList.equals(thatEnabledCipherSuitesList))
319 return false;
320 }
321
322 // enabledProtocols
323 //
324 if ((enabledProtocols == null && that.enabledProtocols != null) ||
325 (enabledProtocols != null && that.enabledProtocols == null))
326 return false;
327 if (enabledProtocols != null && that.enabledProtocols != null) {
328 List<String> thatEnabledProtocolsList =
329 Arrays.asList(that.enabledProtocols);
330 if (!enabledProtocolsList.equals(thatEnabledProtocolsList))
331 return false;
332 }
333
334 return true;
335 }
336
337 /**
338 * <p>Returns a hash code value for this
339 * <code>SslRMIServerSocketFactory</code>.</p>
340 *
341 * @return a hash code value for this
342 * <code>SslRMIServerSocketFactory</code>.
343 */
344 public int hashCode() {
345 return getClass().hashCode() +
346 (context == null ? 0 : context.hashCode()) +
347 (needClientAuth ? Boolean.TRUE.hashCode() : Boolean.FALSE.hashCode()) +
348 (enabledCipherSuites == null ? 0 : enabledCipherSuitesList.hashCode()) +
349 (enabledProtocols == null ? 0 : enabledProtocolsList.hashCode());
350 }
351
352 // We use a static field because:
353 //
354 // SSLSocketFactory.getDefault() always returns the same object
355 // (at least on Sun's implementation), and we want to make sure
356 // that the Javadoc & the implementation stay in sync.
357 //
358 // If someone needs to have different SslRMIServerSocketFactory
359 // factories with different underlying SSLSocketFactory objects
360 // using different keystores and truststores, he/she can always
361 // use the constructor that takes an SSLContext as input.
362 //
363 private static SSLSocketFactory defaultSSLSocketFactory = null;
364
365 private static synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
366 if (defaultSSLSocketFactory == null)
367 defaultSSLSocketFactory =
368 (SSLSocketFactory) SSLSocketFactory.getDefault();
369 return defaultSSLSocketFactory;
370 }
371
372 private final String[] enabledCipherSuites;
373 private final String[] enabledProtocols;
374 private final boolean needClientAuth;
375 private List<String> enabledCipherSuitesList;
376 private List<String> enabledProtocolsList;
377 private SSLContext context;
378}