added i2p support in CertifyKeyFragment and ImportKeyFragment

This commit is contained in:
Adithya Abraham Philip 2015-06-13 01:50:41 +05:30
parent b4f9eafa7b
commit d3fbd4f062
10 changed files with 173 additions and 44 deletions

View File

@ -50,6 +50,7 @@ dependencies {
compile 'com.mikepenz.iconics:community-material-typeface:1.0.0@aar'
compile 'com.nispok:snackbar:2.10.8'
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'net.i2p.android:client:0.7@aar'
// libs as submodules
compile project(':extern:openpgp-api-lib:openpgp-api')
@ -188,6 +189,7 @@ android {
// Disable preDexing, causes com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000) on some systems
dexOptions {
preDexLibraries = false
javaMaxHeapSize = "4g"
}
packagingOptions {

View File

@ -66,8 +66,10 @@
<uses-permission android:name="android.permission.WRITE_PROFILE" />
<!-- android:allowBackup="false": Don't allow backup over adb backup or other apps! -->
<!-- tools:replace="android:allowBackup" to accommodate "true" value in net.i2p.android -->
<application
android:name=".KeychainApplication"
tools:replace="android:allowBackup"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"

View File

@ -96,6 +96,7 @@ public final class Constants {
// proxy settings
public static final String USE_NORMAL_PROXY = "useNormalProxy";
public static final String USE_TOR_PROXY = "useTorProxy";
public static final String USE_I2P_PROXY = "useI2pProxy";
public static final String PROXY_HOST = "proxyHost";
public static final String PROXY_PORT = "proxyPort";
public static final String PROXY_TYPE = "proxyType";
@ -110,6 +111,15 @@ public final class Constants {
public static final Proxy.Type PROXY_TYPE = Proxy.Type.HTTP;
}
/**
* information to connect to I2P
*/
public static final class I2p {
public static final String PROXY_HOST = "127.0.0.1";
public static final int PROXY_PORT = 4444;
public static final Proxy.Type PROXY_TYPE = Proxy.Type.HTTP;
}
public static final class Defaults {
public static final String KEY_SERVERS = "hkps://hkps.pool.sks-keyservers.net, hkps://pgp.mit.edu";
public static final int PREF_VERSION = 4;

View File

@ -41,6 +41,7 @@ import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import net.i2p.android.ui.I2PAndroidHelper;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
@ -175,22 +176,27 @@ public class CertifyKeyFragment
if (selectedKeyId == Constants.key.none) {
Notify.create(getActivity(), getString(R.string.select_key_to_certify),
Notify.Style.ERROR).show();
} else {
} else { // check if proxy settings are valid before allowing operation
Runnable ignoreTor = new Runnable() {
@Override
public void run() {
mProxyPrefs = new Preferences.ProxyPrefs(Preferences.ProxyPrefs.Category.NONE, null, -1,
null);
cryptoOperation();
}
};
if (mUploadKeyCheckbox.isChecked() && mProxyPrefs.torEnabled) {
Handler ignoreTorHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mProxyPrefs = new Preferences.ProxyPrefs(false, false, null, -1, null);
cryptoOperation();
}
};
if (!OrbotHelper.isOrbotInstalled(getActivity())) {
OrbotHelper.getInstallDialogFragmentWithThirdButton(new Messenger(ignoreTorHandler),
R.string.orbot_install_dialog_ignore_tor).show(getActivity().getSupportFragmentManager(), "installOrbot");
} else if (!OrbotHelper.isOrbotRunning()) {
OrbotHelper.getOrbotStartDialogFragment(new Messenger(ignoreTorHandler),
R.string.orbot_install_dialog_ignore_tor).show(getActivity().getSupportFragmentManager(), "startOrbot");
if (mUploadKeyCheckbox.isChecked() && mProxyPrefs.category == Preferences.ProxyPrefs.Category.TOR) {
OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, mProxyPrefs,
getActivity());
}
if (mUploadKeyCheckbox.isChecked() && mProxyPrefs.category == Preferences.ProxyPrefs.Category.I2P) {
I2PAndroidHelper helper = new I2PAndroidHelper(getActivity());
if (!helper.isI2PAndroidInstalled()) {
helper.promptToInstall(getActivity());
} else if (!helper.isI2PAndroidRunning()) {
helper.requestI2PAndroidStart(getActivity());
} else {
cryptoOperation();
}

View File

@ -355,7 +355,7 @@ public class ImportKeysActivity extends BaseNfcActivity {
@Override
public void run() {
// disables Tor until Activity is recreated
mProxyPrefs = new Preferences.ProxyPrefs(false, false, null, -1, null);
mProxyPrefs = new Preferences.ProxyPrefs(Preferences.ProxyPrefs.Category.NONE, null, -1, null);
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
}
};

View File

@ -36,6 +36,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import net.i2p.android.ui.I2PAndroidHelper;
import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@ -303,6 +304,7 @@ public class SettingsActivity extends PreferenceActivity {
public static class Initializer {
private CheckBoxPreference mUseTor;
private CheckBoxPreference mUseI2p;
private CheckBoxPreference mUseNormalProxy;
private EditTextPreference mProxyHost;
private EditTextPreference mProxyPort;
@ -310,6 +312,10 @@ public class SettingsActivity extends PreferenceActivity {
private PreferenceActivity mActivity;
private PreferenceFragment mFragment;
private enum ProxyCategory {
TOR, I2P, NORMAL
}
public Initializer(PreferenceFragment fragment) {
mFragment = fragment;
}
@ -341,17 +347,23 @@ public class SettingsActivity extends PreferenceActivity {
}
mUseTor = (CheckBoxPreference) automaticallyFindPreference(Constants.Pref.USE_TOR_PROXY);
mUseI2p = (CheckBoxPreference) automaticallyFindPreference(Constants.Pref.USE_I2P_PROXY);
mUseNormalProxy = (CheckBoxPreference) automaticallyFindPreference(Constants.Pref.USE_NORMAL_PROXY);
mProxyHost = (EditTextPreference) automaticallyFindPreference(Constants.Pref.PROXY_HOST);
mProxyPort = (EditTextPreference) automaticallyFindPreference(Constants.Pref.PROXY_PORT);
mProxyType = (ListPreference) automaticallyFindPreference(Constants.Pref.PROXY_TYPE);
initializeUseTorPref();
initializeUseI2pPref();
initializeUseNormalProxyPref();
initializeEditTextPreferences();
initializeProxyTypePreference();
if (mUseTor.isChecked()) disableNormalProxyPrefs();
else if (mUseNormalProxy.isChecked()) disableUseTorPrefs();
if (mUseTor.isChecked()) disablePrefsOtherThan(ProxyCategory.TOR);
else if (mUseNormalProxy.isChecked()) disablePrefsOtherThan(ProxyCategory.NORMAL);
else if (mUseI2p.isChecked()) disablePrefsOtherThan(ProxyCategory.I2P);
}
private void initializeUseTorPref() {
@ -368,14 +380,45 @@ public class SettingsActivity extends PreferenceActivity {
// don't let the user check the box until he's installed orbot
return false;
} else {
disableNormalProxyPrefs();
disablePrefsOtherThan(ProxyCategory.TOR);
// let the enable tor box be checked
return true;
}
}
else {
// we're unchecking Tor, so enable other proxy
enableNormalProxyPrefs();
enableAllProxyPrefs();
return true;
}
}
});
}
private void initializeUseI2pPref() {
mUseI2p.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// checks whether the Initializer is being used from a fragment or activity, and acts
// accordingly
Activity activity = mFragment != null ? mFragment.getActivity() : mActivity;
if ((Boolean)newValue) {
I2PAndroidHelper i2pHelper = new I2PAndroidHelper(activity);
boolean installed = i2pHelper.isI2PAndroidInstalled();
if (!installed) {
Log.d(Constants.TAG, "Prompting to install I2P");
i2pHelper.promptToInstall(activity);
// don't let the user check the box until he's installed I2P
return false;
} else {
disablePrefsOtherThan(ProxyCategory.I2P);
// let the enable I2P box be checked
return true;
}
}
else {
// we're unchecking I2P, so enable other proxy options
enableAllProxyPrefs();
return true;
}
}
@ -387,9 +430,9 @@ public class SettingsActivity extends PreferenceActivity {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if ((Boolean) newValue) {
disableUseTorPrefs();
disablePrefsOtherThan(ProxyCategory.NORMAL);
} else {
enableUseTorPrefs();
enableAllProxyPrefs();
}
return true;
}
@ -460,6 +503,29 @@ public class SettingsActivity extends PreferenceActivity {
});
}
private void disablePrefsOtherThan(ProxyCategory type) {
switch(type) {
case TOR:
disableNormalProxyPrefs();
disableI2pPrefs();
break;
case I2P:
disableTorPrefs();
disableNormalProxyPrefs();
break;
case NORMAL:
disableI2pPrefs();
disableTorPrefs();
break;
}
}
private void enableAllProxyPrefs() {
enableTorPrefs();
enableI2pPrefs();
enableNormalProxyPrefs();
}
private void disableNormalProxyPrefs() {
mUseNormalProxy.setChecked(false);
mUseNormalProxy.setEnabled(false);
@ -475,14 +541,23 @@ public class SettingsActivity extends PreferenceActivity {
mProxyType.setEnabled(true);
}
private void disableUseTorPrefs() {
private void disableTorPrefs() {
mUseTor.setChecked(false);
mUseTor.setEnabled(false);
}
private void enableUseTorPrefs() {
private void enableTorPrefs() {
mUseTor.setEnabled(true);
}
private void disableI2pPrefs() {
mUseI2p.setChecked(false);
mUseI2p.setEnabled(false);
}
private void enableI2pPrefs() {
mUseI2p.setEnabled(true);
}
}
}
@ -491,6 +566,7 @@ public class SettingsActivity extends PreferenceActivity {
protected boolean isValidFragment(String fragmentName) {
return AdvancedPrefsFragment.class.getName().equals(fragmentName)
|| CloudSearchPrefsFragment.class.getName().equals(fragmentName)
|| ProxyPrefsFragment.class.getName().equals(fragmentName)
|| super.isValidFragment(fragmentName);
}

View File

@ -247,6 +247,10 @@ public class Preferences {
return mSharedPreferences.getBoolean(Constants.Pref.USE_TOR_PROXY, false);
}
public boolean getUseI2pProxy() {
return mSharedPreferences.getBoolean(Pref.USE_I2P_PROXY, false);
}
public String getProxyHost() {
return mSharedPreferences.getString(Constants.Pref.PROXY_HOST, null);
}
@ -285,36 +289,58 @@ public class Preferences {
}
}
public ProxyPrefs getProxyPrefs() {
public ProxyPrefs.Category getProxyCategory() {
boolean useTor = getUseTorProxy();
boolean useNormalProxy = getUseNormalProxy();
boolean useI2p = getUseI2pProxy();
if (useTor) {
return new ProxyPrefs(true, false, Constants.Orbot.PROXY_HOST, Constants.Orbot.PROXY_PORT,
Constants.Orbot.PROXY_TYPE);
}
else if (useNormalProxy) {
return new ProxyPrefs(useTor, useNormalProxy, getProxyHost(), getProxyPort(), getProxyType());
} else {
return new ProxyPrefs(false, false, null, -1, null);
if (useI2p) return ProxyPrefs.Category.I2P;
if (useTor) return ProxyPrefs.Category.TOR;
if (useNormalProxy) return ProxyPrefs.Category.NORMAL;
return ProxyPrefs.Category.NONE;
}
public ProxyPrefs getProxyPrefs() {
String proxyHost = null;
int proxyPort = -1;
Proxy.Type proxyType = null;
ProxyPrefs.Category category = getProxyCategory();
switch (category) {
case TOR:
proxyHost = Constants.Orbot.PROXY_HOST;
proxyPort = Constants.Orbot.PROXY_PORT;
proxyType = Constants.Orbot.PROXY_TYPE;
break;
case I2P:
proxyHost = Constants.I2p.PROXY_HOST;
proxyPort = Constants.I2p.PROXY_PORT;
proxyType = Constants.I2p.PROXY_TYPE;
break;
case NORMAL:
proxyHost = getProxyHost();
proxyPort = getProxyPort();
proxyType = getProxyType();
break;
// if NONE, do nothing, leave at default values
}
return new ProxyPrefs(category, proxyHost, proxyPort, proxyType);
}
public static class ProxyPrefs {
public final Category category;
public final ParcelableProxy parcelableProxy;
public final boolean torEnabled;
public final boolean normalPorxyEnabled;
public enum Category {
TOR, I2P, NORMAL, NONE
}
/**
* torEnabled and normalProxyEnabled are not expected to both be true
*
* @param torEnabled if Tor is to be used
* @param normalPorxyEnabled if user-specified proxy is to be used
* a null proxy has category null
*/
public ProxyPrefs(boolean torEnabled, boolean normalPorxyEnabled, String hostName, int port, Proxy.Type type) {
this.torEnabled = torEnabled;
this.normalPorxyEnabled = normalPorxyEnabled;
if(!torEnabled && !normalPorxyEnabled) this.parcelableProxy = new ParcelableProxy(null, -1, null);
public ProxyPrefs(Category catgeory, String hostName, int port, Proxy.Type type) {
this.category = catgeory;
if(category == Category.NONE) this.parcelableProxy = new ParcelableProxy(null, -1, null);
else this.parcelableProxy = new ParcelableProxy(hostName, port, type);
}
}

View File

@ -155,7 +155,7 @@ public class OrbotHelper {
}
};
if (!proxyPrefs.torEnabled) {
if (!(proxyPrefs.category == Preferences.ProxyPrefs.Category.TOR)) {
return true;
}

View File

@ -169,6 +169,8 @@
<!-- Proxy Preferences -->
<string name="pref_proxy_tor_title">"Enable Tor"</string>
<string name="pref_proxy_tor_summary">"Requires Orbot to be installed"</string>
<string name="pref_proxy_i2p_title">"Enable I2P"</string>
<string name="pref_proxy_i2p_summary">"Requires I2P to be installed"</string>
<string name="pref_proxy_normal_title">"Enable other proxy"</string>
<string name="pref_proxy_host_title">"Proxy Host"</string>
<string name="pref_proxy_host_err_invalid">"Proxy host cannot be empty"</string>

View File

@ -5,6 +5,11 @@
android:persistent="true"
android:title="@string/pref_proxy_tor_title"
android:summary="@string/pref_proxy_tor_summary" />
<CheckBoxPreference
android:key="useI2pProxy"
android:persistent="true"
android:title="@string/pref_proxy_i2p_title"
android:summary="@string/pref_proxy_i2p_summary" />
<CheckBoxPreference
android:key="useNormalProxy"
android:persistent="true"