001: /*
002: * $Id: HTTPSRetriever.java,v 1.15 2005/03/01 10:30:36 np145014 Exp $
003: * $Source: /m/portal/ps/srap/src/com/sun/portal/rproxy/connectionhandler/HTTPSRetriever.java,v $
004: * $Log: HTTPSRetriever.java,v $
005: * Revision 1.15 2005/03/01 10:30:36 np145014
006: * CR 6224556
007: *
008: * Revision 1.14 2005/03/01 10:17:24 np145014
009: * CR 6224556
010: *
011: * Revision 1.13 2005/02/25 09:44:13 ss150821
012: * RFE 6223490 - SRA Should use JDK based logging, changed to start throwing the full stacktrace for the exception in the logs
013: *
014: * Revision 1.12 2005/02/24 07:36:44 ss150821
015: * RFE 6223490 - SRA Should use JDK based logging
016: *
017: * Revision 1.11 2005/02/23 09:15:05 ss150821
018: * RFE 6223490 - SRA Should use JDK based logging
019: *
020: * Revision 1.10 2004/07/27 12:55:01 vt126379
021: * RFE#5075809, CRT#99
022: *
023: * Revision 1.9 2003/11/27 12:39:46 mm132998
024: * Restructuring and changes for PS-IS seperation
025: *
026: * Revision 1.8 2003/07/30 11:35:14 mm132998
027: * 4878523
028: *
029: * Revision 1.7 2003/06/10 12:23:08 mm132998
030: * Bug : 4875896 , Fix for opening ServerSockets only to 127.0.0.1
031: *
032: * Revision 1.6 2003/06/09 07:11:21 mm132998
033: * Bugs 4818006 , 4389707
034: *
035: * Revision 1.5 2003/05/26 10:30:47 rt130506
036: * Netlet- ProxyTunnel
037: *
038: * Revision 1.4 2002/08/21 10:36:32 ss133690
039: * Bug 4710658
040: *
041: * Revision 1.3 2002/08/16 15:13:06 bv131302
042: * Hana CRT#1888 - Check log settings before logging
043: *
044: * Revision 1.2 2002/06/21 13:04:14 bv131302
045: * LDAP Attribute name changes
046: *
047: * Revision 1.1 2002/06/14 09:53:52 rt130506
048: * SRAP rebranding
049: *
050: * Revision 1.7 2002/06/12 07:55:58 bv131302
051: * more rebranding - filenames
052: *
053: * Revision 1.6 2002/06/11 16:02:03 bv131302
054: * new branded
055: *
056: * Revision 1.5 2002/05/13 06:22:24 mm132998
057: * Perf related modifications
058: *
059: * Revision 1.4 2002/03/04 06:23:17 mm132998
060: * Bug ID : # 4618949 , CRT : # 416 , Desc : Gateway should pass through Authentication headers when the scheme is not Basic.
061: *
062: * Revision 1.3 2002/02/26 11:02:08 mm132998
063: * Bug ID : 4643126 CRT : 368 Desc: Lihue PRD 7.4.3
064: *
065: *
066: */
067: /*
068: * HTTPSRetriever.java
069: *
070: * $Author: np145014 $
071: *
072: * $Date: 2005/03/01 10:30:36 $ $Revision: 1.15 $
073: *
074: * Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
075: *
076: * Developed by SunPS and SunIR
077: */
078:
079: package com.sun.portal.rproxy.connectionhandler;
080:
081: import java.io.IOException;
082: import java.net.InetAddress;
083: import java.net.ServerSocket;
084: import java.util.StringTokenizer;
085: import java.util.logging.Level;
086: import java.util.logging.Logger;
087:
088: import com.sun.portal.log.common.PortalLogger;
089: import com.sun.portal.rproxy.configservlet.client.GatewayProfile;
090: import com.sun.portal.rproxy.monitoring.MonitoringSubsystem;
091: import com.sun.portal.util.*;
092:
093: /**
094: * This class retrieves objects using the HTTPS protocol.
095: *
096: * @author Gabriel Lawrence
097: */
098: // JP_Declaration HTTPSRetriever 193
099: public class HTTPSRetriever extends HTTPRetriever {
100:
101: private static final String DEFAULT_SSL_PORT = "443";
102:
103: public static String currentReqHost;
104:
105: private static String rpSubdomain;
106:
107: private static String rpDomain;
108:
109: public static int jssProxyPort = -1;
110:
111: private static boolean doBasicAuthentication = false;
112:
113: // private static Logger logger =
114: // Logger.getLogger("com.sun.portal.sra.rproxy");
115: private static Logger logger = PortalLogger
116: .getLogger(HTTPSRetriever.class);
117:
118: static {
119: String _host = SystemProperties.get("gateway.host", null);
120:
121: String rphost = "https://" + _host + "/";
122:
123: if (rphost != null) {
124: int len = rphost.length();
125: int index1 = rphost.indexOf('.');
126: if (index1 != -1 && index1 + 1 < len) {
127: int index2 = rphost.indexOf('.', index1 + 1);
128: if (index2 == -1) {
129: rpSubdomain = rphost.substring(index1 + 1);
130: } else {
131: rpSubdomain = rphost.substring(index1 + 1, index2);
132: rpDomain = rphost.substring(index2);
133: }
134: }
135: }
136:
137: ServerSocket ss = null;
138:
139: try {
140: ss = new ServerSocket(0, 50, InetAddress
141: .getByName("127.0.0.1"));
142: MonitoringSubsystem
143: .handleEvent(SRAEvent.SERVER_SOCKET_CREATED);
144: } catch (IOException e) {
145: // logger.log(Level.SEVERE, "HTTPSRetriever: Unable to create server
146: // socket", e);
147: logger.log(Level.SEVERE, "PSSRRPROXY_CSPRCONHNDLR085", e);
148: ss = null;
149: }
150:
151: if (ss != null) {
152: jssProxyPort = ss.getLocalPort();
153: JSSProxyRunnable jssProxy = new JSSProxyRunnable(ss);
154: Thread t = new Thread(jssProxy);
155: t.start();
156: }
157: doBasicAuthentication = GatewayProfile.getBoolean(
158: "DoBasicAuthentication", false)
159: && ServiceIdentifier.isGateway();
160: }
161:
162: // JP_Operation getServerCertificate() 127
163: public byte[] getServerCertificate() {
164: return null;
165: }
166:
167: /***************************************************************************
168: * 4507848 SSL and cert auth does not work together
169: */
170: public Response getResponse2(Request req, String destinationHost,
171: Integer logId, byte[] param) {
172: CachedSocket s = null;
173: CSBufferedInputStream in = null;
174:
175: String password = null;
176: boolean found_pw = false;
177:
178: if (doBasicAuthentication) {
179: password = req.getRequestHeader("Authorization");
180:
181: if (password == null) {
182: found_pw = BasicAuthentication.getPassword(req,
183: destinationHost);
184: }
185: // Lihue Bug ID - 4618949
186: else {
187: String basic = password.substring(
188: password.indexOf(':') + 1).trim();
189: if (!basic.regionMatches(true, 0, "basic ", 0, 5)) {
190: password = null;
191: }
192: }
193: // EOC : Lihue Bug ID - 4618949
194: }
195: // Lihue PRD : 7.4.3.2
196: if (req.getUseProxy()) {
197: String prxyhost = req.getProxyHost();
198: String headerProxyAuth = req
199: .getRequestHeader("Proxy-Authorization");
200:
201: if (headerProxyAuth == null) {
202: String proxy_passwd = DomainWebProxyConfig
203: .getProxyPassword(prxyhost);
204: if (proxy_passwd != null) {
205: req.setRequestHeader("Proxy-Authorization",
206: "Proxy-Authorization: Basic "
207: + proxy_passwd);
208: }
209: }
210: }
211: // End of Code - Lihue PRD : 7.4.3.2
212:
213: Response result = null;
214: try {
215: result = new HTTPResponse();
216: // logger.info("HTTPSRetriever retrieving " + req);
217: Object[] params1 = { req };
218: logger.log(Level.INFO, "PSSRRPROXY_CSPRCONHNDLR086",
219: params1);
220:
221: if (req.getUseProxy()) {
222: ServerCertApprovalCallback serverCertApprovalCB = new ServerCertApprovalCallback(
223: req.getHost());
224:
225: s = CachedSSLSocketFactory.createSocket("127.0.0.1",
226: jssProxyPort, "ssl", logId,
227: serverCertApprovalCB);
228: Integer localport = new Integer(s.getLocalPort());
229: ServiceReachabilityInfo sInfo = new ServiceReachabilityInfo(
230: req.getHost(), Integer.parseInt(req.getPort()),
231: req.getProxyHost(), req.getProxyPort());
232: JSSProxyRunnable.connectHashMap.put(localport, sInfo);
233: // logger.info("HTTPSRetriever: Connecting to " +
234: // req.getProxyHost());
235: Object[] params2 = { req.getProxyHost() };
236: logger.log(Level.INFO, "PSSRRPROXY_CSPRCONHNDLR087",
237: params2);
238: } else {
239: ServerCertApprovalCallback serverCertApprovalCB = null;
240: serverCertApprovalCB = ServerCertApprovalCallback
241: .getInstance();
242: s = CachedSSLSocketFactory.createSocket(req.getHost(),
243: Integer.parseInt(req.getPort()), "ssl", logId,
244: serverCertApprovalCB);
245: // logger.info("HTTPSRetriever: Connecting to: " +
246: // req.getHost());
247: Object[] params3 = { req.getHost() };
248: logger.log(Level.INFO, "PSSRRPROXY_CSPRCONHNDLR088",
249: params3);
250: }
251:
252: if (s == null) {
253: logger
254: .warning("HTTPRetriever: Null socket returned. Probably couldn't resolve host.");
255: return null;
256: }
257:
258: ForceSSLHandshake(req, s);
259: try {
260: sendRequest2(req, s, param);
261: in = s.getInputStream();
262: getResponseHeader((HTTPResponse) result, in, req);
263: } catch (Exception e) {
264: // create a new socket
265: if (req.getUseProxy()) {
266: ServerCertApprovalCallback serverCertApprovalCB = new ServerCertApprovalCallback(
267: req.getHost());
268:
269: s = CachedSSLSocketFactory.createSocket(
270: "127.0.0.1", jssProxyPort, "ssl", logId,
271: serverCertApprovalCB);
272: Integer localport = new Integer(s.getLocalPort());
273: ServiceReachabilityInfo sInfo = new ServiceReachabilityInfo(
274: req.getHost(), Integer.parseInt(req
275: .getPort()), req.getProxyHost(),
276: req.getProxyPort());
277: JSSProxyRunnable.connectHashMap.put(localport,
278: sInfo);
279: // logger.info("HTTPSRetriever: Connecting to " +
280: // req.getProxyHost());
281: Object[] params4 = { req.getProxyHost() };
282: logger.log(Level.INFO,
283: "PSSRRPROXY_CSPRCONHNDLR089", params4);
284: } else {
285: ServerCertApprovalCallback serverCertApprovalCB = null;
286: serverCertApprovalCB = ServerCertApprovalCallback
287: .getInstance();
288: s = CachedSSLSocketFactory.createSocket(req
289: .getHost(),
290: Integer.parseInt(req.getPort()), "ssl",
291: logId, serverCertApprovalCB);
292: // logger.info("HTTPSRetriever: Connecting to: " +
293: // req.getHost());
294: Object[] params5 = { req.getHost() };
295: logger.log(Level.INFO,
296: "PSSRRPROXY_CSPRCONHNDLR090", params5);
297: }
298: sendRequest2(req, s, param);
299: in = s.getInputStream();
300: getResponseHeader((HTTPResponse) result, in, req);
301: }
302: if (doBasicAuthentication) {
303: if (result.getStatusCode().compareTo("401") != 0
304: && result.getStatusCode().compareTo("403") != 0) {
305: if (password != null) {
306: BasicAuthentication.storePassword(req,
307: destinationHost);
308: }
309: }
310: }
311:
312: // Get content length from response header. If not known then set it
313: // to the number of available bytes in the stream.
314: String cl = result.getResponseHeader("content-length");
315: int length = 0;
316: if (cl != null) {
317: length = Integer.parseInt(cl.substring(
318: cl.indexOf(':') + 1).trim());
319: } else {
320: length = -1; // indicates length is unknown
321: }
322:
323: /*
324: * //Look for a keep-alive timeout value to use for socket timeout
325: * //value String ka = result.getResponseHeader("keep-alive"); if
326: * (ka != null) { int to =
327: * Integer.parseInt(ka.substring(ka.indexOf("timeout=")+8,
328: * ka.indexOf(','))); if (to > 0) s.setTimeout(to); } // Check if
329: * socket is to be closed after buffer has been read. if
330: * (result.getResponseHeader("Connection: close") != null)
331: * in.setClosed(); else in.setKeepAlive();
332: */
333: in.setClosed();
334:
335: // Set the content stream with the CachedSocket and set buffer
336: // length. Length is number of bytes or -1 if unknown
337: ((CSBufferedInputStream) in).setLength(length);
338: ((HTTPResponse) result).setContentStream(in);
339: result.setSocket(s);
340: } catch (Exception ex) {
341: // logger.log(Level.SEVERE, "HTTPRetriever failed", ex);
342: logger.log(Level.SEVERE, "PSSRRPROXY_CSPRCONHNDLR091", ex);
343: result = null;
344: /**
345: * Bug 4710658
346: */
347: if (s != null) {
348: try {
349: s.close();
350: } catch (IOException e) {
351: }
352: }
353: // End of code change for Bug 4710658
354:
355: }
356: if (result != null)
357: result.setSocket(s);
358: return result;
359: }
360:
361: // End of change of code for the bug 4507848
362:
363: /**
364: * Get a response for a specific Request
365: */
366: public Response getResponse(Request req, String destinationHost,
367: Integer logId) {
368: CachedSocket s = null;
369: CSBufferedInputStream in = null;
370:
371: String password = null;
372: boolean found_pw = false;
373:
374: if (doBasicAuthentication) {
375: password = req.getRequestHeader("Authorization");
376:
377: if (password == null) {
378: found_pw = BasicAuthentication.getPassword(req,
379: destinationHost);
380: }
381: // Lihue Bug ID - 4618949
382: else {
383: String basic = password.substring(
384: password.indexOf(':') + 1).trim();
385: if (!basic.regionMatches(true, 0, "basic ", 0, 5)) {
386: password = null;
387: }
388: }
389: // EOC : Lihue Bug ID - 4618949
390: }
391: // Lihue PRD : 7.4.3.2
392: if (req.getUseProxy()) {
393: String prxyhost = req.getProxyHost();
394: String headerProxyAuth = req
395: .getRequestHeader("Proxy-Authorization");
396:
397: if (headerProxyAuth == null) {
398: String proxy_passwd = DomainWebProxyConfig
399: .getProxyPassword(prxyhost);
400: if (proxy_passwd != null) {
401: req.setRequestHeader("Proxy-Authorization",
402: "Proxy-Authorization: Basic "
403: + proxy_passwd);
404: }
405: }
406: }
407: // End of Code - Lihue PRD : 7.4.3.2
408:
409: Response result = null;
410: try {
411: result = new HTTPResponse();
412: // logger.info("HTTPSRetriever: AttemptRetrieve " + req);
413: Object[] params7 = { req };
414: logger.log(Level.INFO, "PSSRRPROXY_CSPRCONHNDLR092",
415: params7);
416:
417: if (req.getUseProxy()) {
418: ServerCertApprovalCallback serverCertApprovalCB = new ServerCertApprovalCallback(
419: req.getHost());
420:
421: s = CachedSSLSocketFactory.createSocket("127.0.0.1",
422: jssProxyPort, "ssl", logId,
423: serverCertApprovalCB);
424: Integer localport = new Integer(s.getLocalPort());
425: ServiceReachabilityInfo sInfo = new ServiceReachabilityInfo(
426: req.getHost(), Integer.parseInt(req.getPort()),
427: req.getProxyHost(), req.getProxyPort());
428: JSSProxyRunnable.connectHashMap.put(localport, sInfo);
429:
430: // logger.info("HTTPSRetriever: Connecting to " +
431: // req.getProxyHost());
432: Object[] params8 = { req.getProxyHost() };
433: logger.log(Level.INFO, "PSSRRPROXY_CSPRCONHNDLR093",
434: params8);
435: } else {
436: ServerCertApprovalCallback serverCertApprovalCB = null;
437: serverCertApprovalCB = ServerCertApprovalCallback
438: .getInstance();
439: s = CachedSSLSocketFactory.createSocket(req.getHost(),
440: Integer.parseInt(req.getPort()), "ssl", logId,
441: serverCertApprovalCB);
442:
443: // logger.info("HTTPSRetriever: Connecting to: " +
444: // req.getHost());
445: Object[] params9 = { req.getHost() };
446: logger.log(Level.INFO, "PSSRRPROXY_CSPRCONHNDLR094",
447: params9);
448: }
449:
450: if (s == null) {
451: logger
452: .warning("HTTPSRetriever: Null socket returned. Probably couldn't resolve host.");
453: return null;
454: }
455:
456: ForceSSLHandshake(req, s);
457:
458: try {
459: sendRequest(req, s);
460: in = s.getInputStream();
461: getResponseHeader((HTTPResponse) result, in, req);
462: } catch (Exception e) {
463: // logger.log(Level.SEVERE, "Exception while sending
464: // request/retrieving response", e);
465: logger.log(Level.SEVERE, "PSSRRPROXY_CSPRCONHNDLR095",
466: e);
467: // e.printStackTrace();
468: return null;
469:
470: }
471: if (doBasicAuthentication) {
472: if (result.getStatusCode().compareTo("401") != 0
473: && result.getStatusCode().compareTo("403") != 0) {
474: if (password != null) {
475: BasicAuthentication.storePassword(req,
476: destinationHost);
477: }
478: }
479: }
480:
481: // Get content length from response header. If not known then set it
482: // to the number of available bytes in the stream.
483: String cl = result.getResponseHeader("content-length");
484: int length = 0;
485: if (cl != null) {
486: length = Integer.parseInt(cl.substring(
487: cl.indexOf(':') + 1).trim());
488: } else {
489: length = -1; // indicates length is unknown
490: }
491:
492: /*
493: * //Look for a keep-alive timeout value to use for socket timeout
494: * value String ka = result.getResponseHeader("keep-alive"); if (ka !=
495: * null) { int to =
496: * Integer.parseInt(ka.substring(ka.indexOf("timeout=")+8,
497: * ka.indexOf(','))); if (to > 0) s.setTimeout(to); } // Check if
498: * socket is to be closed after buffer has been read. if
499: * (result.getResponseHeader("Connection: close") != null)
500: * in.setClosed(); else in.setKeepAlive();
501: */
502: in.setClosed();
503:
504: // Set the content stream with the CachedSocket and set buffer
505: // length.
506: // Length is number of bytes or -1 if unknown
507: ((CSBufferedInputStream) in).setLength(length);
508: ((HTTPResponse) result).setContentStream(in);
509: result.setSocket(s);
510: } catch (Exception ex) {
511: // logger.log(Level.SEVERE, "HTTPSRetriever: ErrorRetrieve " + req,
512: // ex);
513: Object[] params11 = { req, ex };
514: logger.log(Level.SEVERE, "PSSRRPROXY_CSPRCONHNDLR096",
515: params11);
516: // ex.printStackTrace();
517:
518: result = null;
519: /**
520: * Bug 4710658
521: */
522: if (s != null) {
523: try {
524: s.close();
525: } catch (IOException e) {
526: }
527: }
528: // End of code change for Bug 4710658
529: }
530: if (result != null)
531: result.setSocket(s);
532: return result;
533: }
534:
535: public void ForceSSLHandshake(Request req, CachedSocket s)
536: throws IOException {
537: // this function will set currentReqHost. ReverseProxyTrustDecider.rptd
538: // isTrustedFor() will read it and determine if we are going to trust
539: // certificate signed by unknown CA
540: // currentReqHost will be either fully qualified host name or ip
541:
542: synchronized (DEFAULT_SSL_PORT) {
543: String h = req.getHost();
544: if (h != null) {
545: StringTokenizer st = new StringTokenizer(h, ".");
546: int tokenCount = st.countTokens();
547: if (tokenCount == 1) {
548: currentReqHost = h + "." + rpSubdomain + rpDomain;
549: } else if (tokenCount == 2) {
550: currentReqHost = h + rpDomain;
551: } else {
552: currentReqHost = h;
553: }
554: } else {
555: currentReqHost = null;
556: }
557: try {
558: s.getOutputStream().write(new byte[0]);
559: } catch (IOException ex) {
560: currentReqHost = null;
561: throw ex;
562: }
563: currentReqHost = null;
564: }
565: }
566: }
|