diff --git a/F-Droid/assets/index.template.html b/F-Droid/assets/index.template.html index fd77b404b..f2f9cee82 100644 --- a/F-Droid/assets/index.template.html +++ b/F-Droid/assets/index.template.html @@ -105,10 +105,5 @@ Not done -
- - Or, download apps from the web - -
diff --git a/F-Droid/build.gradle b/F-Droid/build.gradle index 310c96210..d3d334330 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 @@ -36,7 +37,9 @@ if (!hasProperty('sourceDeps')) { // yet (seems to be a little unsupported as of late), so not using mavenCentral/jcenter. compile(name: 'nanohttpd-2.1.0') - // Upstream doesn't have a binary on mavenCentral. Looks discontinued. + // Upstream doesn't have a binary on mavenCentral, and it is an SVN repo on + // Google Code. We include this code directly in this repo, and have made + // modifications that should be pushed to anyone who wants to maintain it. compile(name: 'zipsigner') // Project semi-abandoned, 3.4.1 is from 2011 and we use trunk from 2013 @@ -68,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/libs/binaryDeps/zipsigner.jar b/F-Droid/libs/binaryDeps/zipsigner.jar index 1e741d758..1a870774e 100644 Binary files a/F-Droid/libs/binaryDeps/zipsigner.jar and b/F-Droid/libs/binaryDeps/zipsigner.jar differ diff --git a/F-Droid/src/org/fdroid/fdroid/FDroidApp.java b/F-Droid/src/org/fdroid/fdroid/FDroidApp.java index 0c140a5d5..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 = ""; } @@ -153,9 +156,10 @@ public class FDroidApp extends Application { c.getResources().updateConfiguration(cfg, null); } + @TargetApi(9) @Override public void onCreate() { - if (BuildConfig.DEBUG) { + if (Build.VERSION.SDK_INT >= 9 && BuildConfig.DEBUG) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/LocalRepoManager.java b/F-Droid/src/org/fdroid/fdroid/localrepo/LocalRepoManager.java index e404db88d..c23278e83 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/LocalRepoManager.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/LocalRepoManager.java @@ -345,11 +345,13 @@ public class LocalRepoManager { serializer = XmlPullParserFactory.newInstance().newSerializer(); } - public void build(Writer output) throws IOException, LocalRepoKeyStore.InitException { + public void build(File file) throws IOException, LocalRepoKeyStore.InitException { + Writer output = new FileWriter(file); serializer.setOutput(output); serializer.startDocument(null, null); tagFdroid(); serializer.endDocument(); + output.close(); } private void tagFdroid() throws IOException, LocalRepoKeyStore.InitException { @@ -485,7 +487,7 @@ public class LocalRepoManager { public void writeIndexJar() throws IOException { try { - new IndexXmlBuilder(context, apps).build(new FileWriter(xmlIndex)); + new IndexXmlBuilder(context, apps).build(xmlIndex); } catch (Exception e) { Log.e(TAG, "Could not write index jar", e); Toast.makeText(context, R.string.failed_to_create_index, Toast.LENGTH_LONG).show(); 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) { diff --git a/extern/zipsigner/src/main/java/kellinwood/security/zipsigner/ZipSigner.java b/extern/zipsigner/src/main/java/kellinwood/security/zipsigner/ZipSigner.java index d5c0604b2..8bc9aea5c 100644 --- a/extern/zipsigner/src/main/java/kellinwood/security/zipsigner/ZipSigner.java +++ b/extern/zipsigner/src/main/java/kellinwood/security/zipsigner/ZipSigner.java @@ -378,8 +378,10 @@ public class ZipSigner Manifest input = null; ZioEntry manifestEntry = entries.get(JarFile.MANIFEST_NAME); if (manifestEntry != null) { + InputStream is = manifestEntry.getInputStream(); input = new Manifest(); - input.read( manifestEntry.getInputStream()); + input.read(is); + is.close(); } Manifest output = new Manifest(); Attributes main = output.getMainAttributes(); @@ -645,6 +647,7 @@ public class ZipSigner ZipInput input = ZipInput.read( inputZipFilename); signZip( input.getEntries(), new FileOutputStream( outputZipFilename), outputZipFilename); + input.close(); } /** Sign the