update to service with new transproxy/iptables code

svn:r24627
This commit is contained in:
Nathan Freitas 2011-04-15 16:37:33 +00:00
parent 644ce2700d
commit 21d01598cd
5 changed files with 172 additions and 145 deletions

View File

@ -12,18 +12,23 @@ import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.torproject.android.R;
import android.content.Context;
import android.util.Log;
public class TorBinaryInstaller implements TorServiceConstants {
String installPath = null;
String apkPath = null;
String installPath;
String apkPath;
Context context;
public TorBinaryInstaller (String installPath, String apkPath)
public TorBinaryInstaller (Context context, String installPath, String apkPath)
{
this.installPath = installPath;
this.apkPath = apkPath;
this.context = context;
}
/*
@ -39,10 +44,39 @@ public class TorBinaryInstaller implements TorServiceConstants {
Log.d(TAG,"Privoxy binary exists=" + privoxyBinaryExists);
if (!(torBinaryExists && privoxyBinaryExists) || force)
installFromZip ();
installFromRaw ();
}
//
/*
* Extract the Tor binary from the APK file using ZIP
*/
private void installFromRaw ()
{
InputStream is = context.getResources().openRawResource(R.raw.tor);
streamToFile(is,installPath + TOR_BINARY_ASSET_KEY);
is = context.getResources().openRawResource(R.raw.torrc);
streamToFile(is,installPath + TORRC_ASSET_KEY);
is = context.getResources().openRawResource(R.raw.privoxy);
streamToFile(is,installPath + PRIVOXY_ASSET_KEY);
is = context.getResources().openRawResource(R.raw.privoxy_config);
streamToFile(is,installPath + PRIVOXYCONFIG_ASSET_KEY);
Log.d(TAG,"SUCCESS: installed tor, privoxy binaries from raw");
}
/*
* Extract the Tor binary from the APK file using ZIP
*/

View File

@ -52,11 +52,15 @@ public class TorService extends Service implements TorServiceConstants, Runnable
private static final int MAX_START_TRIES = 3;
private ArrayList<String> configBuffer = null;
private ArrayList<String> resetBuffer = null;
private String appHome = "/data/data/" + TOR_APP_USERNAME + "/";;
private String torBinaryPath = appHome + TOR_BINARY_ASSET_KEY;
private String privoxyPath = appHome + PRIVOXY_ASSET_KEY;
private String appHome;
private String appBinHome;
private String appDataHome;
private String torBinaryPath;
private String privoxyPath;
private boolean hasRoot = false;
@ -323,7 +327,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
TorServiceUtils.doShellCommand(cmd,log, false, false);
try { Thread.sleep(500); }
catch (Exception e){}
}
while ((procId = TorServiceUtils.findProcessId(privoxyPath)) != -1)
@ -333,7 +338,8 @@ public class TorService extends Service implements TorServiceConstants, Runnable
String[] cmd = { SHELL_CMD_KILL + ' ' + procId + "" };
TorServiceUtils.doShellCommand(cmd,log, false, false);
try { Thread.sleep(500); }
catch (Exception e){}
}
}
@ -349,6 +355,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
}
}
/*
private String findAPK ()
{
@ -428,39 +435,29 @@ public class TorService extends Service implements TorServiceConstants, Runnable
return null;
}
}*/
private boolean checkTorBinaries () throws Exception
{
//android.os.Debug.waitForDebugger();
appHome = "/data/data/" + TOR_APP_USERNAME + "/";
//appHome = getApplicationContext().getFilesDir().getAbsolutePath();
//check and install iptables
Api.assertBinaries(this, true);
File fileInstall = getDir("",0);
String subBinPath = "bin/";
appHome = fileInstall.getAbsolutePath();
appBinHome = appHome + subBinPath;
appDataHome = getCacheDir().getAbsolutePath() + '/';
logNotice( "appHome=" + appHome);
torBinaryPath = appHome + TOR_BINARY_ASSET_KEY;
privoxyPath = appHome + PRIVOXY_ASSET_KEY;
torBinaryPath = appBinHome + TOR_BINARY_ASSET_KEY;
privoxyPath = appBinHome + PRIVOXY_ASSET_KEY;
logNotice( "checking Tor binaries");
String apkPath = findAPK();
if (apkPath == null)
throw new Exception ("Unable to locate Orbot binary APK file");
logNotice( "found apk at: " + apkPath);
boolean apkExists = new File(apkPath).exists();
if (!apkExists)
{
Log.w(TAG,"APK file not found at: " + apkPath);
Log.w(TAG,"Binary installation aborted");
logNotice(getString(R.string.status_install_fail));
sendCallbackStatusMessage(getString(R.string.status_install_fail));
return false;
}
boolean torBinaryExists = new File(torBinaryPath).exists();
boolean privoxyBinaryExists = new File(privoxyPath).exists();
@ -468,7 +465,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
{
killTorProcess ();
TorBinaryInstaller installer = new TorBinaryInstaller(appHome, apkPath);
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome, appBinHome);
installer.start(true);
torBinaryExists = new File(torBinaryPath).exists();
@ -552,12 +549,11 @@ public class TorService extends Service implements TorServiceConstants, Runnable
private void runTorShellCmd() throws Exception
{
StringBuilder log = new StringBuilder();
String torrcPath = appHome + TORRC_ASSET_KEY;
String torrcPath = appBinHome + TORRC_ASSET_KEY;
String[] torCmd = {torBinaryPath + " -f " + torrcPath + " || exit\n"};
String[] torCmd = {torBinaryPath + " DataDirectory " + appDataHome + " -f " + torrcPath + " || exit\n"};
boolean runAsRootFalse = false;
boolean waitForProcess = false;
@ -623,7 +619,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
{
log = new StringBuilder();
String privoxyConfigPath = appHome + PRIVOXYCONFIG_ASSET_KEY;
String privoxyConfigPath = appBinHome + PRIVOXYCONFIG_ASSET_KEY;
String[] cmds =
{ privoxyPath + " " + privoxyConfigPath + " &" };
@ -680,27 +676,31 @@ public class TorService extends Service implements TorServiceConstants, Runnable
torConnSocket = new Socket(IP_LOCALHOST, TOR_CONTROL_PORT);
conn = TorControlConnection.getConnection(torConnSocket);
// conn.authenticate(new byte[0]); // See section 3.2
sendCallbackStatusMessage(getString(R.string.tor_process_connecting_step2));
logNotice( "SUCCESS connected to control port");
String torAuthCookie = appHome + "data/control_auth_cookie";
String torAuthCookie = appDataHome + TOR_CONTROL_COOKIE;
File fileCookie = new File(torAuthCookie);
byte[] cookie = new byte[(int)fileCookie.length()];
new FileInputStream(new File(torAuthCookie)).read(cookie);
conn.authenticate(cookie);
logNotice( "SUCCESS authenticated to control port");
sendCallbackStatusMessage(getString(R.string.tor_process_connecting_step2) + getString(R.string.tor_process_connecting_step3));
addEventHandler();
applyPreferences();
if (fileCookie.exists())
{
byte[] cookie = new byte[(int)fileCookie.length()];
new FileInputStream(new File(torAuthCookie)).read(cookie);
conn.authenticate(cookie);
logNotice( "SUCCESS authenticated to control port");
sendCallbackStatusMessage(getString(R.string.tor_process_connecting_step2) + getString(R.string.tor_process_connecting_step3));
addEventHandler();
applyPreferences();
}
break; //don't need to retry
}
@ -712,8 +712,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
sendCallbackStatusMessage(getString(R.string.tor_process_connecting_step4));
Thread.sleep(1000);
}
}
@ -1052,9 +1051,14 @@ public class TorService extends Service implements TorServiceConstants, Runnable
{
if (configBuffer == null)
configBuffer = new ArrayList<String>();
if (resetBuffer == null)
resetBuffer = new ArrayList<String>();
if (value == null || value.length() == 0)
{
/*
if (conn != null)
{
try {
@ -1063,6 +1067,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable
Log.w(TAG, "Unable to reset conf",e);
}
}
*/
resetBuffer.add(name);
}
else
configBuffer.add(name + ' ' + value);
@ -1076,8 +1083,16 @@ public class TorService extends Service implements TorServiceConstants, Runnable
{
if (conn != null)
{
if (configBuffer != null)
if (resetBuffer != null && resetBuffer.size() > 0)
{
conn.resetConf(resetBuffer);
resetBuffer = null;
}
if (configBuffer != null && configBuffer.size() > 0)
{
conn.setConf(configBuffer);
configBuffer = null;
}
@ -1378,14 +1393,14 @@ public class TorService extends Service implements TorServiceConstants, Runnable
}
else
{
TorTransProxy.purgeIptables(this,AppManager.getApps(this));
TorTransProxy.purgeIptables(this);
}
}
}
else if (hasRoot)
{
TorTransProxy.purgeIptables(this,AppManager.getApps(this));
TorTransProxy.purgeIptables(this);
}
return true;

View File

@ -19,7 +19,8 @@ public interface TorServiceConstants {
//torrc (tor config file)
public final static String TORRC_ASSET_KEY = "torrc";
public final static String TOR_CONTROL_COOKIE = "control_auth_cookie";
//how to launch tor
// public final static String TOR_COMMAND_LINE_ARGS = "-f " + TORRC_INSTALL_PATH + " || exit\n";
@ -39,8 +40,8 @@ public interface TorServiceConstants {
public final static String CHMOD_EXE_VALUE = "777";
//path of the installed APK file
public final static String APK_PATH = "/data/app/org.torproject.android.apk";
public final static String APK_PATH_BASE = "/data/app";
//public final static String APK_PATH = "/data/app/org.torproject.android.apk";
//public final static String APK_PATH_BASE = "/data/app";

View File

@ -165,7 +165,6 @@ public class TorServiceUtils implements TorServiceConstants {
else
proc = Runtime.getRuntime().exec("sh");
OutputStreamWriter out = new OutputStreamWriter(proc.getOutputStream());
for (int i = 0; i < cmds.length; i++)
@ -181,8 +180,6 @@ public class TorServiceUtils implements TorServiceConstants {
if (waitFor)
{
final char buf[] = new char[10];
// Consume the "stdout"

View File

@ -1,5 +1,7 @@
package org.torproject.android.service;
import java.io.File;
import org.torproject.android.TorifiedApp;
import android.content.Context;
@ -21,6 +23,7 @@ public class TorTransProxy implements TorServiceConstants {
* Check if we have root access
* @return boolean true if we have root
*/
/*
public static String getIPTablesVersion() {
@ -52,43 +55,42 @@ public class TorTransProxy implements TorServiceConstants {
logNotice("Could not acquire check iptables: " + log.toString());
return null;
}
}*/
private static String findBaseDir ()
{
return ""; //just blank for now
/*
String[] cmds = {"/system/bin/iptables -t nat --list"};
public static int purgeIptables(Context context) throws Exception {
String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
final StringBuilder script = new StringBuilder();
StringBuilder res = new StringBuilder();
int code = -1;
int code;
try {
code = TorServiceUtils.doShellCommand(cmds, res, true, true);
script.append(ipTablesPath);
script.append(" -t nat");
script.append(" -F || exit\n");
script.append(ipTablesPath);
script.append(" -t filter");
script.append(" -F || exit\n");
String[] cmd = {script.toString()};
code = TorServiceUtils.doShellCommand(cmd, res, true, true);
String msg = res.toString();
logNotice(cmd[0] + ";errCode=" + code + ";resp=" + msg);
if (code != 0) {
return BASE_DIR;
}
else
return "/system/bin/";
} catch (Exception e) {
return BASE_DIR;
}
return "";
*/
return code;
}
public static int purgeIptables(Context context, TorifiedApp[] apps) throws Exception {
/*
public static int purgeIptablesByApp(Context context, TorifiedApp[] apps) throws Exception {
//restoreDNSResolvConf(); //not working yet
String baseDir = findBaseDir();
String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
final StringBuilder script = new StringBuilder();
@ -97,13 +99,14 @@ public class TorTransProxy implements TorServiceConstants {
for (int i = 0; i < apps.length; i++)
{
//flush nat for every app
script.append(baseDir);
script.append("iptables -t nat -m owner --uid-owner ");
script.append(ipTablesPath);
script.append(" -t nat -m owner --uid-owner ");
script.append(apps[i].getUid());
script.append(" -F || exit\n");
script.append("iptables -t filter -m owner --uid-owner ");
script.append(ipTablesPath);
script.append(" -t filter -m owner --uid-owner ");
script.append(apps[i].getUid());
script.append(" -F || exit\n");
@ -118,7 +121,8 @@ public class TorTransProxy implements TorServiceConstants {
return code;
}
}*/
/*
// 9/19/2010 - NF This code is in process... /etc path on System partition
@ -171,38 +175,17 @@ public class TorTransProxy implements TorServiceConstants {
//redirectDNSResolvConf(); //not working yet
String baseDir = findBaseDir();
//String baseDir = context.getDir("bin", 0).getAbsolutePath() + "/";
String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
String iptablesVersion = getIPTablesVersion();
logNotice( "iptables version: " + iptablesVersion);
boolean ipTablesOld = false;
if (iptablesVersion != null && iptablesVersion.startsWith("1.3")){
ipTablesOld = true;
}
StringBuilder script = new StringBuilder();
StringBuilder res = new StringBuilder();
int code = -1;
for (int i = 0; i < apps.length; i++)
{
//flush nat for every app
script.append(baseDir);
script.append("iptables -t nat -m owner --uid-owner ");
script.append(apps[i].getUid());
script.append(" -F || exit\n");
script.append("iptables -t filter -m owner --uid-owner ");
script.append(apps[i].getUid());
script.append(" -F || exit\n");
}
String[] cmdFlush = {script.toString()};
code = TorServiceUtils.doShellCommand(cmdFlush, res, true, true);
//String msg = res.toString(); //get stdout from command
purgeIptables(context);
script = new StringBuilder();
@ -231,8 +214,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
//iptables -t nat -A output -p tcp -m owner --uid-owner 100 -m tcp --sync -j REDIRECT --to-ports 9040
//TCP
script.append(baseDir);
script.append("iptables -t nat");
script.append(ipTablesPath);
script.append(" -t nat");
script.append(" -A OUTPUT -p tcp");
script.append(" -m owner --uid-owner ");
script.append(apps[i].getUid());
@ -248,8 +231,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
script.append(" || exit\n");
//DNS
script.append(baseDir);
script.append("iptables -t nat");
script.append(ipTablesPath);
script.append(" -t nat");
script.append(" -A OUTPUT -p udp -m owner --uid-owner ");
script.append(apps[i].getUid());
script.append(" -m udp --dport ");
@ -268,8 +251,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
//EVERYTHING ELSE - DROP!
if (ipTablesOld) //for some reason this doesn't work on iptables 1.3.7
{
script.append("iptables -t nat");
script.append(ipTablesPath);
script.append(" -t nat");
script.append(" -A OUTPUT -m owner --uid-owner ");
script.append(apps[i].getUid());
script.append(" -j DROP");
@ -277,8 +260,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
}
else
{
script.append(baseDir);
script.append("iptables -t filter");
script.append(ipTablesPath);
script.append(" -t filter");
script.append(" -A OUTPUT -p tcp");
script.append(" -m owner --uid-owner ");
script.append(apps[i].getUid());
@ -287,8 +270,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
script.append(" -j ACCEPT");
script.append(" || exit\n");
script.append(baseDir);
script.append("iptables -t filter");
script.append(ipTablesPath);
script.append(" -t filter");
script.append(" -A OUTPUT -p udp");
script.append(" -m owner --uid-owner ");
script.append(apps[i].getUid());
@ -297,8 +280,7 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
script.append(" -j ACCEPT");
script.append(" || exit\n");
script.append(baseDir);
script.append("iptables");
script.append(ipTablesPath);
script.append(" -t filter -A OUTPUT -m owner --uid-owner ");
script.append(apps[i].getUid());
script.append(" -j DROP"); //drop all other packets as Tor won't handle them
@ -307,6 +289,9 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
}
}
else
{
}
}
@ -325,15 +310,10 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
//redirectDNSResolvConf(); //not working yet
String baseDir = findBaseDir();
//String baseDir = context.getDir("bin",0).getAbsolutePath() + '/';
String ipTablesPath = new File(context.getDir("bin", 0),"iptables_n1").getAbsolutePath();
String iptablesVersion = getIPTablesVersion();
logNotice( "iptables version: " + iptablesVersion);
boolean ipTablesOld = false;
if (iptablesVersion != null && iptablesVersion.startsWith("1.3")){
ipTablesOld = true;
}
StringBuilder script = new StringBuilder();
@ -349,8 +329,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
//TCP
//iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $srcPortNumber -j REDIRECT --to-port $dstPortNumbe
script.append(baseDir);
script.append("iptables -t nat");
script.append(ipTablesPath);
script.append(" -t nat");
script.append(" -A OUTPUT -p tcp");
script.append(" --dport ");
script.append(port);
@ -365,8 +345,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
script.append(" || exit\n");
script.append(baseDir);
script.append("iptables -t nat");
script.append(ipTablesPath);
script.append(" -t nat");
script.append(" -A OUTPUT -p udp");
script.append(" --dport ");
script.append(port);
@ -381,8 +361,8 @@ iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP
script.append(" || exit\n");
//DNS
script.append(baseDir);
script.append("iptables -t nat");
script.append(ipTablesPath);
script.append(" -t nat");
script.append(" -A OUTPUT -p udp ");
script.append(" -m udp --dport ");
script.append(STANDARD_DNS_PORT);