aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java124
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/TorServiceUtils.java234
2 files changed, 358 insertions, 0 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java
new file mode 100644
index 000000000..d9566be4a
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/OrbotHelper.java
@@ -0,0 +1,124 @@
+
+package info.guardianproject.onionkit.ui;
+
+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 info.guardianproject.onionkit.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.yes), activity.getString(R.string.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.yes, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ activity.startActivityForResult(getOrbotStartIntent(), 1);
+ }
+ });
+ downloadDialog.setNegativeButton(R.string.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;
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/TorServiceUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/TorServiceUtils.java
new file mode 100644
index 000000000..80a812344
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/orbot/TorServiceUtils.java
@@ -0,0 +1,234 @@
+/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
+/* See LICENSE for licensing information */
+
+package info.guardianproject.onionkit.ui;
+
+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;
+
+ }
+}