1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.transport.apache;
20
21 import java.util.Locale;
22 import java.util.Map;
23 import java.util.Queue;
24
25 import org.apache.http.Header;
26 import org.apache.http.HttpHost;
27 import org.apache.http.HttpRequest;
28 import org.apache.http.HttpRequestInterceptor;
29 import org.apache.http.HttpResponse;
30 import org.apache.http.auth.AuthOption;
31 import org.apache.http.auth.AuthScope;
32 import org.apache.http.auth.AuthState;
33 import org.apache.http.auth.MalformedChallengeException;
34 import org.apache.http.auth.NTCredentials;
35 import org.apache.http.auth.UsernamePasswordCredentials;
36 import org.apache.http.client.CredentialsProvider;
37 import org.apache.http.client.config.AuthSchemes;
38 import org.apache.http.client.protocol.HttpClientContext;
39 import org.apache.http.conn.routing.RouteInfo;
40 import org.apache.http.impl.client.BasicCredentialsProvider;
41 import org.apache.http.impl.client.ProxyAuthenticationStrategy;
42 import org.apache.http.protocol.BasicHttpContext;
43 import org.apache.http.protocol.HttpContext;
44
45
46
47
48
49
50 final class SystemProxyAuthenticationStrategy extends ProxyAuthenticationStrategy implements HttpRequestInterceptor {
51 private static final String SYSTEM_PROXY = SystemProxyAuthenticationStrategy.class.getName() + ".proxy";
52
53 @Override
54 public void process(HttpRequest request, HttpContext context) {
55 HttpHost authenticatedProxy = (HttpHost) context.getAttribute(SYSTEM_PROXY);
56 RouteInfo route = HttpClientContext.adapt(context).getHttpRoute();
57 if (authenticatedProxy != null && route != null && !authenticatedProxy.equals(route.getProxyHost())) {
58
59 AuthState state = HttpClientContext.adapt(context).getProxyAuthState();
60 if (state != null) {
61 state.reset();
62 }
63 request.removeHeaders("Proxy-Authorization");
64 context.removeAttribute(SYSTEM_PROXY);
65 }
66 }
67
68 @Override
69 public Queue<AuthOption> select(
70 Map<String, Header> challenges, HttpHost authhost, HttpResponse response, HttpContext context)
71 throws MalformedChallengeException {
72 Queue<AuthOption> options = super.select(challenges, authhost, response, context);
73 if (!options.isEmpty()) {
74 return options;
75 }
76 RouteInfo route = HttpClientContext.adapt(context).getHttpRoute();
77 if (route == null || !authhost.equals(route.getProxyHost())) {
78 return options;
79 }
80 String routeProtocol = route.getTargetHost().getSchemeName().toLowerCase(Locale.ENGLISH);
81 CredentialsProvider credentials = credentials(authhost, routeProtocol);
82 String fallbackProtocol = "https".equalsIgnoreCase(routeProtocol) ? "http" : "https";
83 if (credentials == null) {
84 credentials = credentials(authhost, fallbackProtocol);
85 }
86 if (credentials == null) {
87 return options;
88 }
89
90 HttpClientContext proxyContext = HttpClientContext.adapt(new BasicHttpContext(context));
91 proxyContext.setCredentialsProvider(credentials);
92 options = super.select(challenges, authhost, response, proxyContext);
93 if (!options.isEmpty()) {
94 context.setAttribute(SYSTEM_PROXY, authhost);
95 }
96 return options;
97 }
98
99 private static CredentialsProvider credentials(HttpHost proxy, String protocol) {
100 String prefix = protocol + ".proxy";
101 if (!proxy.getHostName().equalsIgnoreCase(System.getProperty(prefix + "Host"))) {
102 return null;
103 }
104 try {
105 String configuredPort = System.getProperty(prefix + "Port");
106 int port = configuredPort == null ? defaultPort(protocol) : Integer.parseInt(configuredPort);
107 if (proxy.getPort() != port) {
108 return null;
109 }
110 } catch (NumberFormatException e) {
111 return null;
112 }
113 String username = System.getProperty(prefix + "User");
114 if (username == null) {
115 return null;
116 }
117 String password = System.getProperty(prefix + "Password", "");
118 BasicCredentialsProvider credentials = new BasicCredentialsProvider();
119 credentials.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials(username, password));
120
121 credentials.setCredentials(
122 new AuthScope(proxy, AuthScope.ANY_REALM, AuthSchemes.NTLM),
123 new NTCredentials(username, password, null, System.getProperty("http.auth.ntlm.domain")));
124 return credentials;
125 }
126
127 private static int defaultPort(String protocol) {
128 return "https".equalsIgnoreCase(protocol) ? 443 : 80;
129 }
130 }