Merge branch 'ever-more-bug-fixes' into 'master'

Ever more bug fixes

Closes #1262, #1484, #1224, #70, and #1448

See merge request fdroid/fdroidclient!713
This commit is contained in:
Hans-Christoph Steiner 2018-07-19 13:50:52 +00:00
commit ac7916298a
7 changed files with 60 additions and 16 deletions

View File

@ -429,14 +429,14 @@ public class IndexV1Updater extends RepoUpdater {
String certFromJar = Hasher.hex(rawCertFromJar); String certFromJar = Hasher.hex(rawCertFromJar);
if (TextUtils.isEmpty(certFromJar)) { if (TextUtils.isEmpty(certFromJar)) {
throw new SigningException(SIGNED_FILE_NAME + " must have an included signing certificate!"); throw new SigningException(repo, SIGNED_FILE_NAME + " must have an included signing certificate!");
} }
if (repo.signingCertificate == null) { if (repo.signingCertificate == null) {
if (repo.fingerprint != null) { if (repo.fingerprint != null) {
String fingerprintFromJar = Utils.calcFingerprint(rawCertFromJar); String fingerprintFromJar = Utils.calcFingerprint(rawCertFromJar);
if (!repo.fingerprint.equalsIgnoreCase(fingerprintFromJar)) { if (!repo.fingerprint.equalsIgnoreCase(fingerprintFromJar)) {
throw new SigningException("Supplied certificate fingerprint does not match!"); throw new SigningException(repo, "Supplied certificate fingerprint does not match!");
} }
} }
Utils.debugLog(TAG, "Saving new signing certificate to database for " + repo.address); Utils.debugLog(TAG, "Saving new signing certificate to database for " + repo.address);
@ -448,14 +448,14 @@ public class IndexV1Updater extends RepoUpdater {
} }
if (TextUtils.isEmpty(repo.signingCertificate)) { if (TextUtils.isEmpty(repo.signingCertificate)) {
throw new SigningException("A empty repo signing certificate is invalid!"); throw new SigningException(repo, "A empty repo signing certificate is invalid!");
} }
if (repo.signingCertificate.equals(certFromJar)) { if (repo.signingCertificate.equals(certFromJar)) {
return; // we have a match! return; // we have a match!
} }
throw new SigningException("Signing certificate does not match!"); throw new SigningException(repo, "Signing certificate does not match!");
} }
/** /**

View File

@ -351,6 +351,10 @@ public class RepoUpdater {
public SigningException(String message) { public SigningException(String message) {
super("Repository was not signed correctly: " + message); super("Repository was not signed correctly: " + message);
} }
public SigningException(Repo repo, String message) {
super((repo == null ? "Repository" : repo.name) + " was not signed correctly: " + message);
}
} }
/** /**
@ -395,7 +399,7 @@ public class RepoUpdater {
String fingerprintFromJar = Utils.calcFingerprint(rawCertFromJar); String fingerprintFromJar = Utils.calcFingerprint(rawCertFromJar);
if (!repo.fingerprint.equalsIgnoreCase(fingerprintFromIndexXml) if (!repo.fingerprint.equalsIgnoreCase(fingerprintFromIndexXml)
|| !repo.fingerprint.equalsIgnoreCase(fingerprintFromJar)) { || !repo.fingerprint.equalsIgnoreCase(fingerprintFromJar)) {
throw new SigningException("Supplied certificate fingerprint does not match!"); throw new SigningException(repo, "Supplied certificate fingerprint does not match!");
} }
} // else - no info to check things are valid, so just Trust On First Use } // else - no info to check things are valid, so just Trust On First Use
@ -426,7 +430,7 @@ public class RepoUpdater {
if (TextUtils.isEmpty(repo.signingCertificate) if (TextUtils.isEmpty(repo.signingCertificate)
|| TextUtils.isEmpty(certFromJar) || TextUtils.isEmpty(certFromJar)
|| TextUtils.isEmpty(certFromIndexXml)) { || TextUtils.isEmpty(certFromIndexXml)) {
throw new SigningException("A empty repo or signing certificate is invalid!"); throw new SigningException(repo, "A empty repo or signing certificate is invalid!");
} }
// though its called repo.signingCertificate, its actually a X509 certificate // though its called repo.signingCertificate, its actually a X509 certificate
@ -435,7 +439,7 @@ public class RepoUpdater {
&& certFromIndexXml.equals(certFromJar)) { && certFromIndexXml.equals(certFromJar)) {
return; // we have a match! return; // we have a match!
} }
throw new SigningException("Signing certificate does not match!"); throw new SigningException(repo, "Signing certificate does not match!");
} }
/** /**

View File

@ -21,9 +21,11 @@
package org.fdroid.fdroid.views; package org.fdroid.fdroid.views;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.support.v4.app.ShareCompat;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
@ -31,6 +33,8 @@ import android.view.MenuItem;
import android.widget.TextView; import android.widget.TextView;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.installer.InstallHistoryService; import org.fdroid.fdroid.installer.InstallHistoryService;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@ -81,6 +85,26 @@ public class InstallHistoryActivity extends AppCompatActivity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.menu_share:
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Repos:\n");
for (Repo repo : RepoProvider.Helper.all(this)) {
if (repo.inuse) {
stringBuilder.append("* ");
stringBuilder.append(repo.address);
stringBuilder.append('\n');
}
}
ShareCompat.IntentBuilder intentBuilder = ShareCompat.IntentBuilder.from(this)
.setStream(InstallHistoryService.LOG_URI)
.setSubject(getString(R.string.send_history_csv, getString(R.string.app_name)))
.setChooserTitle(R.string.send_install_history)
.setText(stringBuilder.toString())
.setType("text/plain");
Intent intent = intentBuilder.getIntent();
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
break;
case R.id.menu_delete: case R.id.menu_delete:
getContentResolver().delete(InstallHistoryService.LOG_URI, null, null); getContentResolver().delete(InstallHistoryService.LOG_URI, null, null);
TextView textView = findViewById(R.id.text); TextView textView = findViewById(R.id.text);

View File

@ -715,9 +715,14 @@ public class ManageReposActivity extends AppCompatActivity
path = path.substring(0, path.length() - 1); path = path.substring(0, path.length() - 1);
} }
} }
return new URI(uri.getScheme().toLowerCase(Locale.ENGLISH), String scheme = uri.getScheme();
String host = uri.getHost();
if (TextUtils.isEmpty(scheme) || TextUtils.isEmpty(host)) {
return urlString;
}
return new URI(scheme.toLowerCase(Locale.ENGLISH),
uri.getUserInfo(), uri.getUserInfo(),
uri.getHost().toLowerCase(Locale.ENGLISH), host.toLowerCase(Locale.ENGLISH),
uri.getPort(), uri.getPort(),
path, path,
uri.getQuery(), uri.getQuery(),

View File

@ -101,6 +101,8 @@ public class PreferencesFragment extends PreferenceFragment
private SwitchPreference useTorCheckPref; private SwitchPreference useTorCheckPref;
private Preference updateAutoDownloadPref; private Preference updateAutoDownloadPref;
private Preference updatePrivilegedExtensionPref; private Preference updatePrivilegedExtensionPref;
private CheckBoxPreference keepInstallHistoryPref;
private Preference installHistoryPref;
private long currentKeepCacheTime; private long currentKeepCacheTime;
private int overWifiPrevious; private int overWifiPrevious;
private int overDataPrevious; private int overDataPrevious;
@ -114,6 +116,10 @@ public class PreferencesFragment extends PreferenceFragment
addPreferencesFromResource(R.xml.preferences); addPreferencesFromResource(R.xml.preferences);
otherPrefGroup = (PreferenceGroup) findPreference("pref_category_other"); otherPrefGroup = (PreferenceGroup) findPreference("pref_category_other");
keepInstallHistoryPref = (CheckBoxPreference) findPreference(Preferences.PREF_KEEP_INSTALL_HISTORY);
installHistoryPref = findPreference("installHistory");
installHistoryPref.setVisible(keepInstallHistoryPref.isChecked());
useTorCheckPref = (SwitchPreference) findPreference(Preferences.PREF_USE_TOR); useTorCheckPref = (SwitchPreference) findPreference(Preferences.PREF_USE_TOR);
enableProxyCheckPref = (SwitchPreference) findPreference(Preferences.PREF_ENABLE_PROXY); enableProxyCheckPref = (SwitchPreference) findPreference(Preferences.PREF_ENABLE_PROXY);
updateAutoDownloadPref = findPreference(Preferences.PREF_AUTO_DOWNLOAD_INSTALL_UPDATES); updateAutoDownloadPref = findPreference(Preferences.PREF_AUTO_DOWNLOAD_INSTALL_UPDATES);
@ -338,14 +344,12 @@ public class PreferencesFragment extends PreferenceFragment
break; break;
case Preferences.PREF_KEEP_INSTALL_HISTORY: case Preferences.PREF_KEEP_INSTALL_HISTORY:
CheckBoxPreference p = (CheckBoxPreference) findPreference(key); if (keepInstallHistoryPref.isChecked()) {
Preference installHistory = findPreference("installHistory");
if (p.isChecked()) {
InstallHistoryService.register(getActivity()); InstallHistoryService.register(getActivity());
installHistory.setVisible(true); installHistoryPref.setVisible(true);
} else { } else {
InstallHistoryService.unregister(getActivity()); InstallHistoryService.unregister(getActivity());
installHistory.setVisible(false); installHistoryPref.setVisible(false);
} }
break; break;
} }

View File

@ -1,7 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_share"
android:icon="@drawable/ic_share_white"
android:title="@string/menu_share"
app:showAsAction="ifRoom"/>
<item <item
android:id="@+id/menu_delete" android:id="@+id/menu_delete"
android:icon="@android:drawable/ic_delete" android:icon="@drawable/ic_delete_white"
android:title="@string/delete"/> android:title="@string/delete"/>
</menu> </menu>

View File

@ -24,6 +24,8 @@
<string name="hide_all_notifications_summary">Prevent all actions from showing in the status bar and notification <string name="hide_all_notifications_summary">Prevent all actions from showing in the status bar and notification
drawer. drawer.
</string> </string>
<string name="send_install_history">Send Install History</string>
<string name="send_history_csv">%s install history as CSV file</string>
<string name="install_history">Install history</string> <string name="install_history">Install history</string>
<string name="install_history_summary">View the private log of all installs and uninstalls</string> <string name="install_history_summary">View the private log of all installs and uninstalls</string>
<string name="keep_install_history">Keep install history</string> <string name="keep_install_history">Keep install history</string>