diff options
Diffstat (limited to 'src/com/android/providers/downloads')
3 files changed, 59 insertions, 0 deletions
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java index c75e4193..325b4eee 100644 --- a/src/com/android/providers/downloads/DownloadThread.java +++ b/src/com/android/providers/downloads/DownloadThread.java @@ -48,6 +48,7 @@ import android.net.INetworkPolicyListener; import android.net.NetworkInfo; import android.net.NetworkPolicyManager; import android.net.TrafficStats; +import android.net.Uri; import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.os.Process; @@ -350,8 +351,17 @@ public class DownloadThread implements Runnable { throw new StopRequestException(STATUS_BAD_REQUEST, e); } + boolean cleartextTrafficPermitted = mSystemFacade.isCleartextTrafficPermitted(mInfo.mUid); int redirectionCount = 0; while (redirectionCount++ < Constants.MAX_REDIRECTS) { + // Enforce the cleartext traffic opt-out for the UID. This cannot be enforced earlier + // because of HTTP redirects which can change the protocol between HTTP and HTTPS. + if ((!cleartextTrafficPermitted) && ("http".equalsIgnoreCase(url.getProtocol()))) { + throw new StopRequestException(STATUS_BAD_REQUEST, + "Cleartext traffic not permitted for UID " + mInfo.mUid + ": " + + Uri.parse(url.toString()).toSafeString()); + } + // Open connection and follow any redirects until we have a useful // response with body. HttpURLConnection conn = null; diff --git a/src/com/android/providers/downloads/RealSystemFacade.java b/src/com/android/providers/downloads/RealSystemFacade.java index fa4f3488..b3f170fb 100644 --- a/src/com/android/providers/downloads/RealSystemFacade.java +++ b/src/com/android/providers/downloads/RealSystemFacade.java @@ -16,9 +16,14 @@ package com.android.providers.downloads; +import com.android.internal.util.ArrayUtils; + import android.app.DownloadManager; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -96,4 +101,43 @@ class RealSystemFacade implements SystemFacade { public boolean userOwnsPackage(int uid, String packageName) throws NameNotFoundException { return mContext.getPackageManager().getApplicationInfo(packageName, 0).uid == uid; } + + @Override + public boolean isCleartextTrafficPermitted(int uid) { + PackageManager packageManager = mContext.getPackageManager(); + String[] packageNames = packageManager.getPackagesForUid(uid); + if (ArrayUtils.isEmpty(packageNames)) { + // Unknown UID -- fail safe: cleartext traffic not permitted + return false; + } + + // Cleartext traffic is permitted from the UID if it's permitted for any of the packages + // belonging to that UID. + for (String packageName : packageNames) { + if (isCleartextTrafficPermitted(packageName)) { + return true; + } + } + return false; + } + + /** + * Returns whether cleartext network traffic (HTTP) is permitted for the provided package. + */ + private boolean isCleartextTrafficPermitted(String packageName) { + PackageManager packageManager = mContext.getPackageManager(); + PackageInfo packageInfo; + try { + packageInfo = packageManager.getPackageInfo(packageName, 0); + } catch (NameNotFoundException e) { + // Unknown package -- fail safe: cleartext traffic not permitted + return false; + } + ApplicationInfo applicationInfo = packageInfo.applicationInfo; + if (applicationInfo == null) { + // No app info -- fail safe: cleartext traffic not permitted + return false; + } + return (applicationInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0; + } } diff --git a/src/com/android/providers/downloads/SystemFacade.java b/src/com/android/providers/downloads/SystemFacade.java index 15fc31f9..83fc7a63 100644 --- a/src/com/android/providers/downloads/SystemFacade.java +++ b/src/com/android/providers/downloads/SystemFacade.java @@ -61,4 +61,9 @@ interface SystemFacade { * Returns true if the specified UID owns the specified package name. */ public boolean userOwnsPackage(int uid, String pckg) throws NameNotFoundException; + + /** + * Returns true if cleartext network traffic is permitted for the specified UID. + */ + public boolean isCleartextTrafficPermitted(int uid); } |