001: // @(#)SConn.java 1.6 "@(#)SConn.java 1.6 99/09/23 Sun Microsystems"
002:
003: package com.sun.portal.netlet.eproxy;
004:
005: import java.io.IOException;
006: import java.net.InetAddress;
007: import java.net.ServerSocket;
008: import java.net.Socket;
009: import java.net.SocketException;
010: import java.net.UnknownHostException;
011: import java.util.StringTokenizer;
012: import java.util.logging.Level;
013: import java.util.logging.Logger;
014:
015: import org.mozilla.jss.ssl.SSLSocket;
016:
017: import com.sun.portal.log.common.PortalLogger;
018: import com.sun.portal.rproxy.configservlet.client.GatewayProfile;
019: import com.sun.portal.rproxy.connectionhandler.CachedSSLSocketFactory;
020: import com.sun.portal.rproxy.connectionhandler.CachedSocket;
021: import com.sun.portal.rproxy.connectionhandler.JSSProxyRunnable;
022: import com.sun.portal.rproxy.monitoring.MonitoringSubsystem;
023: import com.sun.portal.util.*;
024:
025: class SConn {
026: private static final String DEFAULT_SSL_PORT = "443";
027:
028: private static final String BLOCKED_SOCKET_TIMEOUT = "BlockedSocketTimeout";
029:
030: private static final int DEFAULT_SOCKET_TIMEOUT = 200000;
031:
032: private static String rpSubdomain;
033:
034: private static String rpDomain;
035:
036: // private static Logger logger =
037: // Logger.getLogger("com.sun.portal.sra.netlet");
038: private static Logger logger = PortalLogger.getLogger(SConn.class);
039:
040: static {
041: String _host = SystemProperties.get("gateway.host", null);
042:
043: String rphost = "https://" + _host + "/";
044:
045: if (rphost != null) {
046: int len = rphost.length();
047: int index1 = rphost.indexOf('.');
048: if (index1 != -1 && index1 + 1 < len) {
049: int index2 = rphost.indexOf('.', index1 + 1);
050: if (index2 == -1) {
051: rpSubdomain = rphost.substring(index1 + 1);
052: } else {
053: rpSubdomain = rphost.substring(index1 + 1, index2);
054: rpDomain = rphost.substring(index2);
055: }
056: }
057: }
058: }
059:
060: public static Socket connect(int p, String h) {
061:
062: Socket conn = null;
063: try {
064: conn = new Socket(h, p);
065: conn.setTcpNoDelay(true);
066: MonitoringSubsystem
067: .handleEvent(SRAEvent.PLAIN_SOCKET_CREATED);
068: } catch (UnknownHostException e) {
069: conn = null;
070: // logger.log(Level.SEVERE, "Cannot open connection to " + h + ":" +
071: // p, e);
072: Object[] params0 = { h, ":", p + "", e };
073: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX095", params0);
074: } catch (SocketException e) {
075: conn = null;
076: // logger.log(Level.SEVERE, "Cannot set tcpNoDelay on connection to
077: // " + h + ":" + p, e);
078: Object[] params1 = { h, ":", p + "", e };
079: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX096", params1);
080: } catch (IOException e) {
081: conn = null;
082: // logger.log(Level.SEVERE, "Cannot open connection to " + h + ":" +
083: // p, e);
084: Object[] params2 = { h, ":", p + "", e };
085: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX097", params2);
086: }
087:
088: return conn;
089: }
090:
091: public static Socket sslconnect(int p, String h) {
092: SSLSocket sslSocket = null;
093: /*
094: * SSLCertificateApprovalCallback approvalCallback = new
095: * TestCertApprovalCallback(); SSLClientCertificateSelectionCallback
096: * certSelectionCallback = new TestClientCertificateSelectionCallback();
097: * Socket js = new Socket(InetAddress.getByName(h), p); conn = new
098: * SSLSocket(js, h, approvalCallback, certSelectionCallback);
099: * //conn.requestClientAuth(false); conn.forceHandshake();
100: */
101: ServerCertApprovalCallback serverCertApprovalCB = null;
102: serverCertApprovalCB = ServerCertApprovalCallback.getInstance();
103: try {
104: sslSocket = new org.mozilla.jss.ssl.SSLSocket(InetAddress
105: .getByName(h), p, null, 0,
106: /* JSS3.1.1 change - begin */
107: // true,
108: /* JSS3.1.1 change - end */
109: serverCertApprovalCB, null);
110: } catch (Exception ex) {
111: // logger.log(Level.SEVERE, "Unable to create ssl Socket to Netlet
112: // proxy", ex);
113: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX098");
114: return null;
115: }
116: if (sslSocket == null) {
117: logger
118: .warning("SConn: Null socket returned. Probably couldn't resolve host.");
119: return null;
120: }
121: try {
122: sslSocket.setUseClientMode(true);
123: /**
124: * Bug 4740555 - Enable ciphers for SSL connection between Gateway &
125: * server
126: */
127: sslSocket.enableSSL2(true);
128: sslSocket.enableSSL3(true);
129: sslSocket.forceHandshake();
130: // End of code change for the bug 4740555
131: // Fix for #5003538, turn off SO_LINGER, SO_TIMEOUT so that the
132: // sockets do not remain open
133: // a long time when close is called on them.
134: sslSocket.setSoLinger(false, 0); // - Sandeep
135: int timeout = GatewayProfile.getInt(BLOCKED_SOCKET_TIMEOUT,
136: DEFAULT_SOCKET_TIMEOUT);
137: sslSocket.setSoTimeout(timeout * 1000);
138:
139: } catch (Exception e) {
140: // logger.log(Level.SEVERE, "CachedSSLSocketFactory socket error",
141: // e);
142: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX099");
143: }
144: return sslSocket;
145: }
146:
147: /*
148: * Added for RFE 4645450 ( Lihue Netlet PRD 2.2) @ Added bshankar@sun.com @
149: * parameters p = List of target Ports h = List of target Hosts Returns
150: * Socket if the socket connection can be established to the specified list
151: * of hosts/ports @ Returns null if the socket connection is not possible to
152: * the specified list of hosts/ports
153: */
154: public static Socket connect(String p, String h) {
155: Socket conn = null;
156:
157: StringTokenizer hosts = new StringTokenizer(h, "+");
158: StringTokenizer portlist = new StringTokenizer(p, "-");
159: int portlistLen = portlist.countTokens();
160:
161: if ((hosts.countTokens() == portlistLen) || (portlistLen == 1)) {
162: while (hosts.hasMoreElements() && conn == null) {
163: String strPorts = "";
164:
165: if (portlistLen == 1)
166: strPorts = p;
167: else
168: strPorts = (String) portlist.nextElement();
169:
170: StringTokenizer ports = new StringTokenizer(strPorts,
171: "+");
172: String host = (String) hosts.nextElement();
173:
174: while (ports.hasMoreElements() && conn == null) {
175: String strPort = (String) ports.nextElement();
176: int port = -999;
177: try {
178: port = Integer.parseInt(strPort);
179: } catch (NumberFormatException nfe) {
180: continue;
181: }
182:
183: try {
184: conn = new Socket(host, port);
185: conn.setTcpNoDelay(true);
186: MonitoringSubsystem
187: .handleEvent(SRAEvent.PLAIN_SOCKET_CREATED);
188: } catch (UnknownHostException e) {
189: conn = null;
190: Object[] param = { host, port + "", e };
191: logger.log(Level.SEVERE,
192: "PSSRNTLT_CSPNEPROX100", param);
193: } catch (SocketException e) {
194: conn = null;
195: // logger.log(Level.SEVERE, "Cannot set tcpNoDelay on
196: // connection to "
197: // "Cannot set tcpNoDelay on connection to " + host +
198: // ":" + port, e
199: Object[] param = { host, port + "", e };
200: logger.log(Level.SEVERE,
201: "PSSRNTLT_CSPNEPROX101");
202: } catch (IOException e) {
203: conn = null;
204: // logger.log(Level.SEVERE, "Cannot open connection to "
205: // +
206: Object[] param = { host, port + "", e };
207: logger.log(Level.SEVERE,
208: "PSSRNTLT_CSPNEPROX102");
209: }
210: }
211: }
212: } else // Rule format error
213: {
214: conn = null;
215: }
216: return conn;
217: }
218:
219: // //////////////////////////////////////////////////////////////////////////////
220: // ----- Proxy Tunnel Code--------
221: // //////////////////////////////////////////////////////////////////////////////
222: /*
223: *
224: */
225:
226: public static Socket sslProxyConnect(String host, int port,
227: String proxyHost, int proxyPort, int clientPort) {
228:
229: ServerSocket ss = null;
230: CachedSocket s = null;
231: Integer logId = null;
232:
233: Object tmp = GWLogManager.logIdMap.remove(new Integer(
234: clientPort));
235: if (tmp != null) {
236: LogInfoContainer info = (LogInfoContainer) tmp;
237: logId = info.getLogID();
238: }
239:
240: int jssProxyPort = -1;
241:
242: try {
243: ss = new ServerSocket(0, 50, InetAddress
244: .getByName("127.0.0.1"));
245: MonitoringSubsystem
246: .handleEvent(SRAEvent.SERVER_SOCKET_CREATED);
247:
248: } catch (IOException e) {
249: // logger.log(Level.SEVERE, "SConn: Unable to create server socket",
250: // e);
251: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX103");
252: ss = null;
253: }
254:
255: if (ss != null) {
256: jssProxyPort = ss.getLocalPort();
257: JSSProxyRunnable jssProxy = new JSSProxyRunnable(ss);
258: Thread t = new Thread(jssProxy);
259: t.start();
260: }
261:
262: ServerCertApprovalCallback serverCertApprovalCB = new ServerCertApprovalCallback(
263: host);
264:
265: s = CachedSSLSocketFactory.createSocket("127.0.0.1",
266: jssProxyPort, "ssl", logId, serverCertApprovalCB);
267: Integer localport = new Integer(s.getLocalPort());
268: ServiceReachabilityInfo sInfo = new ServiceReachabilityInfo(
269: host, port, proxyHost, proxyPort);
270: JSSProxyRunnable.connectHashMap.put(localport, sInfo);
271: // logger.info("SConn: Connecting to " + proxyHost);
272: Object[] params9 = { proxyHost };
273: logger.log(Level.INFO, "PSSRNTLT_CSPNEPROX104", params9);
274:
275: if (s == null) {
276: logger
277: .warning("SConn: Null socket returned. Probably couldn't resolve host.");
278: return null;
279: }
280:
281: try {
282: ForceSSLHandshake(host, s);
283: } catch (IOException e) {
284: s = null;
285: // logger.log(Level.SEVERE, "Cannot open connection to " +
286: Object[] params = { host, port + "", e };
287: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX105", params);
288: return null;
289: }
290:
291: return s.getSocket();
292: }
293:
294: /*
295: *
296: */
297:
298: private static void ForceSSLHandshake(String host, CachedSocket s)
299: throws IOException {
300: // this function will set currentReqHost. ReverseProxyTrustDecider.rptd
301: // isTrustedFor() will read it and determine if we are going to trust
302: // certificate signed by unknown CA
303: // currentReqHost will be either fully qualified host name or ip
304: String currentReqHost;
305:
306: synchronized (DEFAULT_SSL_PORT) {
307: String h = host;
308: if (h != null) {
309: StringTokenizer st = new StringTokenizer(h, ".");
310: int tokenCount = st.countTokens();
311: if (tokenCount == 1) {
312: currentReqHost = h + "." + rpSubdomain + rpDomain;
313: } else if (tokenCount == 2) {
314: currentReqHost = h + rpDomain;
315: } else {
316: currentReqHost = h;
317: }
318: } else {
319: currentReqHost = null;
320: }
321: try {
322: s.getOutputStream().write(new byte[0]);
323: } catch (IOException ex) {
324: currentReqHost = null;
325: throw ex;
326: }
327: currentReqHost = null;
328: }
329: }
330:
331: // ////////////////////////////////////////////////////////////////////
332: public static Socket proxyConnect(String host, int port,
333: String proxyHost, int proxyPort) {
334:
335: ServerSocket ss = null;
336: Socket s = null;
337:
338: int jssProxyPort = -1;
339:
340: try {
341: ss = new ServerSocket(0, 50, InetAddress
342: .getByName("127.0.0.1"));
343: MonitoringSubsystem
344: .handleEvent(SRAEvent.SERVER_SOCKET_CREATED);
345: } catch (IOException e) {
346: // logger.log(Level.SEVERE, "SConn: Unable to create server socket",
347: // e);
348: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX106");
349: ss = null;
350: }
351:
352: if (ss != null) {
353: jssProxyPort = ss.getLocalPort();
354: JSSProxyRunnable jssProxy = new JSSProxyRunnable(ss);
355: Thread t = new Thread(jssProxy);
356: t.start();
357: }
358:
359: try {
360: s = new Socket("127.0.0.1", jssProxyPort);
361: s.setTcpNoDelay(true);
362: MonitoringSubsystem
363: .handleEvent(SRAEvent.PLAIN_SOCKET_CREATED);
364: } catch (UnknownHostException e) {
365: s = null;
366: // logger.log(Level.SEVERE, "Cannot open connection to " + host +
367: // ":"
368: Object[] params = { host, port + "", e };
369: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX107", params);
370: } catch (SocketException e) {
371: s = null;
372: // logger.log(Level.SEVERE, "Cannot set tcpNoDelay on connection to
373: // " +.
374: Object[] params = { host, port + "", e };
375: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX108", params);
376: } catch (IOException e) {
377: s = null;
378: // logger.log(Level.SEVERE, "Cannot open connection to " +
379: Object[] params = { host, port + "", e };
380: logger.log(Level.SEVERE, "PSSRNTLT_CSPNEPROX109", params);
381: }
382:
383: Integer localport = new Integer(s.getLocalPort());
384: ServiceReachabilityInfo sInfo = new ServiceReachabilityInfo(
385: host, port, proxyHost, proxyPort);
386: JSSProxyRunnable.connectHashMap.put(localport, sInfo);
387:
388: // logger.info("SConn: Connecting to " + proxyHost);
389: Object[] params15 = { proxyHost };
390: logger.log(Level.INFO, "PSSRNTLT_CSPNEPROX110", params15);
391:
392: if (s == null) {
393: logger
394: .warning("SConn: Null socket returned. Probably couldn't resolve host.");
395: return null;
396: }
397:
398: return s;
399: }
400: // ///////////////////////////////////////////////////////////////////
401: }
|