8
8
import java .net .URL ;
9
9
import java .nio .channels .Channels ;
10
10
import java .nio .channels .ReadableByteChannel ;
11
+ import java .security .KeyManagementException ;
12
+ import java .security .KeyStoreException ;
13
+ import java .security .NoSuchAlgorithmException ;
14
+
15
+ import javax .net .ssl .SSLContext ;
11
16
12
17
import org .apache .commons .io .FileUtils ;
13
18
import org .apache .commons .io .FilenameUtils ;
14
19
import org .apache .http .HttpHost ;
15
20
import org .apache .http .auth .AuthScope ;
21
+ import org .apache .http .auth .AuthState ;
16
22
import org .apache .http .auth .UsernamePasswordCredentials ;
17
23
import org .apache .http .client .AuthCache ;
18
24
import org .apache .http .client .CredentialsProvider ;
19
25
import org .apache .http .client .config .RequestConfig ;
20
26
import org .apache .http .client .methods .CloseableHttpResponse ;
21
27
import org .apache .http .client .methods .HttpGet ;
22
28
import org .apache .http .client .protocol .HttpClientContext ;
29
+ import org .apache .http .conn .ssl .TrustSelfSignedStrategy ;
23
30
import org .apache .http .impl .auth .BasicScheme ;
24
31
import org .apache .http .impl .client .BasicAuthCache ;
25
32
import org .apache .http .impl .client .BasicCredentialsProvider ;
26
33
import org .apache .http .impl .client .CloseableHttpClient ;
27
34
import org .apache .http .impl .client .HttpClients ;
35
+ import org .apache .http .ssl .SSLContextBuilder ;
28
36
import org .codehaus .plexus .util .StringUtils ;
29
37
import org .slf4j .Logger ;
30
38
import org .slf4j .LoggerFactory ;
@@ -41,7 +49,7 @@ public DownloadException(String message){
41
49
}
42
50
43
51
interface FileDownloader {
44
- void download (String downloadUrl , String destination , String userName , String password ) throws DownloadException ;
52
+ void download (String downloadUrl , String destination , String userName , String password , boolean trustInsecureDownloadRoot ) throws DownloadException ;
45
53
}
46
54
47
55
final class DefaultFileDownloader implements FileDownloader {
@@ -54,7 +62,7 @@ public DefaultFileDownloader(ProxyConfig proxyConfig){
54
62
}
55
63
56
64
@ Override
57
- public void download (String downloadUrl , String destination , String userName , String password ) throws DownloadException {
65
+ public void download (String downloadUrl , String destination , String userName , String password , boolean trustInsecureDownloadRoot ) throws DownloadException {
58
66
// force tls to 1.2 since github removed weak cryptographic standards
59
67
// https://blog.github.com/2018-02-02-weak-cryptographic-standards-removal-notice/
60
68
System .setProperty ("https.protocols" , "TLSv1.2" );
@@ -66,7 +74,7 @@ public void download(String downloadUrl, String destination, String userName, St
66
74
FileUtils .copyFile (new File (downloadURI ), new File (destination ));
67
75
}
68
76
else {
69
- CloseableHttpResponse response = execute (fixedDownloadUrl , userName , password );
77
+ CloseableHttpResponse response = execute (fixedDownloadUrl , userName , password , trustInsecureDownloadRoot );
70
78
int statusCode = response .getStatusLine ().getStatusCode ();
71
79
if (statusCode != 200 ){
72
80
throw new DownloadException ("Got error code " + statusCode +" from the server." );
@@ -82,12 +90,18 @@ public void download(String downloadUrl, String destination, String userName, St
82
90
}
83
91
}
84
92
85
- private CloseableHttpResponse execute (String requestUrl , String userName , String password ) throws IOException {
93
+ private CloseableHttpResponse execute (String requestUrl , String userName , String password , boolean trustInsecureDownloadRoot )
94
+ throws IOException , DownloadException {
86
95
CloseableHttpResponse response ;
96
+ SSLContext sslContext = null ;
97
+ if (trustInsecureDownloadRoot ) {
98
+ LOGGER .info ("Trust insecure download enabled." );
99
+ sslContext = makeSSLContextForTrustedInsecureDownloads ();
100
+ }
87
101
Proxy proxy = proxyConfig .getProxyForUrl (requestUrl );
88
102
if (proxy != null ) {
89
103
LOGGER .info ("Downloading via proxy " + proxy .toString ());
90
- return executeViaProxy (proxy , requestUrl );
104
+ return executeViaProxy (proxy , sslContext , requestUrl );
91
105
} else {
92
106
LOGGER .info ("No proxy was configured, downloading directly" );
93
107
if (StringUtils .isNotEmpty (userName ) && StringUtils .isNotEmpty (password )) {
@@ -100,40 +114,50 @@ private CloseableHttpResponse execute(String requestUrl, String userName, String
100
114
aURL .getPort (),
101
115
userName ,
102
116
password );
103
- response = buildHttpClient (credentialsProvider ).execute (new HttpGet (requestUrl ),localContext );
117
+ response = buildHttpClient (sslContext , credentialsProvider ).execute (new HttpGet (requestUrl ),localContext );
104
118
} else {
105
- response = buildHttpClient (null ).execute (new HttpGet (requestUrl ));
119
+ response = buildHttpClient (sslContext , null ).execute (new HttpGet (requestUrl ));
106
120
}
107
121
}
108
122
return response ;
109
123
}
110
124
111
- private CloseableHttpResponse executeViaProxy (Proxy proxy , String requestUrl ) throws IOException {
112
- final CloseableHttpClient proxyClient ;
113
- if (proxy .useAuthentication ()){
114
- proxyClient = buildHttpClient (makeCredentialsProvider (proxy .host ,proxy .port ,proxy .username ,proxy .password ));
125
+ private CloseableHttpResponse executeViaProxy (Proxy proxy , SSLContext sslContext , String requestUrl ) throws IOException {
126
+ final HttpGet request = new HttpGet (requestUrl );
127
+ request .setConfig (RequestConfig .custom ()
128
+ .setProxy (new HttpHost (proxy .host , proxy .port ))
129
+ .build ());
130
+ final CloseableHttpClient proxyClient = buildHttpClient (sslContext , null );
131
+ if (proxy .useAuthentication ()) {
132
+ final AuthState authState = new AuthState ();
133
+ authState .update (new BasicScheme (), new UsernamePasswordCredentials (proxy .username , proxy .password ));
134
+ final HttpClientContext httpContext = HttpClientContext .create ();
135
+ httpContext .setAttribute (HttpClientContext .PROXY_AUTH_STATE , authState );
136
+ return proxyClient .execute (request , httpContext );
115
137
} else {
116
- proxyClient = buildHttpClient ( null );
138
+ return proxyClient . execute ( request );
117
139
}
118
-
119
- final HttpHost proxyHttpHost = new HttpHost (proxy .host , proxy .port );
120
-
121
- final RequestConfig requestConfig = RequestConfig .custom ().setProxy (proxyHttpHost ).build ();
122
-
123
- final HttpGet request = new HttpGet (requestUrl );
124
- request .setConfig (requestConfig );
125
-
126
- return proxyClient .execute (request );
127
140
}
128
141
129
- private CloseableHttpClient buildHttpClient (CredentialsProvider credentialsProvider ) {
142
+ private CloseableHttpClient buildHttpClient (SSLContext sslContext , CredentialsProvider credentialsProvider ) {
130
143
return HttpClients .custom ()
144
+ .setSSLContext (sslContext )
131
145
.disableContentCompression ()
132
146
.useSystemProperties ()
133
147
.setDefaultCredentialsProvider (credentialsProvider )
134
148
.build ();
135
149
}
136
150
151
+ private SSLContext makeSSLContextForTrustedInsecureDownloads () throws DownloadException {
152
+ try {
153
+ return SSLContextBuilder .create ()
154
+ .loadTrustMaterial (TrustSelfSignedStrategy .INSTANCE )
155
+ .build ();
156
+ } catch (final NoSuchAlgorithmException | KeyStoreException | KeyManagementException e ) {
157
+ throw new DownloadException ("Unable to create SSLContext to trust insecure downloads." , e );
158
+ }
159
+ }
160
+
137
161
private CredentialsProvider makeCredentialsProvider (String host , int port , String username , String password ) {
138
162
CredentialsProvider credentialsProvider = new BasicCredentialsProvider ();
139
163
credentialsProvider .setCredentials (
0 commit comments