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+
26+package javax.rmi.ssl;
27+
28+import java.io.IOException;
29+import java.net.ServerSocket;
30+import java.net.Socket;
31+import java.rmi.server.RMIServerSocketFactory;
32+import java.util.Arrays;
33+import java.util.List;
34+import javax.net.ssl.SSLContext;
35+import javax.net.ssl.SSLServerSocketFactory;
36+import javax.net.ssl.SSLSocket;
37+import 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+ */
69+public 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+}