diff --git a/F-Droid/build.gradle b/F-Droid/build.gradle index 0e26dca10..270be4936 100644 --- a/F-Droid/build.gradle +++ b/F-Droid/build.gradle @@ -27,6 +27,7 @@ if (!hasProperty('sourceDeps')) { compile 'com.madgag.spongycastle:pkix:1.51.0.0' compile 'com.madgag.spongycastle:prov:1.51.0.0' compile 'com.madgag.spongycastle:core:1.51.0.0' + compile 'commons-net:commons-net:3.3' // Upstream doesn't have a binary on mavenCentral/jcenter yet: // https://github.com/kolavar/android-support-v4-preferencefragment/issues/13 @@ -70,6 +71,7 @@ if (!hasProperty('sourceDeps')) { compile 'eu.chainfire:libsuperuser:1.0.0.201504231659' compile 'cc.mvdan.accesspoint:library:0.1.1' compile 'info.guardianproject.netcipher:netcipher:1.2' + compile 'commons-net:commons-net:3.3' compile(project(':extern:support-v4-preferencefragment')) { exclude module: 'support-v4' diff --git a/F-Droid/src/org/fdroid/fdroid/FDroidApp.java b/F-Droid/src/org/fdroid/fdroid/FDroidApp.java index b10d43932..554722e15 100644 --- a/F-Droid/src/org/fdroid/fdroid/FDroidApp.java +++ b/F-Droid/src/org/fdroid/fdroid/FDroidApp.java @@ -44,6 +44,7 @@ import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.utils.StorageUtils; +import org.apache.commons.net.util.SubnetUtils; import org.fdroid.fdroid.Preferences.ChangeListener; import org.fdroid.fdroid.compat.PRNGFixes; import org.fdroid.fdroid.data.AppProvider; @@ -68,6 +69,7 @@ public class FDroidApp extends Application { // for the local repo on this device, all static since there is only one public static int port; public static String ipAddressString; + public static SubnetUtils.SubnetInfo subnetInfo; public static String ssid; public static String bssid; public static final Repo repo = new Repo(); @@ -135,6 +137,7 @@ public class FDroidApp extends Application { public static void initWifiSettings() { port = 8888; ipAddressString = null; + subnetInfo = (new SubnetUtils("0.0.0.0/32").getInfo()); ssid = ""; bssid = ""; } diff --git a/F-Droid/src/org/fdroid/fdroid/net/HttpDownloader.java b/F-Droid/src/org/fdroid/fdroid/net/HttpDownloader.java index dcdf7c683..241a73cee 100644 --- a/F-Droid/src/org/fdroid/fdroid/net/HttpDownloader.java +++ b/F-Droid/src/org/fdroid/fdroid/net/HttpDownloader.java @@ -5,6 +5,7 @@ import android.util.Log; import com.nostra13.universalimageloader.core.download.BaseImageDownloader; +import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Utils; @@ -84,11 +85,18 @@ public class HttpDownloader extends Downloader { } } + boolean isSwapUrl() { + String host = sourceUrl.getHost(); + return sourceUrl.getPort() > 1023 // only root can use <= 1023, so never a swap repo + && host.matches("[0-9.]+") // host must be an IP address + && FDroidApp.subnetInfo.isInRange(host); // on the same subnet as we are + } + protected void setupConnection() throws IOException { if (connection != null) return; Preferences prefs = Preferences.get(); - if (prefs.isProxyEnabled()) { + if (prefs.isProxyEnabled() && ! isSwapUrl()) { SocketAddress sa = new InetSocketAddress(prefs.getProxyHost(), prefs.getProxyPort()); Proxy proxy = new Proxy(Proxy.Type.HTTP, sa); NetCipher.setProxy(proxy); diff --git a/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java b/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java index 88eeeda11..ed058d7ab 100644 --- a/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java +++ b/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java @@ -1,5 +1,6 @@ package org.fdroid.fdroid.net; +import android.annotation.TargetApi; import android.app.Service; import android.content.ComponentName; import android.content.Context; @@ -9,10 +10,13 @@ import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.AsyncTask; +import android.os.Build; import android.os.IBinder; import android.support.v4.content.LocalBroadcastManager; +import android.text.TextUtils; import android.util.Log; +import org.apache.commons.net.util.SubnetUtils; import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; @@ -23,6 +27,7 @@ import org.fdroid.fdroid.localrepo.SwapService; import java.net.Inet6Address; import java.net.InetAddress; +import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.security.cert.Certificate; @@ -80,14 +85,17 @@ public class WifiStateChangeService extends Service { if (wifiState == WifiManager.WIFI_STATE_ENABLED) { wifiInfo = wifiManager.getConnectionInfo(); FDroidApp.ipAddressString = formatIpAddress(wifiInfo.getIpAddress()); + String netmask = formatIpAddress(wifiManager.getDhcpInfo().netmask); + if (!TextUtils.isEmpty(FDroidApp.ipAddressString)) + FDroidApp.subnetInfo = new SubnetUtils(FDroidApp.ipAddressString, netmask).getInfo(); } else if (wifiState == WifiManager.WIFI_STATE_DISABLED || wifiState == WifiManager.WIFI_STATE_DISABLING) { // try once to see if its a hotspot - FDroidApp.ipAddressString = getIpAddressFromNetworkInterface(); + setIpInfoFromNetworkInterface(); if (FDroidApp.ipAddressString == null) return null; } else { // a hotspot can be active during WIFI_STATE_UNKNOWN - FDroidApp.ipAddressString = getIpAddressFromNetworkInterface(); + setIpInfoFromNetworkInterface(); } if (FDroidApp.ipAddressString == null) { @@ -179,7 +187,8 @@ public class WifiStateChangeService extends Service { return null; } - public String getIpAddressFromNetworkInterface() { + @TargetApi(9) + public void setIpInfoFromNetworkInterface() { try { for (Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); networkInterfaces.hasMoreElements(); ) { NetworkInterface netIf = networkInterfaces.nextElement(); @@ -191,15 +200,23 @@ public class WifiStateChangeService extends Service { } else if (netIf.getDisplayName().contains("wlan0") || netIf.getDisplayName().contains("eth0") || netIf.getDisplayName().contains("ap0")) { - return inetAddress.getHostAddress(); + FDroidApp.ipAddressString = inetAddress.getHostAddress(); + if (Build.VERSION.SDK_INT < 9) + return; + // the following methods were not added until android-9/Gingerbread + for (InterfaceAddress address : netIf.getInterfaceAddresses()) { + if (inetAddress.equals(address.getAddress()) && ! TextUtils.isEmpty(FDroidApp.ipAddressString)) { + String cidr = String.format("%s/%i", FDroidApp.ipAddressString, address.getNetworkPrefixLength()); + FDroidApp.subnetInfo = (new SubnetUtils(cidr)).getInfo(); + break; + } + } } } } } catch (SocketException e) { Log.e(TAG, "Could not get ip address", e); } - - return null; } private String formatIpAddress(int ipAddress) {