updates related to motorola milestone debugging and iptables transproxy settings

svn:r22743
This commit is contained in:
Nathan Freitas 2010-07-31 15:43:56 +00:00
parent 243ff10c48
commit e157ecd92a
6 changed files with 117 additions and 199 deletions

View File

@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false"> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".Orbot" <activity android:name=".Orbot"
android:theme="@android:style/Theme.NoTitleBar" android:theme="@android:style/Theme.NoTitleBar"

View File

@ -390,134 +390,7 @@ public class Orbot extends Activity implements OnClickListener, TorConstants
* Read in the Preferences and write then to the .torrc file * Read in the Preferences and write then to the .torrc file
*/ */
/*
private void processSettingsOld ()
{
StringBuffer torrcText = new StringBuffer();
torrcText.append(TorConstants.TORRC_DEFAULT);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean useBridges = prefs.getBoolean(PREF_BRIDGES_ENABLED, false);
boolean autoUpdateBridges = prefs.getBoolean(PREF_BRIDGES_UPDATED, false);
boolean becomeRelay = prefs.getBoolean(PREF_OR, false);
boolean ReachableAddresses = prefs.getBoolean(PREF_REACHABLE_ADDRESSES,false);
enableTransparentProxy = prefs.getBoolean(PREF_TRANSPARENT, false);
if (hasRoot)
{
if (enableTransparentProxy)
{
TorTransProxy.setDNSProxying();
TorTransProxy.setTransparentProxying(this, TorServiceUtils.getApps(this));
}
else
{
TorTransProxy.purgeNatIptables();
}
}
String bridgeList = prefs.getString(PREF_BRIDGES_LIST,"");
if (useBridges)
{
if (bridgeList == null || bridgeList.length() == 0)
{
showAlert("Bridge Error","In order to use the bridge feature, you must enter at least one bridge IP address." +
"Send an email to bridges@torproject.org with the line \"get bridges\" by itself in the body of the mail from a gmail account.");
showSettings();
return;
}
torrcText.append("UseBridges 1");
torrcText.append('\n');
torrcText.append("UpdateBridgesFromAuthority ");
if (autoUpdateBridges)
torrcText.append("1");
else
torrcText.append("0");
torrcText.append('\n');
String bridgeDelim = "\n";
if (bridgeList.indexOf(",") != -1)
{
bridgeDelim = ",";
}
StringTokenizer st = new StringTokenizer(bridgeList,bridgeDelim);
while (st.hasMoreTokens())
{
torrcText.append("bridge ");
torrcText.append(st.nextToken());
torrcText.append('\n');
}
}
else
{
torrcText.append("UseBridges 0");
torrcText.append('\n');
}
try
{
if (ReachableAddresses)
{
String ReachableAddressesPorts =
prefs.getString(PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443");
torrcText.append("ReachableAddresses ");
// We should verify this and someday, the Exception will matter :-)
torrcText.append(ReachableAddressesPorts);
torrcText.append('\n');
}
}
catch (Exception e)
{
showAlert("Config Error","Your ReachableAddresses settings caused an exception!");
}
try
{
if (becomeRelay && (!useBridges) && (!ReachableAddresses))
{
int ORPort = Integer.parseInt(prefs.getString(PREF_OR_PORT, "9001"));
String nickname = prefs.getString(PREF_OR_NICKNAME, "Orbot");
torrcText.append("ORPort ");
torrcText.append(ORPort);
torrcText.append('\n');
torrcText.append("Nickname ");
torrcText.append(nickname);
torrcText.append('\n');
torrcText.append("ExitPolicy reject *:*");
torrcText.append('\n');
}
}
catch (Exception e)
{
showAlert("Uh-oh!","Your relay settings caused an exception!");
showSettings();
return;
}
Utils.saveTextFile(TorServiceConstants.TORRC_INSTALL_PATH, torrcText.toString());
}
*/
private void processSettings () throws RemoteException private void processSettings () throws RemoteException
{ {

View File

@ -38,7 +38,10 @@ public class TorBinaryInstaller implements TorServiceConstants {
boolean privoxyBinaryExists = new File(installPath + PRIVOXY_ASSET_KEY).exists(); boolean privoxyBinaryExists = new File(installPath + PRIVOXY_ASSET_KEY).exists();
Log.i(TAG,"Privoxy binary exists=" + privoxyBinaryExists); Log.i(TAG,"Privoxy binary exists=" + privoxyBinaryExists);
if (!(torBinaryExists && privoxyBinaryExists) || force) boolean iptablesBinaryExists = new File(installPath + IPTABLES_ASSET_KEY).exists();
Log.i(TAG,"IPTables binary exists=" + iptablesBinaryExists);
if (!(torBinaryExists && privoxyBinaryExists && iptablesBinaryExists) || force)
installFromZip (); installFromZip ();
} }
@ -51,39 +54,31 @@ public class TorBinaryInstaller implements TorServiceConstants {
try try
{ {
/*
String apkPath = APK_PATH;
int apkIdx = 1;
while (!new File(apkPath).exists())
{
apkPath = APK_PATH_BASE + '-' + (apkIdx++) + ".apk";
Log.i(TAG,"Could not find APK. Trying new path: " + apkPath);
}
*/
ZipFile zip = new ZipFile(apkPath); ZipFile zip = new ZipFile(apkPath);
ZipEntry zipen = zip.getEntry(TOR_BINARY_ZIP_KEY); ZipEntry zipen = zip.getEntry(ASSETS_BASE + TOR_BINARY_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + TOR_BINARY_ASSET_KEY); streamToFile(zip.getInputStream(zipen),installPath + TOR_BINARY_ASSET_KEY);
zipen = zip.getEntry(TORRC_ZIP_KEY); zipen = zip.getEntry(ASSETS_BASE + TORRC_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + TORRC_ASSET_KEY); streamToFile(zip.getInputStream(zipen),installPath + TORRC_ASSET_KEY);
zipen = zip.getEntry(PRIVOXY_ZIP_KEY); zipen = zip.getEntry(ASSETS_BASE + PRIVOXY_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXY_ASSET_KEY); streamToFile(zip.getInputStream(zipen),installPath + PRIVOXY_ASSET_KEY);
zipen = zip.getEntry(PRIVOXYCONFIG_ZIP_KEY); zipen = zip.getEntry(ASSETS_BASE + PRIVOXYCONFIG_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY); streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY);
zipen = zip.getEntry(ASSETS_BASE + PRIVOXYCONFIG_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY);
zipen = zip.getEntry(ASSETS_BASE + IPTABLES_ASSET_KEY);
streamToFile(zip.getInputStream(zipen),installPath + IPTABLES_ASSET_KEY);
zip.close(); zip.close();
Log.i(TAG,"SUCCESS: unzipped tor, privoxy binaries from apk"); Log.i(TAG,"SUCCESS: unzipped tor, privoxy, iptables binaries from apk");
} }
catch (IOException ioe) catch (IOException ioe)

View File

@ -401,11 +401,13 @@ public class TorService extends Service implements TorServiceConstants, Runnable
torBinaryPath = appHome + TOR_BINARY_ASSET_KEY; torBinaryPath = appHome + TOR_BINARY_ASSET_KEY;
privoxyPath = appHome + PRIVOXY_ASSET_KEY; privoxyPath = appHome + PRIVOXY_ASSET_KEY;
String iptablesPath = appHome + IPTABLES_ASSET_KEY;
boolean torBinaryExists = new File(torBinaryPath).exists(); boolean torBinaryExists = new File(torBinaryPath).exists();
boolean privoxyBinaryExists = new File(privoxyPath).exists(); boolean privoxyBinaryExists = new File(privoxyPath).exists();
boolean iptablesBinaryExists = new File(iptablesPath).exists();
if (!(torBinaryExists && privoxyBinaryExists)) if (!(torBinaryExists && privoxyBinaryExists && iptablesBinaryExists))
{ {
killTorProcess (); killTorProcess ();
@ -415,7 +417,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
torBinaryExists = new File(torBinaryPath).exists(); torBinaryExists = new File(torBinaryPath).exists();
privoxyBinaryExists = new File(privoxyPath).exists(); privoxyBinaryExists = new File(privoxyPath).exists();
if (torBinaryExists && privoxyBinaryExists) if (torBinaryExists && privoxyBinaryExists && iptablesBinaryExists)
{ {
logNotice(getString(R.string.status_install_success)); logNotice(getString(R.string.status_install_success));
@ -429,8 +431,6 @@ public class TorService extends Service implements TorServiceConstants, Runnable
sendCallbackMessage(getString(R.string.status_install_fail)); sendCallbackMessage(getString(R.string.status_install_fail));
//showAlert(getString(R.string.title_error),getString(R.string.status_install_fail));
return false; return false;
} }
@ -439,7 +439,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable
{ {
logNotice("Found Tor binary: " + torBinaryPath); logNotice("Found Tor binary: " + torBinaryPath);
logNotice("Found prvoxy binary: " + privoxyPath); logNotice("Found privoxy binary: " + privoxyPath);
logNotice("Found iptables binary: " + iptablesPath);
} }
@ -453,6 +455,10 @@ public class TorService extends Service implements TorServiceConstants, Runnable
String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + privoxyPath}; String[] cmd2 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + privoxyPath};
TorServiceUtils.doShellCommand(cmd2, log, false, true); TorServiceUtils.doShellCommand(cmd2, log, false, true);
logNotice("(re)Setting permission on iptables binary");
String[] cmd3 = {SHELL_CMD_CHMOD + ' ' + CHMOD_EXE_VALUE + ' ' + iptablesPath};
TorServiceUtils.doShellCommand(cmd3, log, false, true);
return true; return true;
} }
@ -1181,15 +1187,15 @@ public class TorService extends Service implements TorServiceConstants, Runnable
logNotice ("TorTransProxy enabled: " + success); logNotice ("TorTransProxy enabled: " + success);
} catch (Exception e) { } catch (Exception e) {
logNotice("WARNING: Error configuring transparenty proxying: " + e.getMessage());
logNotice("WARNING: Error configuring transparenty proxying: " + e.getMessage());
Log.w(TAG, "error refreshing iptables: err=" + e.getMessage(), e); Log.w(TAG, "error refreshing iptables: err=" + e.getMessage(), e);
} }
} }
else else
{ {
TorTransProxy.purgeNatIptables(); TorTransProxy.purgeIptables();
} }
} }
@ -1197,7 +1203,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
{ {
if (hasRoot) if (hasRoot)
{ {
TorTransProxy.purgeNatIptables(); TorTransProxy.purgeIptables();
} }
} }
} }

View File

@ -8,42 +8,27 @@ public interface TorServiceConstants {
public final static String TOR_APP_USERNAME = "org.torproject.android"; public final static String TOR_APP_USERNAME = "org.torproject.android";
//home directory of Android application public final static String ASSETS_BASE = "assets/";
// public final static String TOR_HOME = "/data/data/" + TOR_APP_USERNAME + "/";
//public final static String TOR_HOME_DATA_DIR = TOR_HOME + "data/"; //home directory of Android application
//name of the tor C binary //name of the tor C binary
public final static String TOR_BINARY_ASSET_KEY = "tor"; public final static String TOR_BINARY_ASSET_KEY = "tor";
// public final static String TOR_BINARY_INSTALL_PATH = TOR_HOME + TOR_BINARY_ASSET_KEY; //path to install the Tor binary too
public final static String TOR_BINARY_ZIP_KEY = "assets/" + TOR_BINARY_ASSET_KEY;//key of the tor binary in the Zip file
//torrc (tor config file) //torrc (tor config file)
public final static String TORRC_ASSET_KEY = "torrc"; public final static String TORRC_ASSET_KEY = "torrc";
// public final static String TORRC_INSTALL_PATH = TOR_HOME + TORRC_ASSET_KEY; //path to install torrc to within the android app data folder
public final static String TORRC_ZIP_KEY = "assets/" + TORRC_ASSET_KEY; //key of the torrc file in the Zip file
//how to launch tor //how to launch tor
// public final static String TOR_COMMAND_LINE_ARGS = "-f " + TORRC_INSTALL_PATH + " || exit\n"; // public final static String TOR_COMMAND_LINE_ARGS = "-f " + TORRC_INSTALL_PATH + " || exit\n";
//privoxy //privoxy
public final static String PRIVOXY_ASSET_KEY = "privoxy"; public final static String PRIVOXY_ASSET_KEY = "privoxy";
// public final static String PRIVOXY_INSTALL_PATH = TOR_HOME + PRIVOXY_ASSET_KEY; //path to install privoxy to within the android app data folder
public final static String PRIVOXY_ZIP_KEY = "assets/" + PRIVOXY_ASSET_KEY; //key of the privoxy file in the Zip file
//privoxy.config //privoxy.config
public final static String PRIVOXYCONFIG_ASSET_KEY = "privoxy.config"; public final static String PRIVOXYCONFIG_ASSET_KEY = "privoxy.config";
// public final static String PRIVOXYCONFIG_INSTALL_PATH = TOR_HOME + PRIVOXYCONFIG_ASSET_KEY; //path to install privoxy to within the android app data folder
public final static String PRIVOXYCONFIG_ZIP_KEY = "assets/" + PRIVOXYCONFIG_ASSET_KEY; //key of the privoxy file in the Zip file
//how to launch privoxy
// public final static String PRIVOXY_COMMAND_LINE_ARGS = ' ' + PRIVOXYCONFIG_INSTALL_PATH + " || exit\n";
//where to send the notices log
// public final static String TOR_LOG_PATH = TOR_HOME + "notices.log";
//control port cookie path
// public final static String TOR_CONTROL_AUTH_COOKIE = TOR_HOME_DATA_DIR + "control_auth_cookie";
//iptables key
public final static String IPTABLES_ASSET_KEY = "iptables";
//various console cmds //various console cmds
public final static String SHELL_CMD_CHMOD = "chmod"; public final static String SHELL_CMD_CHMOD = "chmod";

View File

@ -1,5 +1,7 @@
package org.torproject.android.service; package org.torproject.android.service;
import java.io.File;
import org.torproject.android.TorifiedApp; import org.torproject.android.TorifiedApp;
import android.content.Context; import android.content.Context;
@ -9,14 +11,17 @@ public class TorTransProxy {
private final static String TAG = "TorTransProxy"; private final static String TAG = "TorTransProxy";
private final static String CMD_NAT_FLUSH = "iptables -t nat -F || exit\n"; private static String BASE_DIR = "/data/data/" + TorServiceConstants.TOR_APP_USERNAME + "/";
private final static String CMD_DNS_PROXYING_ADD = "iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to 127.0.0.1:5400 || exit\n";
//private final static String CMD_DNS_PROXYING_DELETE = "iptables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to 127.0.0.1:5400 || exit\n"; private final static String CMD_NAT_FLUSH = "iptables -t nat -F || exit\n";
// - just calling a system wide flush of iptables rules private final static String CMD_FILTER_FLUSH = "iptables -t filter -F || exit\n";
private final static String CMD_DNS_PROXYING_ADD = "iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to 127.0.0.1:5400 || exit\n";
private final static String IPTABLES_ADD = " -A "; private final static String IPTABLES_ADD = " -A ";
//private final static String CMD_DNS_PROXYING_DELETE = "iptables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to 127.0.0.1:5400 || exit\n";
// - just calling a system wide flush of iptables rules
//private final static String IPTABLES_DELETE = " -D "; //not deleting manually anymore - just calling a system wide flush of iptables rules //private final static String IPTABLES_DELETE = " -D "; //not deleting manually anymore - just calling a system wide flush of iptables rules
// private final static String IPTABLES_DROP_ALL = " -j DROP "; // private final static String IPTABLES_DROP_ALL = " -j DROP ";
@ -32,7 +37,7 @@ public class TorTransProxy {
try { try {
// Run an empty script just to check root access // Run an empty script just to check root access
String[] cmd = {"whoami"}; String[] cmd = {"exit 0"};
int exitCode = TorServiceUtils.doShellCommand(cmd, log, true, true); int exitCode = TorServiceUtils.doShellCommand(cmd, log, true, true);
if (exitCode == 0) { if (exitCode == 0) {
@ -46,13 +51,36 @@ public class TorTransProxy {
return false; return false;
} }
private static String findBaseDir ()
{
String[] cmds = {"/system/bin/iptables -t nat --list"};
StringBuilder res = new StringBuilder();
int code;
try {
code = TorServiceUtils.doShellCommand(cmds, res, true, true);
if (code != 0) {
return BASE_DIR;
}
else
return "/system/bin/";
} catch (Exception e) {
return BASE_DIR;
}
}
public static int setDNSProxying () throws Exception public static int setDNSProxying () throws Exception
{ {
String baseDir = findBaseDir();
final StringBuilder log = new StringBuilder(); final StringBuilder log = new StringBuilder();
int code; int code;
String[] cmds = {CMD_DNS_PROXYING_ADD}; String[] cmds = {baseDir + CMD_DNS_PROXYING_ADD};
code = TorServiceUtils.doShellCommand(cmds, log, true, true); code = TorServiceUtils.doShellCommand(cmds, log, true, true);
@ -78,15 +106,21 @@ public class TorTransProxy {
} }
*/ */
public static boolean purgeNatIptables() { public static boolean purgeIptables() {
String baseDir = findBaseDir();
StringBuilder res = new StringBuilder(); StringBuilder res = new StringBuilder();
try { try {
String[] cmds = {CMD_NAT_FLUSH}; String[] cmds = {baseDir + CMD_NAT_FLUSH, baseDir + CMD_FILTER_FLUSH};
int code = TorServiceUtils.doShellCommand(cmds, res, true, true); int code = TorServiceUtils.doShellCommand(cmds, res, true, true);
if (code != 0) { if (code != 0) {
Log.w(TAG, "error purging iptables. exit code: " + code + "\n" + res); Log.w(TAG, "error purging iptables. exit code: " + code + "\n" + res);
return false; return false;
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {
Log.w(TAG,"error purging iptables: " + e); Log.w(TAG,"error purging iptables: " + e);
@ -97,6 +131,8 @@ public class TorTransProxy {
public static boolean setTransparentProxyingByApp(Context context, TorifiedApp[] apps, boolean forceAll) throws Exception public static boolean setTransparentProxyingByApp(Context context, TorifiedApp[] apps, boolean forceAll) throws Exception
{ {
String baseDir = findBaseDir();
String command = null; String command = null;
command = IPTABLES_ADD; //ADD command = IPTABLES_ADD; //ADD
@ -121,30 +157,49 @@ public class TorTransProxy {
Log.i(TAG,"enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")"); Log.i(TAG,"enabling transproxy for app: " + apps[i].getUsername() + "(" + apps[i].getUid() + ")");
//TCP //TCP
script.append(baseDir);
script.append("iptables -t nat"); script.append("iptables -t nat");
script.append(command); script.append(" -A OUTPUT -p tcp -m owner --uid-owner ");
script.append("OUTPUT -p tcp -m owner --uid-owner ");
script.append(apps[i].getUid()); script.append(apps[i].getUid());
script.append(" -j DNAT --to 127.0.0.1:9040"); // script.append(" -j DNAT --to 127.0.0.1:9040");
script.append(" -m tcp --syn -j REDIRECT --to-ports 9040");
script.append(" || exit\n"); script.append(" || exit\n");
//UDP //UDP
script.append(baseDir);
script.append("iptables -t nat"); script.append("iptables -t nat");
script.append(command); script.append(" -A OUTPUT -p udp -m owner --uid-owner ");
script.append("OUTPUT -p udp -m owner --uid-owner ");
script.append(apps[i].getUid()); script.append(apps[i].getUid());
script.append(" -j DROP"); //drop all UDP packets as Tor won't handle them script.append(" --dport 53 -j REDIRECT --to-ports 5400"); //drop all UDP packets as Tor won't handle them
script.append(" || exit\n"); script.append(" || exit\n");
script.append(baseDir);
script.append("iptables -t nat");
script.append(" -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
script.append(" || exit\n");
/*
* iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner anonymous -m tcp -j REDIRECT --to-ports 9040
iptables -t nat -A OUTPUT -p udp -m owner --uid-owner anonymous -m udp --dport 53 -j REDIRECT --to-ports 53
iptables -t filter -A OUTPUT -p tcp -m owner --uid-owner anonymous -m tcp --dport 9040 -j ACCEPT
iptables -t filter -A OUTPUT -p udp -m owner --uid-owner anonymous -m udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -m owner --uid-owner anonymous -j DROP
*/
} }
} }
String[] cmd = {script.toString()}; String[] cmd = {script.toString()};
Log.i(TAG, cmd[0]);
code = TorServiceUtils.doShellCommand(cmd, res, true, true); code = TorServiceUtils.doShellCommand(cmd, res, true, true);
String msg = res.toString(); String msg = res.toString();
Log.e(TAG, msg); Log.i(TAG, msg);
return false; return false;
@ -153,9 +208,8 @@ public class TorTransProxy {
public static boolean setTransparentProxyingByPort(Context context, String[] ports) { public static boolean setTransparentProxyingByPort(Context context, String[] ports) {
String command = null; String baseDir = findBaseDir();
command = IPTABLES_ADD; //ADD
final StringBuilder script = new StringBuilder(); final StringBuilder script = new StringBuilder();
@ -167,6 +221,8 @@ public class TorTransProxy {
Log.i(TAG,"enabling transproxy for port: " + ports[i]); Log.i(TAG,"enabling transproxy for port: " + ports[i]);
//TCP //TCP
script.append(baseDir);
script.append("iptables -t nat"); script.append("iptables -t nat");
script.append("-A PREROUTING -p tcp --dport "); script.append("-A PREROUTING -p tcp --dport ");
script.append(ports[i]); script.append(ports[i]);
@ -174,6 +230,8 @@ public class TorTransProxy {
script.append(" || exit\n"); script.append(" || exit\n");
//UDP //UDP
script.append(baseDir);
script.append("iptables -t nat"); script.append("iptables -t nat");
script.append("-A PREROUTING -p udp --dport "); script.append("-A PREROUTING -p udp --dport ");
script.append(ports[i]); script.append(ports[i]);
@ -185,6 +243,7 @@ public class TorTransProxy {
StringBuilder res = new StringBuilder(); StringBuilder res = new StringBuilder();
String[] cmd = {script.toString()}; String[] cmd = {script.toString()};
Log.i(TAG, cmd[0]);
code = TorServiceUtils.doShellCommand(cmd, res, true, true); code = TorServiceUtils.doShellCommand(cmd, res, true, true);