From c7b076e5ea29869c0c240421607e22f940ef421b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 2 Dec 2013 20:12:52 -0500 Subject: [PATCH] add detailed checking of incoming repos based on fingerprint in DB When a new repo is being added, whether manually or via an incoming Intent, check the address and fingerprint against repos in the DB. If the repo is not in the DB, offer to add it. If the repo address is in the DB, then do more checks: * If that address has no fingerprint in the DB, then offer to add the new repo including that fingerprint. This might happen when upgrading a repo from unsigned to signed. * if the incoming info matches a repo in the DB, offer to enable that repo * if the address matches a repo in the DB but the incoming fingerprint does not match the fingerprint in the DB, warn the user, and tell them to delete the existing repo if they truly want to override the existing info --- res/layout/addrepo.xml | 23 ++---- res/values/strings.xml | 7 +- src/org/fdroid/fdroid/ManageRepo.java | 107 ++++++++++++++++++-------- 3 files changed, 86 insertions(+), 51 deletions(-) diff --git a/res/layout/addrepo.xml b/res/layout/addrepo.xml index 95882888e..0638049ee 100644 --- a/res/layout/addrepo.xml +++ b/res/layout/addrepo.xml @@ -4,17 +4,6 @@ android:layout_height="wrap_content" android:orientation="vertical" > - - - diff --git a/res/values/strings.xml b/res/values/strings.xml index 58f105812..fcf48814a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -56,6 +56,9 @@ Add Cancel + Enable + Add Key + Overwrite Choose repository to remove Update repositories @@ -72,7 +75,9 @@ Repository address fingerprint (optional) This repo already exists! - Overwrite the existing repo? + This repo is already setup, this will add new key information. + This repo is already setup, confirm that you want to re-enable it. + You must first delete this repo before you can add one with a different key! The list of used repositories has changed.\nDo you diff --git a/src/org/fdroid/fdroid/ManageRepo.java b/src/org/fdroid/fdroid/ManageRepo.java index b9913b293..8555d90d8 100644 --- a/src/org/fdroid/fdroid/ManageRepo.java +++ b/src/org/fdroid/fdroid/ManageRepo.java @@ -35,24 +35,21 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.support.v4.app.NavUtils; +import android.support.v4.view.MenuItemCompat; import android.text.format.DateFormat; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.View.OnClickListener; import android.widget.Button; -import android.widget.CheckBox; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import org.fdroid.fdroid.DB.Repo; -import android.support.v4.app.NavUtils; -import android.support.v4.view.MenuItemCompat; - import org.fdroid.fdroid.compat.ActionBarCompat; public class ManageRepo extends ListActivity { @@ -62,6 +59,11 @@ public class ManageRepo extends ListActivity { private boolean changed = false; + private enum PositiveAction { + ADD_NEW, ENABLE, IGNORE + } + private PositiveAction positiveAction; + private List repos; private static List reposToDisable; @@ -231,10 +233,10 @@ public class ManageRepo extends ListActivity { return repos; } - protected Repo getRepo(String repoUri, List repos) { - if (repoUri != null) + protected Repo getRepoByAddress(String address, List repos) { + if (address != null) for (Repo repo : repos) - if (repoUri.equals(repo.address)) + if (address.equals(repo.address)) return repo; return null; } @@ -249,7 +251,7 @@ public class ManageRepo extends ListActivity { return super.onOptionsItemSelected(item); } - private void showAddRepo(String uriString, String fingerprint) { + private void showAddRepo(String newAddress, String newFingerprint) { LayoutInflater li = LayoutInflater.from(this); View view = li.inflate(R.layout.addrepo, null); Builder p = new AlertDialog.Builder(this).setView(view); @@ -257,6 +259,9 @@ public class ManageRepo extends ListActivity { final EditText uriEditText = (EditText) view.findViewById(R.id.edit_uri); final EditText fingerprintEditText = (EditText) view.findViewById(R.id.edit_fingerprint); + List repos = getRepos(); + final Repo repo = getRepoByAddress(newAddress, repos); + alrt.setIcon(android.R.drawable.ic_menu_add); alrt.setTitle(getString(R.string.repo_add_title)); alrt.setButton(DialogInterface.BUTTON_POSITIVE, @@ -264,10 +269,15 @@ public class ManageRepo extends ListActivity { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - addRepo(uriEditText.getText().toString(), - fingerprintEditText.getText().toString()); - changed = true; - redraw(); + String fp = fingerprintEditText.getText().toString(); + // the DB uses null for no fingerprint but the above + // code returns "" rather than null if its blank + if (fp.equals("")) + fp = null; + if (positiveAction == PositiveAction.ADD_NEW) + addRepoPositiveAction(uriEditText.getText().toString(), fp, null); + else if (positiveAction == PositiveAction.ENABLE) + addRepoPositiveAction(null, null, repo); } }); @@ -281,30 +291,59 @@ public class ManageRepo extends ListActivity { }); alrt.show(); - List repos = getRepos(); - Repo repo = getRepo(uriString, repos); - if (repo != null) { - TextView tv = (TextView) view.findViewById(R.id.repo_alert); - tv.setVisibility(0); - tv.setText(R.string.repo_exists); + final TextView overwriteMessage = (TextView) view.findViewById(R.id.overwrite_message); + overwriteMessage.setVisibility(View.GONE); + if (repo == null) { + // no existing repo, add based on what we have + positiveAction = PositiveAction.ADD_NEW; + } else { + // found the address in the DB of existing repos final Button addButton = alrt.getButton(DialogInterface.BUTTON_POSITIVE); - addButton.setEnabled(false); - final CheckBox overwriteCheckBox = (CheckBox) view.findViewById(R.id.overwrite_repo); - overwriteCheckBox.setVisibility(0); - overwriteCheckBox.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - addButton.setEnabled(overwriteCheckBox.isChecked()); - } - }); - // TODO if address and fingerprint match, then enable existing repo - // TODO if address matches but fingerprint doesn't, handle this with extra widgets + alrt.setTitle(R.string.repo_exists); + overwriteMessage.setVisibility(View.VISIBLE); + if (repo.fingerprint == null && newFingerprint != null) { + // we're upgrading from unsigned to signed repo + overwriteMessage.setText(R.string.repo_exists_add_fingerprint); + addButton.setText(R.string.add_key); + positiveAction = PositiveAction.ADD_NEW; + } else if (newFingerprint == null || newFingerprint.equals(repo.fingerprint)) { + // this entry already exists, offer to enable it + overwriteMessage.setText(R.string.repo_exists_enable); + addButton.setText(R.string.enable); + positiveAction = PositiveAction.ENABLE; + } else { + // same address with different fingerprint, this could be + // malicious, so force the user to manually delete the repo + // before adding this one + overwriteMessage.setTextColor(getResources().getColor(R.color.red)); + overwriteMessage.setText(R.string.repo_delete_to_overwrite); + addButton.setText(R.string.overwrite); + addButton.setEnabled(false); + positiveAction = PositiveAction.IGNORE; + } } - if (uriString != null) - uriEditText.setText(uriString); - if (fingerprint != null) - fingerprintEditText.setText(fingerprint); + if (newAddress != null) + uriEditText.setText(newAddress); + if (newFingerprint != null) + fingerprintEditText.setText(newFingerprint); + } + + private void addRepoPositiveAction(String address, String fingerprint, Repo repo) { + if (address != null) { + addRepo(address, fingerprint); + } else if (repo != null) { + // force-enable an existing repo + repo.inuse = true; + try { + DB db = DB.getDB(); + db.updateRepoByAddress(repo); + } finally { + DB.releaseDB(); + } + } + changed = true; + redraw(); } @Override