From e3cd9b9f1c9787c36d5ea82190bf1e2365377e66 Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Wed, 27 Apr 2016 07:35:28 +0530 Subject: [PATCH] Fixes #2513 - NetworkSecurityPolicy based ConnectionSpec setup. --- .../src/main/java/okhttp3/OkHttpClient.java | 10 +++++-- .../main/java/okhttp3/internal/Platform.java | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/okhttp/src/main/java/okhttp3/OkHttpClient.java b/okhttp/src/main/java/okhttp3/OkHttpClient.java index 8df00c54a4b3..b23e6a221255 100644 --- a/okhttp/src/main/java/okhttp3/OkHttpClient.java +++ b/okhttp/src/main/java/okhttp3/OkHttpClient.java @@ -65,10 +65,16 @@ public class OkHttpClient implements Cloneable, Call.Factory { private static final List DEFAULT_PROTOCOLS = Util.immutableList( Protocol.HTTP_2, Protocol.SPDY_3, Protocol.HTTP_1_1); - private static final List DEFAULT_CONNECTION_SPECS = Util.immutableList( - ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT); + private static final List DEFAULT_CONNECTION_SPECS; static { + List connSpecs = new ArrayList<>(Arrays.asList(ConnectionSpec.MODERN_TLS, + ConnectionSpec.COMPATIBLE_TLS)); + if (Platform.get().isCleartextTrafficPermitted()) { + connSpecs.add(ConnectionSpec.CLEARTEXT); + } + DEFAULT_CONNECTION_SPECS = Util.immutableList(connSpecs); + Internal.instance = new Internal() { @Override public void addLenient(Headers.Builder builder, String line) { builder.addLenient(line); diff --git a/okhttp/src/main/java/okhttp3/internal/Platform.java b/okhttp/src/main/java/okhttp3/internal/Platform.java index 423a6aa9c076..370662e90b36 100644 --- a/okhttp/src/main/java/okhttp3/internal/Platform.java +++ b/okhttp/src/main/java/okhttp3/internal/Platform.java @@ -67,6 +67,10 @@ * *

Supported on Android 2.3+ and OpenJDK 7+. There are no public APIs to recover the trust * manager that was used to create an {@link SSLSocketFactory}. + * + *

Android Cleartext Permit Detection

+ * + *

Supported on Android 6.0+ via {@code NetworkSecurityPolicy}. */ public class Platform { private static final Platform PLATFORM = findPlatform(); @@ -128,6 +132,10 @@ public void log(String message) { System.out.println(message); } + public boolean isCleartextTrafficPermitted() { + return true; + } + public static List alpnProtocolNames(List protocols) { List names = new ArrayList<>(protocols.size()); for (int i = 0, size = protocols.size(); i < size; i++) { @@ -298,6 +306,25 @@ public Android(Class sslParametersClass, OptionalMethod setUseSession } while (i < newline); } } + + @Override public boolean isCleartextTrafficPermitted() { + try { + Class networkPolicyClass = Class.forName("android.security.NetworkSecurityPolicy"); + Method getInstanceMethod = networkPolicyClass.getMethod("getInstance"); + Object networkSecurityPolicy = getInstanceMethod.invoke(null); + Method isCleartextTrafficPermittedMethod = networkPolicyClass + .getMethod("isCleartextTrafficPermitted"); + boolean cleartextPermitted = (boolean) isCleartextTrafficPermittedMethod + .invoke(networkSecurityPolicy); + return cleartextPermitted; + } catch (ClassNotFoundException e) { + return super.isCleartextTrafficPermitted(); + } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new AssertionError(); + } + } + } /**