summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Klyubin <klyubin@google.com>2015-03-27 08:50:03 -0700
committerAlex Klyubin <klyubin@google.com>2015-03-27 10:40:30 -0700
commit23c78a7d649e632852abb1f73ee36c117097c5c0 (patch)
tree6e0509d81ec004f816619d3a5ce5b767deb32aa4
parent1cbd67d91edfcedbfd28aac75c1c616ced66ab4a (diff)
downloadandroid_external_apache-http-23c78a7d649e632852abb1f73ee36c117097c5c0.tar.gz
android_external_apache-http-23c78a7d649e632852abb1f73ee36c117097c5c0.tar.bz2
android_external_apache-http-23c78a7d649e632852abb1f73ee36c117097c5c0.zip
Honor NetworkSecurityPolicy regarding cleartext traffic.
This makes HttpClient instances honor the process-wide policy about cleartext network traffic. If cleartext network traffic is not permitted, then attempts to send a cleartext HTTP request will throw an IOException. This change is needed despite platform-provided HttpClient being deprecated because a large fraction of applications still use this HttpClient library to generate HTTP traffic instead of using URLConnection. HttpClient is modular -- most of its parts can be replaced with alternative implementations. Thus, this CL enforces the cleartext traffic policy in DefaultRequestDirector because RequestDirector is least commonly replaced (if ever) and there are no other RequestDirector implementations provided by the library. The cleartext policy is enforced pretty late in the process of emitting a request to give time for any HttpRequestInterceptor instances to see the request. This is because some apps use a HttpRequestInterceptor to enforce their own policies about cleartext HTTP such as catching accidental use of cleartext HTTP and reporting it to their servers for analysis. Bug: 19215516 Change-Id: I03687123080475581e7196d9bb8c0d006502d056
-rw-r--r--src/org/apache/http/impl/client/DefaultRequestDirector.java43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/org/apache/http/impl/client/DefaultRequestDirector.java b/src/org/apache/http/impl/client/DefaultRequestDirector.java
index 9aafa85..6f9dcd0 100644
--- a/src/org/apache/http/impl/client/DefaultRequestDirector.java
+++ b/src/org/apache/http/impl/client/DefaultRequestDirector.java
@@ -33,6 +33,7 @@ package org.apache.http.impl.client;
import java.io.IOException;
import java.io.InterruptedIOException;
+import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
@@ -430,6 +431,12 @@ public class DefaultRequestDirector implements RequestDirector {
if (this.log.isDebugEnabled()) {
this.log.debug("Attempt " + execCount + " to execute request");
}
+ // BEGIN android-added
+ if ((!route.isSecure()) && (!isCleartextTrafficPermitted())) {
+ throw new IOException(
+ "Cleartext traffic not permitted: " + route.getTargetHost());
+ }
+ // END android-added
response = requestExec.execute(wrapper, managedConn, context);
retrying = false;
@@ -1121,4 +1128,40 @@ public class DefaultRequestDirector implements RequestDirector {
authState.setCredentials(creds);
}
+ // BEGIN android-added
+ /** Cached instance of android.security.NetworkSecurityPolicy. */
+ private static Object networkSecurityPolicy;
+
+ /** Cached android.security.NetworkSecurityPolicy.isCleartextTrafficPermitted method. */
+ private static Method cleartextTrafficPermittedMethod;
+
+ private static boolean isCleartextTrafficPermitted() {
+ // TODO: Remove this method once NetworkSecurityPolicy can be accessed without Reflection.
+ // This method invokes NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted
+ // via Reflection API.
+ // Because of the way external/apache-http is built, in the near term it can't invoke new
+ // Android framework API directly.
+ try {
+ Object policy;
+ Method method;
+ synchronized (DefaultRequestDirector.class) {
+ if (cleartextTrafficPermittedMethod == null) {
+ Class<?> cls = Class.forName("android.security.NetworkSecurityPolicy");
+ Method getInstanceMethod = cls.getMethod("getInstance");
+ networkSecurityPolicy = getInstanceMethod.invoke(null);
+ cleartextTrafficPermittedMethod = cls.getMethod("isCleartextTrafficPermitted");
+ }
+ policy = networkSecurityPolicy;
+ method = cleartextTrafficPermittedMethod;
+ }
+ return (Boolean) method.invoke(policy);
+ } catch (ReflectiveOperationException e) {
+ // Can't access the Android framework NetworkSecurityPolicy. To be backward compatible,
+ // assume that cleartext traffic is permitted. Android CTS will take care of ensuring
+ // this issue doesn't occur on new Android platforms.
+ return true;
+ }
+ }
+ // END android-added
+
} // class DefaultClientRequestDirector