xref: /trunk/main/swext/mediawiki/src/com/sun/star/wiki/WikiSession.java (revision 33efb51f76a78baf5a276c335781687d66cf274a)
1*33efb51fSJim Jagielski /**************************************************************
2*33efb51fSJim Jagielski  *
3*33efb51fSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*33efb51fSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*33efb51fSJim Jagielski  * distributed with this work for additional information
6*33efb51fSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*33efb51fSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*33efb51fSJim Jagielski  * "License"); you may not use this file except in compliance
9*33efb51fSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*33efb51fSJim Jagielski  *
11*33efb51fSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*33efb51fSJim Jagielski  *
13*33efb51fSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*33efb51fSJim Jagielski  * software distributed under the License is distributed on an
15*33efb51fSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*33efb51fSJim Jagielski  * KIND, either express or implied.  See the License for the
17*33efb51fSJim Jagielski  * specific language governing permissions and limitations
18*33efb51fSJim Jagielski  * under the License.
19*33efb51fSJim Jagielski  *
20*33efb51fSJim Jagielski  *************************************************************/
21*33efb51fSJim Jagielski 
22*33efb51fSJim Jagielski 
23*33efb51fSJim Jagielski 
24*33efb51fSJim Jagielski package com.sun.star.wiki;
25*33efb51fSJim Jagielski 
26*33efb51fSJim Jagielski import com.sun.star.uno.XComponentContext;
27*33efb51fSJim Jagielski import java.io.ByteArrayInputStream;
28*33efb51fSJim Jagielski import java.io.ByteArrayOutputStream;
29*33efb51fSJim Jagielski import java.io.IOException;
30*33efb51fSJim Jagielski import java.io.InputStream;
31*33efb51fSJim Jagielski import java.io.OutputStream;
32*33efb51fSJim Jagielski import java.io.UnsupportedEncodingException;
33*33efb51fSJim Jagielski import java.net.CookieManager;
34*33efb51fSJim Jagielski import java.net.CookiePolicy;
35*33efb51fSJim Jagielski import java.net.HttpURLConnection;
36*33efb51fSJim Jagielski import java.net.Proxy;
37*33efb51fSJim Jagielski import java.net.URISyntaxException;
38*33efb51fSJim Jagielski import java.net.URL;
39*33efb51fSJim Jagielski import java.net.URLEncoder;
40*33efb51fSJim Jagielski import java.security.KeyStore;
41*33efb51fSJim Jagielski import java.security.cert.CertificateException;
42*33efb51fSJim Jagielski import java.security.cert.X509Certificate;
43*33efb51fSJim Jagielski import java.util.HashMap;
44*33efb51fSJim Jagielski import java.util.List;
45*33efb51fSJim Jagielski import java.util.Map;
46*33efb51fSJim Jagielski import javax.net.ssl.HttpsURLConnection;
47*33efb51fSJim Jagielski import javax.net.ssl.SSLContext;
48*33efb51fSJim Jagielski import javax.net.ssl.SSLSocketFactory;
49*33efb51fSJim Jagielski import javax.net.ssl.TrustManager;
50*33efb51fSJim Jagielski import javax.net.ssl.TrustManagerFactory;
51*33efb51fSJim Jagielski import javax.net.ssl.X509TrustManager;
52*33efb51fSJim Jagielski import javax.xml.parsers.DocumentBuilder;
53*33efb51fSJim Jagielski import javax.xml.parsers.DocumentBuilderFactory;
54*33efb51fSJim Jagielski import org.w3c.dom.Document;
55*33efb51fSJim Jagielski import org.w3c.dom.Element;
56*33efb51fSJim Jagielski import org.w3c.dom.NodeList;
57*33efb51fSJim Jagielski 
58*33efb51fSJim Jagielski /** An HTTP session with one MediaWiki server, talking to its Action API (api.php). */
59*33efb51fSJim Jagielski public class WikiSession
60*33efb51fSJim Jagielski {
61*33efb51fSJim Jagielski     public static class Response
62*33efb51fSJim Jagielski     {
63*33efb51fSJim Jagielski         public int m_nStatus;
64*33efb51fSJim Jagielski         public String m_sBody;
65*33efb51fSJim Jagielski         public URL m_aURL;
66*33efb51fSJim Jagielski     }
67*33efb51fSJim Jagielski 
68*33efb51fSJim Jagielski     private static final int MAX_REDIRECTS = 10;
69*33efb51fSJim Jagielski     private static final int CONNECT_TIMEOUT_MS = 30000;
70*33efb51fSJim Jagielski     private static final String USER_AGENT = "Apache-OpenOffice-Wiki-Publisher";
71*33efb51fSJim Jagielski 
72*33efb51fSJim Jagielski     private static SSLSocketFactory m_aUnknownCertSocketFactory;
73*33efb51fSJim Jagielski 
74*33efb51fSJim Jagielski     private XComponentContext m_xContext;
75*33efb51fSJim Jagielski     private URL m_aMainURL;
76*33efb51fSJim Jagielski     // not CookieHandler.setDefault(): that would be shared by everything in the office JVM
77*33efb51fSJim Jagielski     private CookieManager m_aCookies = new CookieManager( null, CookiePolicy.ACCEPT_ORIGINAL_SERVER );
78*33efb51fSJim Jagielski 
WikiSession( XComponentContext xContext, URL aMainURL )79*33efb51fSJim Jagielski     public WikiSession( XComponentContext xContext, URL aMainURL )
80*33efb51fSJim Jagielski     {
81*33efb51fSJim Jagielski         m_xContext = xContext;
82*33efb51fSJim Jagielski         m_aMainURL = aMainURL;
83*33efb51fSJim Jagielski     }
84*33efb51fSJim Jagielski 
GetMainURL()85*33efb51fSJim Jagielski     public URL GetMainURL()
86*33efb51fSJim Jagielski     {
87*33efb51fSJim Jagielski         return m_aMainURL;
88*33efb51fSJim Jagielski     }
89*33efb51fSJim Jagielski 
Get( URL aURL )90*33efb51fSJim Jagielski     public Response Get( URL aURL )
91*33efb51fSJim Jagielski         throws IOException, WikiCancelException
92*33efb51fSJim Jagielski     {
93*33efb51fSJim Jagielski         for ( int nRedirect = 0; ; nRedirect++ )
94*33efb51fSJim Jagielski         {
95*33efb51fSJim Jagielski             HttpURLConnection aConn = Open( aURL );
96*33efb51fSJim Jagielski             Response aResponse = Execute( aConn, aURL, null );
97*33efb51fSJim Jagielski             int nStatus = aResponse.m_nStatus;
98*33efb51fSJim Jagielski             String sLocation = aConn.getHeaderField( "Location" );
99*33efb51fSJim Jagielski             if ( nStatus < 300 || nStatus > 399 || sLocation == null || nRedirect >= MAX_REDIRECTS )
100*33efb51fSJim Jagielski                 return aResponse;
101*33efb51fSJim Jagielski 
102*33efb51fSJim Jagielski             aURL = new URL( aURL, sLocation );
103*33efb51fSJim Jagielski         }
104*33efb51fSJim Jagielski     }
105*33efb51fSJim Jagielski 
Post( URL aURL, String[][] pParams )106*33efb51fSJim Jagielski     public Response Post( URL aURL, String[][] pParams )
107*33efb51fSJim Jagielski         throws IOException, WikiCancelException
108*33efb51fSJim Jagielski     {
109*33efb51fSJim Jagielski         StringBuilder aBody = new StringBuilder();
110*33efb51fSJim Jagielski         for ( int nInd = 0; nInd < pParams.length; nInd++ )
111*33efb51fSJim Jagielski         {
112*33efb51fSJim Jagielski             if ( pParams[nInd] == null || pParams[nInd][0] == null || pParams[nInd][1] == null )
113*33efb51fSJim Jagielski                 continue;
114*33efb51fSJim Jagielski             if ( aBody.length() > 0 )
115*33efb51fSJim Jagielski                 aBody.append( '&' );
116*33efb51fSJim Jagielski             aBody.append( URLEncoder.encode( pParams[nInd][0], "UTF-8" ) );
117*33efb51fSJim Jagielski             aBody.append( '=' );
118*33efb51fSJim Jagielski             aBody.append( URLEncoder.encode( pParams[nInd][1], "UTF-8" ) );
119*33efb51fSJim Jagielski         }
120*33efb51fSJim Jagielski 
121*33efb51fSJim Jagielski         HttpURLConnection aConn = Open( aURL );
122*33efb51fSJim Jagielski         aConn.setRequestMethod( "POST" );
123*33efb51fSJim Jagielski         aConn.setDoOutput( true );
124*33efb51fSJim Jagielski         aConn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" );
125*33efb51fSJim Jagielski         return Execute( aConn, aURL, aBody.toString().getBytes( "UTF-8" ) );
126*33efb51fSJim Jagielski     }
127*33efb51fSJim Jagielski 
128*33efb51fSJim Jagielski     /** Calls api.php; HTTP errors and non-XML answers throw, API-level errors are left in the returned document. */
CallAPI( String[][] pParams )129*33efb51fSJim Jagielski     public Document CallAPI( String[][] pParams )
130*33efb51fSJim Jagielski         throws IOException, WikiCancelException
131*33efb51fSJim Jagielski     {
132*33efb51fSJim Jagielski         String[][] pAllParams = new String[pParams.length + 1][];
133*33efb51fSJim Jagielski         pAllParams[0] = new String[] { "format", "xml" };
134*33efb51fSJim Jagielski         System.arraycopy( pParams, 0, pAllParams, 1, pParams.length );
135*33efb51fSJim Jagielski 
136*33efb51fSJim Jagielski         Response aResponse = Post( new URL( m_aMainURL, "api.php" ), pAllParams );
137*33efb51fSJim Jagielski         if ( aResponse.m_nStatus != 200 )
138*33efb51fSJim Jagielski             throw new IOException( "MediaWiki API request failed with HTTP status " + aResponse.m_nStatus );
139*33efb51fSJim Jagielski 
140*33efb51fSJim Jagielski         try
141*33efb51fSJim Jagielski         {
142*33efb51fSJim Jagielski             DocumentBuilderFactory aFactory = DocumentBuilderFactory.newInstance();
143*33efb51fSJim Jagielski             aFactory.setFeature( "http://apache.org/xml/features/disallow-doctype-decl", true );
144*33efb51fSJim Jagielski             aFactory.setExpandEntityReferences( false );
145*33efb51fSJim Jagielski             DocumentBuilder aBuilder = aFactory.newDocumentBuilder();
146*33efb51fSJim Jagielski             Document aDoc = aBuilder.parse( new ByteArrayInputStream( aResponse.m_sBody.getBytes( "UTF-8" ) ) );
147*33efb51fSJim Jagielski             if ( !"api".equals( aDoc.getDocumentElement().getTagName() ) )
148*33efb51fSJim Jagielski                 throw new IOException( "Not a MediaWiki API response" );
149*33efb51fSJim Jagielski             return aDoc;
150*33efb51fSJim Jagielski         }
151*33efb51fSJim Jagielski         catch ( IOException e )
152*33efb51fSJim Jagielski         {
153*33efb51fSJim Jagielski             throw e;
154*33efb51fSJim Jagielski         }
155*33efb51fSJim Jagielski         catch ( Exception e )
156*33efb51fSJim Jagielski         {
157*33efb51fSJim Jagielski             IOException aIOEx = new IOException( "Not a MediaWiki API response" );
158*33efb51fSJim Jagielski             aIOEx.initCause( e );
159*33efb51fSJim Jagielski             throw aIOEx;
160*33efb51fSJim Jagielski         }
161*33efb51fSJim Jagielski     }
162*33efb51fSJim Jagielski 
163*33efb51fSJim Jagielski     /** Returns the requested token ("login", "csrf"), or null if the wiki does not provide it. */
GetToken( String sType )164*33efb51fSJim Jagielski     public String GetToken( String sType )
165*33efb51fSJim Jagielski         throws IOException, WikiCancelException
166*33efb51fSJim Jagielski     {
167*33efb51fSJim Jagielski         Document aDoc = CallAPI( new String[][] { { "action", "query" }, { "meta", "tokens" }, { "type", sType } } );
168*33efb51fSJim Jagielski         Element aTokens = GetElement( aDoc, "tokens" );
169*33efb51fSJim Jagielski         if ( aTokens == null || !aTokens.hasAttribute( sType + "token" ) )
170*33efb51fSJim Jagielski             return null;
171*33efb51fSJim Jagielski         return aTokens.getAttribute( sType + "token" );
172*33efb51fSJim Jagielski     }
173*33efb51fSJim Jagielski 
GetElement( Document aDoc, String sTagName )174*33efb51fSJim Jagielski     public static Element GetElement( Document aDoc, String sTagName )
175*33efb51fSJim Jagielski     {
176*33efb51fSJim Jagielski         NodeList aList = aDoc.getElementsByTagName( sTagName );
177*33efb51fSJim Jagielski         return aList.getLength() > 0 ? (Element) aList.item( 0 ) : null;
178*33efb51fSJim Jagielski     }
179*33efb51fSJim Jagielski 
Open( URL aURL )180*33efb51fSJim Jagielski     private HttpURLConnection Open( URL aURL )
181*33efb51fSJim Jagielski         throws IOException, WikiCancelException
182*33efb51fSJim Jagielski     {
183*33efb51fSJim Jagielski         if ( !Helper.IsConnectionAllowed() )
184*33efb51fSJim Jagielski             throw new WikiCancelException();
185*33efb51fSJim Jagielski 
186*33efb51fSJim Jagielski         String sProtocol = aURL.getProtocol();
187*33efb51fSJim Jagielski         if ( !sProtocol.equals( "http" ) && !sProtocol.equals( "https" ) )
188*33efb51fSJim Jagielski             throw new IOException( "Unsupported protocol: " + sProtocol );
189*33efb51fSJim Jagielski 
190*33efb51fSJim Jagielski         Proxy aProxy = Helper.GetProxy( m_xContext, aURL );
191*33efb51fSJim Jagielski         HttpURLConnection aConn = (HttpURLConnection) ( aProxy == null ? aURL.openConnection() : aURL.openConnection( aProxy ) );
192*33efb51fSJim Jagielski         aConn.setInstanceFollowRedirects( false );
193*33efb51fSJim Jagielski         aConn.setConnectTimeout( CONNECT_TIMEOUT_MS );
194*33efb51fSJim Jagielski         aConn.setUseCaches( false );
195*33efb51fSJim Jagielski         aConn.setRequestProperty( "User-Agent", USER_AGENT );
196*33efb51fSJim Jagielski 
197*33efb51fSJim Jagielski         if ( aConn instanceof HttpsURLConnection && Helper.AllowUnknownCert( m_xContext, aURL.getHost() ) )
198*33efb51fSJim Jagielski             ( (HttpsURLConnection) aConn ).setSSLSocketFactory( GetUnknownCertSocketFactory() );
199*33efb51fSJim Jagielski 
200*33efb51fSJim Jagielski         try
201*33efb51fSJim Jagielski         {
202*33efb51fSJim Jagielski             Map<String, List<String>> aCookieHeaders = m_aCookies.get( aURL.toURI(), new HashMap<String, List<String>>() );
203*33efb51fSJim Jagielski             List<String> aCookies = aCookieHeaders.get( "Cookie" );
204*33efb51fSJim Jagielski             if ( aCookies != null && !aCookies.isEmpty() )
205*33efb51fSJim Jagielski             {
206*33efb51fSJim Jagielski                 StringBuilder aCookie = new StringBuilder();
207*33efb51fSJim Jagielski                 for ( String sCookie : aCookies )
208*33efb51fSJim Jagielski                 {
209*33efb51fSJim Jagielski                     if ( aCookie.length() > 0 )
210*33efb51fSJim Jagielski                         aCookie.append( "; " );
211*33efb51fSJim Jagielski                     aCookie.append( sCookie );
212*33efb51fSJim Jagielski                 }
213*33efb51fSJim Jagielski                 aConn.setRequestProperty( "Cookie", aCookie.toString() );
214*33efb51fSJim Jagielski             }
215*33efb51fSJim Jagielski         }
216*33efb51fSJim Jagielski         catch ( URISyntaxException e )
217*33efb51fSJim Jagielski         {
218*33efb51fSJim Jagielski             throw new IOException( e.getMessage() );
219*33efb51fSJim Jagielski         }
220*33efb51fSJim Jagielski 
221*33efb51fSJim Jagielski         return aConn;
222*33efb51fSJim Jagielski     }
223*33efb51fSJim Jagielski 
Execute( HttpURLConnection aConn, URL aURL, byte[] pBody )224*33efb51fSJim Jagielski     private Response Execute( HttpURLConnection aConn, URL aURL, byte[] pBody )
225*33efb51fSJim Jagielski         throws IOException, WikiCancelException
226*33efb51fSJim Jagielski     {
227*33efb51fSJim Jagielski         Helper.RegisterConnection( aConn );
228*33efb51fSJim Jagielski         try
229*33efb51fSJim Jagielski         {
230*33efb51fSJim Jagielski             // disconnect() is a no-op until the TCP connect has finished, so recheck a cancel that came during it
231*33efb51fSJim Jagielski             aConn.connect();
232*33efb51fSJim Jagielski             if ( !Helper.IsConnectionAllowed() )
233*33efb51fSJim Jagielski                 throw new WikiCancelException();
234*33efb51fSJim Jagielski 
235*33efb51fSJim Jagielski             if ( pBody != null )
236*33efb51fSJim Jagielski             {
237*33efb51fSJim Jagielski                 OutputStream aOut = aConn.getOutputStream();
238*33efb51fSJim Jagielski                 try
239*33efb51fSJim Jagielski                 {
240*33efb51fSJim Jagielski                     aOut.write( pBody );
241*33efb51fSJim Jagielski                 }
242*33efb51fSJim Jagielski                 finally
243*33efb51fSJim Jagielski                 {
244*33efb51fSJim Jagielski                     aOut.close();
245*33efb51fSJim Jagielski                 }
246*33efb51fSJim Jagielski             }
247*33efb51fSJim Jagielski 
248*33efb51fSJim Jagielski             Response aResponse = new Response();
249*33efb51fSJim Jagielski             aResponse.m_nStatus = aConn.getResponseCode();
250*33efb51fSJim Jagielski             aResponse.m_aURL = aURL;
251*33efb51fSJim Jagielski 
252*33efb51fSJim Jagielski             try
253*33efb51fSJim Jagielski             {
254*33efb51fSJim Jagielski                 m_aCookies.put( aURL.toURI(), aConn.getHeaderFields() );
255*33efb51fSJim Jagielski             }
256*33efb51fSJim Jagielski             catch ( URISyntaxException e )
257*33efb51fSJim Jagielski             {
258*33efb51fSJim Jagielski                 throw new IOException( e.getMessage() );
259*33efb51fSJim Jagielski             }
260*33efb51fSJim Jagielski 
261*33efb51fSJim Jagielski             InputStream aIn = aResponse.m_nStatus >= 400 ? aConn.getErrorStream() : aConn.getInputStream();
262*33efb51fSJim Jagielski             aResponse.m_sBody = ( aIn == null ) ? "" : ReadAll( aIn, GetCharset( aConn.getContentType() ) );
263*33efb51fSJim Jagielski             return aResponse;
264*33efb51fSJim Jagielski         }
265*33efb51fSJim Jagielski         catch ( IOException e )
266*33efb51fSJim Jagielski         {
267*33efb51fSJim Jagielski             if ( !Helper.IsConnectionAllowed() )
268*33efb51fSJim Jagielski                 throw new WikiCancelException();
269*33efb51fSJim Jagielski             throw e;
270*33efb51fSJim Jagielski         }
271*33efb51fSJim Jagielski         finally
272*33efb51fSJim Jagielski         {
273*33efb51fSJim Jagielski             Helper.UnregisterConnection( aConn );
274*33efb51fSJim Jagielski         }
275*33efb51fSJim Jagielski     }
276*33efb51fSJim Jagielski 
GetCharset( String sContentType )277*33efb51fSJim Jagielski     private static String GetCharset( String sContentType )
278*33efb51fSJim Jagielski     {
279*33efb51fSJim Jagielski         if ( sContentType != null )
280*33efb51fSJim Jagielski         {
281*33efb51fSJim Jagielski             String[] pParts = sContentType.split( ";" );
282*33efb51fSJim Jagielski             for ( int nInd = 1; nInd < pParts.length; nInd++ )
283*33efb51fSJim Jagielski             {
284*33efb51fSJim Jagielski                 String sPart = pParts[nInd].trim();
285*33efb51fSJim Jagielski                 if ( sPart.regionMatches( true, 0, "charset=", 0, 8 ) )
286*33efb51fSJim Jagielski                     return sPart.substring( 8 ).replace( "\"", "" ).trim();
287*33efb51fSJim Jagielski             }
288*33efb51fSJim Jagielski         }
289*33efb51fSJim Jagielski         return "UTF-8";
290*33efb51fSJim Jagielski     }
291*33efb51fSJim Jagielski 
ReadAll( InputStream aIn, String sCharset )292*33efb51fSJim Jagielski     private static String ReadAll( InputStream aIn, String sCharset )
293*33efb51fSJim Jagielski         throws IOException
294*33efb51fSJim Jagielski     {
295*33efb51fSJim Jagielski         try
296*33efb51fSJim Jagielski         {
297*33efb51fSJim Jagielski             ByteArrayOutputStream aOut = new ByteArrayOutputStream();
298*33efb51fSJim Jagielski             byte[] pBuf = new byte[8192];
299*33efb51fSJim Jagielski             int nRead;
300*33efb51fSJim Jagielski             while ( ( nRead = aIn.read( pBuf ) ) != -1 )
301*33efb51fSJim Jagielski                 aOut.write( pBuf, 0, nRead );
302*33efb51fSJim Jagielski             try
303*33efb51fSJim Jagielski             {
304*33efb51fSJim Jagielski                 return aOut.toString( sCharset );
305*33efb51fSJim Jagielski             }
306*33efb51fSJim Jagielski             catch ( UnsupportedEncodingException e )
307*33efb51fSJim Jagielski             {
308*33efb51fSJim Jagielski                 return aOut.toString( "UTF-8" );
309*33efb51fSJim Jagielski             }
310*33efb51fSJim Jagielski         }
311*33efb51fSJim Jagielski         finally
312*33efb51fSJim Jagielski         {
313*33efb51fSJim Jagielski             aIn.close();
314*33efb51fSJim Jagielski         }
315*33efb51fSJim Jagielski     }
316*33efb51fSJim Jagielski 
GetUnknownCertSocketFactory()317*33efb51fSJim Jagielski     private static synchronized SSLSocketFactory GetUnknownCertSocketFactory()
318*33efb51fSJim Jagielski         throws IOException
319*33efb51fSJim Jagielski     {
320*33efb51fSJim Jagielski         if ( m_aUnknownCertSocketFactory == null )
321*33efb51fSJim Jagielski         {
322*33efb51fSJim Jagielski             try
323*33efb51fSJim Jagielski             {
324*33efb51fSJim Jagielski                 TrustManagerFactory aFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
325*33efb51fSJim Jagielski                 aFactory.init( (KeyStore) null );
326*33efb51fSJim Jagielski                 X509TrustManager aDefault = null;
327*33efb51fSJim Jagielski                 TrustManager[] pManagers = aFactory.getTrustManagers();
328*33efb51fSJim Jagielski                 for ( int nInd = 0; nInd < pManagers.length && aDefault == null; nInd++ )
329*33efb51fSJim Jagielski                     if ( pManagers[nInd] instanceof X509TrustManager )
330*33efb51fSJim Jagielski                         aDefault = (X509TrustManager) pManagers[nInd];
331*33efb51fSJim Jagielski                 if ( aDefault == null )
332*33efb51fSJim Jagielski                     throw new IOException( "No default trust manager" );
333*33efb51fSJim Jagielski 
334*33efb51fSJim Jagielski                 SSLContext aContext = SSLContext.getInstance( "TLS" );
335*33efb51fSJim Jagielski                 aContext.init( null, new TrustManager[] { new UnknownCertTrustManager( aDefault ) }, null );
336*33efb51fSJim Jagielski                 m_aUnknownCertSocketFactory = aContext.getSocketFactory();
337*33efb51fSJim Jagielski             }
338*33efb51fSJim Jagielski             catch ( IOException e )
339*33efb51fSJim Jagielski             {
340*33efb51fSJim Jagielski                 throw e;
341*33efb51fSJim Jagielski             }
342*33efb51fSJim Jagielski             catch ( Exception e )
343*33efb51fSJim Jagielski             {
344*33efb51fSJim Jagielski                 IOException aIOEx = new IOException( "Cannot initialize TLS" );
345*33efb51fSJim Jagielski                 aIOEx.initCause( e );
346*33efb51fSJim Jagielski                 throw aIOEx;
347*33efb51fSJim Jagielski             }
348*33efb51fSJim Jagielski         }
349*33efb51fSJim Jagielski 
350*33efb51fSJim Jagielski         return m_aUnknownCertSocketFactory;
351*33efb51fSJim Jagielski     }
352*33efb51fSJim Jagielski 
353*33efb51fSJim Jagielski     /** For servers the configuration marks with AllowUnknownCertificate: a server certificate
354*33efb51fSJim Jagielski         that does not chain to a trusted root is accepted if it is within its validity period.
355*33efb51fSJim Jagielski         The host name is still verified by HttpsURLConnection. */
356*33efb51fSJim Jagielski     private static class UnknownCertTrustManager implements X509TrustManager
357*33efb51fSJim Jagielski     {
358*33efb51fSJim Jagielski         private X509TrustManager m_aDefault;
359*33efb51fSJim Jagielski 
UnknownCertTrustManager( X509TrustManager aDefault )360*33efb51fSJim Jagielski         UnknownCertTrustManager( X509TrustManager aDefault )
361*33efb51fSJim Jagielski         {
362*33efb51fSJim Jagielski             m_aDefault = aDefault;
363*33efb51fSJim Jagielski         }
364*33efb51fSJim Jagielski 
getAcceptedIssuers()365*33efb51fSJim Jagielski         public X509Certificate[] getAcceptedIssuers()
366*33efb51fSJim Jagielski         {
367*33efb51fSJim Jagielski             return m_aDefault.getAcceptedIssuers();
368*33efb51fSJim Jagielski         }
369*33efb51fSJim Jagielski 
checkClientTrusted( X509Certificate[] pCerts, String sAuthType )370*33efb51fSJim Jagielski         public void checkClientTrusted( X509Certificate[] pCerts, String sAuthType ) throws CertificateException
371*33efb51fSJim Jagielski         {
372*33efb51fSJim Jagielski             m_aDefault.checkClientTrusted( pCerts, sAuthType );
373*33efb51fSJim Jagielski         }
374*33efb51fSJim Jagielski 
checkServerTrusted( X509Certificate[] pCerts, String sAuthType )375*33efb51fSJim Jagielski         public void checkServerTrusted( X509Certificate[] pCerts, String sAuthType ) throws CertificateException
376*33efb51fSJim Jagielski         {
377*33efb51fSJim Jagielski             try
378*33efb51fSJim Jagielski             {
379*33efb51fSJim Jagielski                 m_aDefault.checkServerTrusted( pCerts, sAuthType );
380*33efb51fSJim Jagielski             }
381*33efb51fSJim Jagielski             catch ( CertificateException e )
382*33efb51fSJim Jagielski             {
383*33efb51fSJim Jagielski                 if ( pCerts == null || pCerts.length == 0 )
384*33efb51fSJim Jagielski                     throw e;
385*33efb51fSJim Jagielski                 pCerts[0].checkValidity();
386*33efb51fSJim Jagielski             }
387*33efb51fSJim Jagielski         }
388*33efb51fSJim Jagielski     }
389*33efb51fSJim Jagielski }
390