View Javadoc
1   /*
2    * Copyright (C) 2013, 2020 Christian Halstrick <christian.halstrick@sap.com> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.transport.http.apache;
11  
12  import java.io.IOException;
13  import java.net.Proxy;
14  import java.net.URL;
15  import java.security.GeneralSecurityException;
16  import java.text.MessageFormat;
17  
18  import javax.net.ssl.HostnameVerifier;
19  import javax.net.ssl.SSLContext;
20  import javax.net.ssl.SSLSocket;
21  import javax.net.ssl.TrustManager;
22  
23  import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
24  import org.eclipse.jgit.transport.http.HttpConnection;
25  import org.eclipse.jgit.transport.http.HttpConnectionFactory2;
26  import org.eclipse.jgit.transport.http.NoCheckX509TrustManager;
27  import org.eclipse.jgit.transport.http.apache.internal.HttpApacheText;
28  import org.eclipse.jgit.util.HttpSupport;
29  
30  /**
31   * A factory returning instances of {@link HttpClientConnection}.
32   *
33   * @since 3.3
34   */
35  public class HttpClientConnectionFactory implements HttpConnectionFactory2 {
36  
37  	@Override
38  	public HttpConnection create(URL url) throws IOException {
39  		return new HttpClientConnection(url.toString());
40  	}
41  
42  	@Override
43  	public HttpConnection create(URL url, Proxy proxy) throws IOException {
44  		return new HttpClientConnection(url.toString(), proxy);
45  	}
46  
47  	@Override
48  	public GitSession newSession() {
49  		return new HttpClientSession();
50  	}
51  
52  	private static class HttpClientSession implements GitSession {
53  
54  		private SSLContext securityContext;
55  
56  		private SSLConnectionSocketFactory socketFactory;
57  
58  		private boolean isDefault;
59  
60  		@Override
61  		public HttpClientConnection configure(HttpConnection connection,
62  				boolean sslVerify)
63  				throws IOException, GeneralSecurityException {
64  			if (!(connection instanceof HttpClientConnection)) {
65  				throw new IllegalArgumentException(MessageFormat.format(
66  						HttpApacheText.get().httpWrongConnectionType,
67  						HttpClientConnection.class.getName(),
68  						connection.getClass().getName()));
69  			}
70  			HttpClientConnection conn = (HttpClientConnection) connection;
71  			String scheme = conn.getURL().getProtocol();
72  			if (!"https".equals(scheme)) { //$NON-NLS-1$
73  				return conn;
74  			}
75  			if (securityContext == null || isDefault != sslVerify) {
76  				isDefault = sslVerify;
77  				HostnameVerifier verifier;
78  				if (sslVerify) {
79  					securityContext = SSLContext.getDefault();
80  					verifier = SSLConnectionSocketFactory
81  							.getDefaultHostnameVerifier();
82  				} else {
83  					securityContext = SSLContext.getInstance("TLS");
84  					TrustManager[] trustAllCerts = {
85  							new NoCheckX509TrustManager() };
86  					securityContext.init(null, trustAllCerts, null);
87  					verifier = (name, session) -> true;
88  				}
89  				socketFactory = new SSLConnectionSocketFactory(securityContext,
90  						verifier) {
91  
92  					@Override
93  					protected void prepareSocket(SSLSocket socket)
94  							throws IOException {
95  						super.prepareSocket(socket);
96  						HttpSupport.configureTLS(socket);
97  					}
98  				};
99  			}
100 			conn.setSSLSocketFactory(socketFactory, isDefault);
101 			return conn;
102 		}
103 
104 		@Override
105 		public void close() {
106 			securityContext = null;
107 			socketFactory = null;
108 		}
109 
110 	}
111 }