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