KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > components > net > JSSESocketFactory


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.axis.components.net;
17
18 import org.apache.axis.utils.Messages;
19 import org.apache.axis.utils.XMLUtils;
20 import org.apache.axis.utils.StringUtils;
21
22 import javax.net.ssl.SSLSocket;
23 import javax.net.ssl.SSLSocketFactory;
24 import java.io.BufferedWriter JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.OutputStream JavaDoc;
28 import java.io.OutputStreamWriter JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30 import java.net.Socket JavaDoc;
31 import java.util.Hashtable JavaDoc;
32
33
34 /**
35  * SSL socket factory. It _requires_ a valid RSA key and
36  * JSSE. (borrowed code from tomcat)
37  *
38  * THIS CODE STILL HAS DEPENDENCIES ON sun.* and com.sun.*
39  *
40  * @author Davanum Srinivas (dims@yahoo.com)
41  */

42 public class JSSESocketFactory extends DefaultSocketFactory implements SecureSocketFactory {
43
44     /** Field sslFactory */
45     protected SSLSocketFactory sslFactory = null;
46
47     /**
48      * Constructor JSSESocketFactory
49      *
50      * @param attributes
51      */

52     public JSSESocketFactory(Hashtable JavaDoc attributes) {
53         super(attributes);
54     }
55
56     /**
57      * Initialize the SSLSocketFactory
58      * @throws IOException
59      */

60     protected void initFactory() throws IOException JavaDoc {
61         sslFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
62     }
63     
64     /**
65      * creates a secure socket
66      *
67      * @param host
68      * @param port
69      * @param otherHeaders
70      * @param useFullURL
71      *
72      * @return Socket
73      * @throws Exception
74      */

75     public Socket create(
76             String JavaDoc host, int port, StringBuffer JavaDoc otherHeaders, BooleanHolder useFullURL)
77             throws Exception JavaDoc {
78         if (sslFactory == null) {
79             initFactory();
80         }
81         if (port == -1) {
82             port = 443;
83         }
84
85         TransportClientProperties tcp = TransportClientPropertiesFactory.create("https");
86
87         boolean hostInNonProxyList = isHostInNonProxyList(host, tcp.getNonProxyHosts());
88
89         Socket sslSocket = null;
90         if (tcp.getProxyHost().length() == 0 || hostInNonProxyList) {
91             // direct SSL connection
92
sslSocket = sslFactory.createSocket(host, port);
93         } else {
94
95             // Default proxy port is 80, even for https
96
int tunnelPort = (tcp.getProxyPort().length() != 0)
97                              ? Integer.parseInt(tcp.getProxyPort())
98                              : 80;
99             if (tunnelPort < 0)
100                 tunnelPort = 80;
101
102             // Create the regular socket connection to the proxy
103
Socket tunnel = new Socket(tcp.getProxyHost(), tunnelPort);
104
105             // The tunnel handshake method (condensed and made reflexive)
106
OutputStream JavaDoc tunnelOutputStream = tunnel.getOutputStream();
107             PrintWriter JavaDoc out = new PrintWriter JavaDoc(
108                     new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(tunnelOutputStream)));
109
110             // More secure version... engage later?
111
// PasswordAuthentication pa =
112
// Authenticator.requestPasswordAuthentication(
113
// InetAddress.getByName(tunnelHost),
114
// tunnelPort, "SOCK", "Proxy","HTTP");
115
// if(pa == null){
116
// printDebug("No Authenticator set.");
117
// }else{
118
// printDebug("Using Authenticator.");
119
// tunnelUser = pa.getUserName();
120
// tunnelPassword = new String(pa.getPassword());
121
// }
122
out.print("CONNECT " + host + ":" + port + " HTTP/1.0\r\n"
123                     + "User-Agent: AxisClient");
124             if (tcp.getProxyUser().length() != 0 &&
125                 tcp.getProxyPassword().length() != 0) {
126
127                 // add basic authentication header for the proxy
128
String JavaDoc encodedPassword = XMLUtils.base64encode((tcp.getProxyUser()
129                         + ":"
130                         + tcp.getProxyPassword()).getBytes());
131
132                 out.print("\nProxy-Authorization: Basic " + encodedPassword);
133             }
134             out.print("\nContent-Length: 0");
135             out.print("\nPragma: no-cache");
136             out.print("\r\n\r\n");
137             out.flush();
138             InputStream JavaDoc tunnelInputStream = tunnel.getInputStream();
139
140             if (log.isDebugEnabled()) {
141                 log.debug(Messages.getMessage("isNull00", "tunnelInputStream",
142                         "" + (tunnelInputStream
143                         == null)));
144             }
145             String JavaDoc replyStr = "";
146
147             // Make sure to read all the response from the proxy to prevent SSL negotiation failure
148
// Response message terminated by two sequential newlines
149
int newlinesSeen = 0;
150             boolean headerDone = false; /* Done on first newline */
151
152             while (newlinesSeen < 2) {
153                 int i = tunnelInputStream.read();
154
155                 if (i < 0) {
156                     throw new IOException JavaDoc("Unexpected EOF from proxy");
157                 }
158                 if (i == '\n') {
159                     headerDone = true;
160                     ++newlinesSeen;
161                 } else if (i != '\r') {
162                     newlinesSeen = 0;
163                     if (!headerDone) {
164                         replyStr += String.valueOf((char) i);
165                     }
166                 }
167             }
168             if (StringUtils.startsWithIgnoreWhitespaces("HTTP/1.0 200", replyStr) &&
169                     StringUtils.startsWithIgnoreWhitespaces("HTTP/1.1 200", replyStr)) {
170                 throw new IOException JavaDoc(Messages.getMessage("cantTunnel00",
171                         new String JavaDoc[]{
172                             tcp.getProxyHost(),
173                             "" + tunnelPort,
174                             replyStr}));
175             }
176
177             // End of condensed reflective tunnel handshake method
178
sslSocket = sslFactory.createSocket(tunnel, host, port, true);
179             if (log.isDebugEnabled()) {
180                 log.debug(Messages.getMessage("setupTunnel00",
181                           tcp.getProxyHost(),
182                         "" + tunnelPort));
183             }
184         }
185
186         ((SSLSocket) sslSocket).startHandshake();
187         if (log.isDebugEnabled()) {
188             log.debug(Messages.getMessage("createdSSL00"));
189         }
190         return sslSocket;
191     }
192 }
193
Popular Tags