mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 17:22:16 -05:00
added proxy/tor preferences
This commit is contained in:
parent
0b3317600b
commit
8f332fad6b
@ -91,6 +91,17 @@ public final class Constants {
|
|||||||
public static final String FILE_USE_COMPRESSION = "useFileCompression";
|
public static final String FILE_USE_COMPRESSION = "useFileCompression";
|
||||||
public static final String TEXT_USE_COMPRESSION = "useTextCompression";
|
public static final String TEXT_USE_COMPRESSION = "useTextCompression";
|
||||||
public static final String USE_ARMOR = "useArmor";
|
public static final String USE_ARMOR = "useArmor";
|
||||||
|
// proxy settings
|
||||||
|
public static final String USE_NORMAL_PROXY = "useNormalProxy";
|
||||||
|
public static final String USE_TOR_PROXY = "useTorProxy";
|
||||||
|
public static final String PROXY_HOST = "proxyHost";
|
||||||
|
public static final String PROXY_PORT = "proxyPort";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ProxyOrbot {
|
||||||
|
public static final String PROXY_HOST = "127.0.0.1";
|
||||||
|
public static final int PROXY_HTTP_PORT = 8118;
|
||||||
|
public static final int PROXY_SOCKS_PORT = 9050;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Defaults {
|
public static final class Defaults {
|
||||||
|
@ -23,6 +23,7 @@ import android.content.Intent;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
|
import android.preference.EditTextPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
@ -35,8 +36,11 @@ import android.widget.LinearLayout;
|
|||||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||||
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
|
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Preferences;
|
import org.sufficientlysecure.keychain.util.Preferences;
|
||||||
|
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -270,6 +274,145 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ProxyPrefsFragment extends PreferenceFragment {
|
||||||
|
private CheckBoxPreference mUseTor;
|
||||||
|
private CheckBoxPreference mUseNormalProxy;
|
||||||
|
private EditTextPreference mProxyHost;
|
||||||
|
private EditTextPreference mProxyPort;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Load the preferences from an XML resource
|
||||||
|
addPreferencesFromResource(R.xml.proxy_prefs);
|
||||||
|
|
||||||
|
mUseTor = (CheckBoxPreference) findPreference(Constants.Pref.USE_TOR_PROXY);
|
||||||
|
mUseNormalProxy = (CheckBoxPreference) findPreference(Constants.Pref.USE_NORMAL_PROXY);
|
||||||
|
mProxyHost = (EditTextPreference) findPreference(Constants.Pref.PROXY_HOST);
|
||||||
|
mProxyPort = (EditTextPreference) findPreference(Constants.Pref.PROXY_PORT);
|
||||||
|
|
||||||
|
initializeUseTorPref();
|
||||||
|
initializeUseNormalProxyPref();
|
||||||
|
initialiseEditTextPreferences();
|
||||||
|
|
||||||
|
if (mUseTor.isChecked()) disableNormalProxyPrefs();
|
||||||
|
else if (mUseNormalProxy.isChecked()) disableUseTorPrefs();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeUseTorPref() {
|
||||||
|
mUseTor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
if ((Boolean)newValue) {
|
||||||
|
OrbotHelper orbotHelper = new OrbotHelper(ProxyPrefsFragment.this.getActivity());
|
||||||
|
boolean installed = orbotHelper.isOrbotInstalled();
|
||||||
|
if (!installed) {
|
||||||
|
Log.d(Constants.TAG, "Prompting to install Tor");
|
||||||
|
orbotHelper.promptToInstall(ProxyPrefsFragment.this.getActivity());
|
||||||
|
// don't let the user check the box until he's installed orbot
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
disableNormalProxyPrefs();
|
||||||
|
// let the enable tor box be checked
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we're unchecking Tor, so enable other proxy
|
||||||
|
enableNormalProxyPrefs();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeUseNormalProxyPref() {
|
||||||
|
mUseNormalProxy.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
if ((Boolean) newValue) {
|
||||||
|
disableUseTorPrefs();
|
||||||
|
} else {
|
||||||
|
enableUseTorPrefs();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialiseEditTextPreferences() {
|
||||||
|
mProxyHost.setSummary(mProxyHost.getText());
|
||||||
|
mProxyPort.setSummary(mProxyPort.getText());
|
||||||
|
|
||||||
|
mProxyHost.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
if (newValue.equals("")) {
|
||||||
|
Notify.create(
|
||||||
|
ProxyPrefsFragment.this.getActivity(),
|
||||||
|
R.string.pref_proxy_host_err_invalid,
|
||||||
|
Notify.Style.ERROR
|
||||||
|
).show();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
mProxyHost.setSummary((CharSequence) newValue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mProxyPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
try {
|
||||||
|
int port = Integer.parseInt((String) newValue);
|
||||||
|
if(port < 0 || port > 65535) {
|
||||||
|
Notify.create(
|
||||||
|
ProxyPrefsFragment.this.getActivity(),
|
||||||
|
R.string.pref_proxy_port_err_invalid,
|
||||||
|
Notify.Style.ERROR
|
||||||
|
).show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// no issues, save port
|
||||||
|
mProxyPort.setSummary("" + port);
|
||||||
|
return true;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Notify.create(
|
||||||
|
ProxyPrefsFragment.this.getActivity(),
|
||||||
|
R.string.pref_proxy_port_err_invalid,
|
||||||
|
Notify.Style.ERROR
|
||||||
|
).show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableNormalProxyPrefs() {
|
||||||
|
mUseNormalProxy.setChecked(false);
|
||||||
|
mUseNormalProxy.setEnabled(false);
|
||||||
|
mProxyHost.setEnabled(false);
|
||||||
|
mProxyPort.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableNormalProxyPrefs() {
|
||||||
|
mUseNormalProxy.setEnabled(true);
|
||||||
|
mProxyHost.setEnabled(true);
|
||||||
|
mProxyPort.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableUseTorPrefs() {
|
||||||
|
mUseTor.setChecked(false);
|
||||||
|
mUseTor.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableUseTorPrefs() {
|
||||||
|
mUseTor.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||||
protected boolean isValidFragment(String fragmentName) {
|
protected boolean isValidFragment(String fragmentName) {
|
||||||
return AdvancedPrefsFragment.class.getName().equals(fragmentName)
|
return AdvancedPrefsFragment.class.getName().equals(fragmentName)
|
||||||
@ -332,7 +475,8 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
String[] servers = sPreferences.getKeyServers();
|
String[] servers = sPreferences.getKeyServers();
|
||||||
String serverSummary = context.getResources().getQuantityString(
|
String serverSummary = context.getResources().getQuantityString(
|
||||||
R.plurals.n_keyservers, servers.length, servers.length);
|
R.plurals.n_keyservers, servers.length, servers.length);
|
||||||
return serverSummary + "; " + context.getString(R.string.label_preferred) + ": " + sPreferences.getPreferredKeyserver();
|
return serverSummary + "; " + context.getString(R.string.label_preferred) + ": " + sPreferences
|
||||||
|
.getPreferredKeyserver();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initializeUseDefaultYubiKeyPin(final CheckBoxPreference mUseDefaultYubiKeyPin) {
|
private static void initializeUseDefaultYubiKeyPin(final CheckBoxPreference mUseDefaultYubiKeyPin) {
|
||||||
|
@ -224,6 +224,53 @@ public class Preferences {
|
|||||||
return mSharedPreferences.getBoolean(Pref.ENCRYPT_FILENAMES, true);
|
return mSharedPreferences.getBoolean(Pref.ENCRYPT_FILENAMES, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getUseNormalProxy() {
|
||||||
|
return mSharedPreferences.getBoolean(Constants.Pref.USE_NORMAL_PROXY, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseNormalProxy(boolean use) {
|
||||||
|
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||||
|
editor.putBoolean(Constants.Pref.USE_NORMAL_PROXY, use);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getUseTorProxy() {
|
||||||
|
return mSharedPreferences.getBoolean(Constants.Pref.USE_TOR_PROXY, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseTorProxy(boolean use) {
|
||||||
|
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||||
|
editor.putBoolean(Constants.Pref.USE_TOR_PROXY, use);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProxyHost() {
|
||||||
|
return mSharedPreferences.getString(Constants.Pref.PROXY_HOST, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProxyHost(String host) {
|
||||||
|
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||||
|
editor.putString(Constants.Pref.PROXY_HOST, host);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* we store port as String for easy interfacing with EditTextPreference, but return it as an integer
|
||||||
|
* @return port number of proxy
|
||||||
|
*/
|
||||||
|
public int getProxyPort() {
|
||||||
|
return Integer.parseInt(mSharedPreferences.getString(Pref.PROXY_PORT, "-1"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* we store port as String for easy interfacing with EditTextPreference, but return it as an integer
|
||||||
|
* @param port proxy port
|
||||||
|
*/
|
||||||
|
public void setProxyPort(String port) {
|
||||||
|
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||||
|
editor.putString(Pref.PROXY_PORT, port);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
public CloudSearchPrefs getCloudSearchPrefs() {
|
public CloudSearchPrefs getCloudSearchPrefs() {
|
||||||
return new CloudSearchPrefs(mSharedPreferences.getBoolean(Pref.SEARCH_KEYSERVER, true),
|
return new CloudSearchPrefs(mSharedPreferences.getBoolean(Pref.SEARCH_KEYSERVER, true),
|
||||||
mSharedPreferences.getBoolean(Pref.SEARCH_KEYBASE, true),
|
mSharedPreferences.getBoolean(Pref.SEARCH_KEYBASE, true),
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.util.orbot;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
|
||||||
|
|
||||||
|
public class OrbotHelper {
|
||||||
|
|
||||||
|
private final static int REQUEST_CODE_STATUS = 100;
|
||||||
|
|
||||||
|
public final static String ORBOT_PACKAGE_NAME = "org.torproject.android";
|
||||||
|
public final static String TOR_BIN_PATH = "/data/data/org.torproject.android/app_bin/tor";
|
||||||
|
|
||||||
|
public final static String ACTION_START_TOR = "org.torproject.android.START_TOR";
|
||||||
|
public final static String ACTION_REQUEST_HS = "org.torproject.android.REQUEST_HS_PORT";
|
||||||
|
public final static int HS_REQUEST_CODE = 9999;
|
||||||
|
|
||||||
|
private Context mContext = null;
|
||||||
|
|
||||||
|
public OrbotHelper(Context context)
|
||||||
|
{
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOrbotRunning()
|
||||||
|
{
|
||||||
|
int procId = TorServiceUtils.findProcessId(TOR_BIN_PATH);
|
||||||
|
|
||||||
|
return (procId != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOrbotInstalled()
|
||||||
|
{
|
||||||
|
return isAppInstalled(ORBOT_PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAppInstalled(String uri) {
|
||||||
|
PackageManager pm = mContext.getPackageManager();
|
||||||
|
boolean installed = false;
|
||||||
|
try {
|
||||||
|
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
|
||||||
|
installed = true;
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
installed = false;
|
||||||
|
}
|
||||||
|
return installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void promptToInstall(Activity activity)
|
||||||
|
{
|
||||||
|
String uriMarket = activity.getString(R.string.market_orbot);
|
||||||
|
// show dialog - install from market, f-droid or direct APK
|
||||||
|
showDownloadDialog(activity, activity.getString(R.string.install_orbot_),
|
||||||
|
activity.getString(R.string.you_must_have_orbot),
|
||||||
|
activity.getString(R.string.orbot_yes), activity.getString(R.string.orbot_no), uriMarket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AlertDialog showDownloadDialog(final Activity activity,
|
||||||
|
CharSequence stringTitle, CharSequence stringMessage, CharSequence stringButtonYes,
|
||||||
|
CharSequence stringButtonNo, final String uriString) {
|
||||||
|
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
|
||||||
|
downloadDialog.setTitle(stringTitle);
|
||||||
|
downloadDialog.setMessage(stringMessage);
|
||||||
|
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
Uri uri = Uri.parse(uriString);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
activity.startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return downloadDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestOrbotStart(final Activity activity)
|
||||||
|
{
|
||||||
|
|
||||||
|
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
|
||||||
|
downloadDialog.setTitle(R.string.start_orbot_);
|
||||||
|
downloadDialog
|
||||||
|
.setMessage(R.string.orbot_doesn_t_appear_to_be_running_would_you_like_to_start_it_up_and_connect_to_tor_);
|
||||||
|
downloadDialog.setPositiveButton(R.string.orbot_yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
activity.startActivityForResult(getOrbotStartIntent(), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
downloadDialog.setNegativeButton(R.string.orbot_no, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
downloadDialog.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestHiddenServiceOnPort(Activity activity, int port)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(ACTION_REQUEST_HS);
|
||||||
|
intent.setPackage(ORBOT_PACKAGE_NAME);
|
||||||
|
intent.putExtra("hs_port", port);
|
||||||
|
|
||||||
|
activity.startActivityForResult(intent, HS_REQUEST_CODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Intent getOrbotStartIntent() {
|
||||||
|
Intent intent = new Intent(ACTION_START_TOR);
|
||||||
|
intent.setPackage(ORBOT_PACKAGE_NAME);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,234 @@
|
|||||||
|
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.util.orbot;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class TorServiceUtils {
|
||||||
|
|
||||||
|
private final static String TAG = "TorUtils";
|
||||||
|
// various console cmds
|
||||||
|
public final static String SHELL_CMD_CHMOD = "chmod";
|
||||||
|
public final static String SHELL_CMD_KILL = "kill -9";
|
||||||
|
public final static String SHELL_CMD_RM = "rm";
|
||||||
|
public final static String SHELL_CMD_PS = "ps";
|
||||||
|
public final static String SHELL_CMD_PIDOF = "pidof";
|
||||||
|
|
||||||
|
public final static String CHMOD_EXE_VALUE = "700";
|
||||||
|
|
||||||
|
public static boolean isRootPossible()
|
||||||
|
{
|
||||||
|
|
||||||
|
StringBuilder log = new StringBuilder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Check if Superuser.apk exists
|
||||||
|
File fileSU = new File("/system/app/Superuser.apk");
|
||||||
|
if (fileSU.exists())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fileSU = new File("/system/app/superuser.apk");
|
||||||
|
if (fileSU.exists())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fileSU = new File("/system/bin/su");
|
||||||
|
if (fileSU.exists())
|
||||||
|
{
|
||||||
|
String[] cmd = {
|
||||||
|
"su"
|
||||||
|
};
|
||||||
|
int exitCode = TorServiceUtils.doShellCommand(cmd, log, false, true);
|
||||||
|
if (exitCode != 0)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for 'su' binary
|
||||||
|
String[] cmd = {
|
||||||
|
"which su"
|
||||||
|
};
|
||||||
|
int exitCode = TorServiceUtils.doShellCommand(cmd, log, false, true);
|
||||||
|
|
||||||
|
if (exitCode == 0) {
|
||||||
|
Log.d(TAG, "root exists, but not sure about permissions");
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
// this means that there is no root to be had (normally) so we won't
|
||||||
|
// log anything
|
||||||
|
Log.e(TAG, "Error checking for root access", e);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error checking for root access", e);
|
||||||
|
// this means that there is no root to be had (normally)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.e(TAG, "Could not acquire root permissions");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int findProcessId(String command)
|
||||||
|
{
|
||||||
|
int procId = -1;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
procId = findProcessIdWithPidOf(command);
|
||||||
|
|
||||||
|
if (procId == -1)
|
||||||
|
procId = findProcessIdWithPS(command);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
procId = findProcessIdWithPS(command);
|
||||||
|
} catch (Exception e2)
|
||||||
|
{
|
||||||
|
Log.e(TAG, "Unable to get proc id for command: " + URLEncoder.encode(command), e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return procId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use 'pidof' command
|
||||||
|
public static int findProcessIdWithPidOf(String command) throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
int procId = -1;
|
||||||
|
|
||||||
|
Runtime r = Runtime.getRuntime();
|
||||||
|
|
||||||
|
Process procPs = null;
|
||||||
|
|
||||||
|
String baseName = new File(command).getName();
|
||||||
|
// fix contributed my mikos on 2010.12.10
|
||||||
|
procPs = r.exec(new String[] {
|
||||||
|
SHELL_CMD_PIDOF, baseName
|
||||||
|
});
|
||||||
|
// procPs = r.exec(SHELL_CMD_PIDOF);
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream()));
|
||||||
|
String line = null;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// this line should just be the process id
|
||||||
|
procId = Integer.parseInt(line.trim());
|
||||||
|
break;
|
||||||
|
} catch (NumberFormatException e)
|
||||||
|
{
|
||||||
|
Log.e("TorServiceUtils", "unable to parse process pid: " + line, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return procId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// use 'ps' command
|
||||||
|
public static int findProcessIdWithPS(String command) throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
int procId = -1;
|
||||||
|
|
||||||
|
Runtime r = Runtime.getRuntime();
|
||||||
|
|
||||||
|
Process procPs = null;
|
||||||
|
|
||||||
|
procPs = r.exec(SHELL_CMD_PS);
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream()));
|
||||||
|
String line = null;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null)
|
||||||
|
{
|
||||||
|
if (line.indexOf(' ' + command) != -1)
|
||||||
|
{
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer(line, " ");
|
||||||
|
st.nextToken(); // proc owner
|
||||||
|
|
||||||
|
procId = Integer.parseInt(st.nextToken().trim());
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return procId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int doShellCommand(String[] cmds, StringBuilder log, boolean runAsRoot,
|
||||||
|
boolean waitFor) throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
Process proc = null;
|
||||||
|
int exitCode = -1;
|
||||||
|
|
||||||
|
if (runAsRoot)
|
||||||
|
proc = Runtime.getRuntime().exec("su");
|
||||||
|
else
|
||||||
|
proc = Runtime.getRuntime().exec("sh");
|
||||||
|
|
||||||
|
OutputStreamWriter out = new OutputStreamWriter(proc.getOutputStream());
|
||||||
|
|
||||||
|
for (int i = 0; i < cmds.length; i++)
|
||||||
|
{
|
||||||
|
// TorService.logMessage("executing shell cmd: " + cmds[i] +
|
||||||
|
// "; runAsRoot=" + runAsRoot + ";waitFor=" + waitFor);
|
||||||
|
|
||||||
|
out.write(cmds[i]);
|
||||||
|
out.write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
out.flush();
|
||||||
|
out.write("exit\n");
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
if (waitFor)
|
||||||
|
{
|
||||||
|
|
||||||
|
final char buf[] = new char[10];
|
||||||
|
|
||||||
|
// Consume the "stdout"
|
||||||
|
InputStreamReader reader = new InputStreamReader(proc.getInputStream());
|
||||||
|
int read = 0;
|
||||||
|
while ((read = reader.read(buf)) != -1) {
|
||||||
|
if (log != null)
|
||||||
|
log.append(buf, 0, read);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consume the "stderr"
|
||||||
|
reader = new InputStreamReader(proc.getErrorStream());
|
||||||
|
read = 0;
|
||||||
|
while ((read = reader.read(buf)) != -1) {
|
||||||
|
if (log != null)
|
||||||
|
log.append(buf, 0, read);
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCode = proc.waitFor();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -49,6 +49,7 @@
|
|||||||
<string name="section_keys">"Subkeys"</string>
|
<string name="section_keys">"Subkeys"</string>
|
||||||
<string name="section_cloud_search">"Cloud search"</string>
|
<string name="section_cloud_search">"Cloud search"</string>
|
||||||
<string name="section_passphrase_cache">"Password Cache"</string>
|
<string name="section_passphrase_cache">"Password Cache"</string>
|
||||||
|
<string name="section_proxy_settings">"Proxy Settings"</string>
|
||||||
<string name="section_certify">"Confirm"</string>
|
<string name="section_certify">"Confirm"</string>
|
||||||
<string name="section_actions">"Actions"</string>
|
<string name="section_actions">"Actions"</string>
|
||||||
<string name="section_share_key">"Key"</string>
|
<string name="section_share_key">"Key"</string>
|
||||||
@ -165,6 +166,16 @@
|
|||||||
<string name="pref_keybase">"keybase.io"</string>
|
<string name="pref_keybase">"keybase.io"</string>
|
||||||
<string name="pref_keybase_summary">"Search keys on keybase.io"</string>
|
<string name="pref_keybase_summary">"Search keys on keybase.io"</string>
|
||||||
|
|
||||||
|
<!-- Proxy Preferences -->
|
||||||
|
<string name="pref_proxy_non">"Don't use a proxy"</string>
|
||||||
|
<string name="pref_proxy_tor">"Enable Tor"</string>
|
||||||
|
<string name="pref_proxy_tor_summary">"Requires Orbot to be installed"</string>
|
||||||
|
<string name="pref_proxy_normal">"Enable other proxy"</string>
|
||||||
|
<string name="pref_proxy_host">"Proxy Host"</string>
|
||||||
|
<string name="pref_proxy_host_err_invalid">"Proxy host cannot be empty"</string>
|
||||||
|
<string name="pref_proxy_port">"Proxy Port"</string>
|
||||||
|
<string name="pref_proxy_port_err_invalid">"Invalid port number entered"</string>
|
||||||
|
|
||||||
<string name="user_id_no_name">"<no name>"</string>
|
<string name="user_id_no_name">"<no name>"</string>
|
||||||
<string name="none">"<none>"</string>
|
<string name="none">"<none>"</string>
|
||||||
|
|
||||||
@ -180,6 +191,15 @@
|
|||||||
|
|
||||||
<string name="secret_key">"Secret Key:"</string>
|
<string name="secret_key">"Secret Key:"</string>
|
||||||
|
|
||||||
|
<!-- OrbotHelper strings -->
|
||||||
|
<string name="install_orbot_">"Install Orbot?"</string>
|
||||||
|
<string name="market_orbot">"market://search?q=pname:org.torproject.android"</string>
|
||||||
|
<string name="you_must_have_orbot">"You must have Orbot installed and activated to proxy traffic through it. Would you like to install it from Google Play?"</string>
|
||||||
|
<string name="orbot_yes">"Yes"</string>
|
||||||
|
<string name="orbot_no">"No"</string>
|
||||||
|
<string name="start_orbot_">"Start Orbot?"</string>
|
||||||
|
<string name="orbot_doesn_t_appear_to_be_running_would_you_like_to_start_it_up_and_connect_to_tor_">"Orbot doesn\'t appear to be running. Would you like to start it up and connect to Tor?"</string>
|
||||||
|
|
||||||
<!-- choice -->
|
<!-- choice -->
|
||||||
<string name="choice_none">"None"</string>
|
<string name="choice_none">"None"</string>
|
||||||
<string name="choice_15secs">"15 secs"</string>
|
<string name="choice_15secs">"15 secs"</string>
|
||||||
|
@ -5,4 +5,7 @@
|
|||||||
<header
|
<header
|
||||||
android:fragment="org.sufficientlysecure.keychain.ui.SettingsActivity$AdvancedPrefsFragment"
|
android:fragment="org.sufficientlysecure.keychain.ui.SettingsActivity$AdvancedPrefsFragment"
|
||||||
android:title="@string/section_passphrase_cache" />
|
android:title="@string/section_passphrase_cache" />
|
||||||
|
<header
|
||||||
|
android:fragment="org.sufficientlysecure.keychain.ui.SettingsActivity$ProxyPrefsFragment"
|
||||||
|
android:title="@string/section_proxy_settings" />
|
||||||
</preference-headers>
|
</preference-headers>
|
||||||
|
27
OpenKeychain/src/main/res/xml/proxy_prefs.xml
Normal file
27
OpenKeychain/src/main/res/xml/proxy_prefs.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="useTorProxy"
|
||||||
|
android:persistent="true"
|
||||||
|
android:title="@string/pref_proxy_tor"
|
||||||
|
android:summary="@string/pref_proxy_tor_summary" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="useNormalProxy"
|
||||||
|
android:persistent="true"
|
||||||
|
android:title="@string/pref_proxy_normal" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="proxyHost"
|
||||||
|
android:persistent="true"
|
||||||
|
android:defaultValue="127.0.0.1"
|
||||||
|
android:title="@string/pref_proxy_host"
|
||||||
|
android:cursorVisible="true"
|
||||||
|
android:textCursorDrawable="@null"
|
||||||
|
android:inputType="textEmailAddress"/>
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="proxyPort"
|
||||||
|
android:defaultValue="8118"
|
||||||
|
android:persistent="true"
|
||||||
|
android:title="@string/pref_proxy_port"
|
||||||
|
android:textCursorDrawable="@null"
|
||||||
|
android:inputType="number" />
|
||||||
|
</PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user