fix xtables installation and permission setting
more fixes for running from sdcard
This commit is contained in:
parent
43625f835b
commit
f538930b7c
|
@ -1,255 +0,0 @@
|
||||||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
|
||||||
/* See LICENSE for licensing information */
|
|
||||||
|
|
||||||
package org.torproject.android.service;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
|
|
||||||
import org.torproject.android.R;
|
|
||||||
import org.torproject.android.TorConstants;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class TorBinaryInstaller implements TorServiceConstants {
|
|
||||||
|
|
||||||
|
|
||||||
File installFolder;
|
|
||||||
Context context;
|
|
||||||
|
|
||||||
private static int isARMv6 = -1;
|
|
||||||
private static String CHMOD_EXEC = "700";
|
|
||||||
|
|
||||||
public TorBinaryInstaller (Context context, File installFolder)
|
|
||||||
{
|
|
||||||
this.installFolder = installFolder;
|
|
||||||
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
/*
|
|
||||||
* Extract the Tor binary from the APK file using ZIP
|
|
||||||
*/
|
|
||||||
public boolean installResources () throws IOException, FileNotFoundException
|
|
||||||
{
|
|
||||||
|
|
||||||
InputStream is;
|
|
||||||
File outFile;
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.torrc);
|
|
||||||
outFile = new File(installFolder, TORRC_ASSET_KEY);
|
|
||||||
streamToFile(is,outFile, false, false);
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.torrctether);
|
|
||||||
outFile = new File(installFolder, TORRC_TETHER_KEY);
|
|
||||||
streamToFile(is, outFile, false, false);
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.privoxy_config);
|
|
||||||
outFile = new File(installFolder, PRIVOXYCONFIG_ASSET_KEY);
|
|
||||||
streamToFile(is,outFile, false, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extract the Tor binary from the APK file using ZIP
|
|
||||||
*/
|
|
||||||
|
|
||||||
public boolean installGeoIP () throws IOException, FileNotFoundException
|
|
||||||
{
|
|
||||||
|
|
||||||
InputStream is;
|
|
||||||
File outFile;
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.geoip);
|
|
||||||
outFile = new File(installFolder, GEOIP_ASSET_KEY);
|
|
||||||
streamToFile(is, outFile, false, true);
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.geoip6);
|
|
||||||
outFile = new File(installFolder, GEOIP6_ASSET_KEY);
|
|
||||||
streamToFile(is, outFile, false, true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
private static void copyAssetFile(Context ctx, String asset, File file) throws IOException, InterruptedException
|
|
||||||
{
|
|
||||||
|
|
||||||
DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
|
|
||||||
InputStream is = new GZIPInputStream(ctx.getAssets().open(asset));
|
|
||||||
|
|
||||||
byte buf[] = new byte[8172];
|
|
||||||
int len;
|
|
||||||
while ((len = is.read(buf)) > 0) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
is.close();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write the inputstream contents to the file
|
|
||||||
*/
|
|
||||||
private static boolean streamToFile(InputStream stm, File outFile, boolean append, boolean zip) throws IOException
|
|
||||||
|
|
||||||
{
|
|
||||||
byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
|
|
||||||
|
|
||||||
int bytecount;
|
|
||||||
|
|
||||||
|
|
||||||
OutputStream stmOut = new FileOutputStream(outFile, append);
|
|
||||||
ZipInputStream zis = null;
|
|
||||||
|
|
||||||
if (zip)
|
|
||||||
{
|
|
||||||
zis = new ZipInputStream(stm);
|
|
||||||
ZipEntry ze = zis.getNextEntry();
|
|
||||||
stm = zis;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((bytecount = stm.read(buffer)) > 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
stmOut.write(buffer, 0, bytecount);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
stmOut.close();
|
|
||||||
stm.close();
|
|
||||||
|
|
||||||
if (zis != null)
|
|
||||||
zis.close();
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy the file from inputstream to File output - alternative impl
|
|
||||||
public void copyFile (InputStream is, File outputFile)
|
|
||||||
{
|
|
||||||
|
|
||||||
try {
|
|
||||||
outputFile.createNewFile();
|
|
||||||
DataOutputStream out = new DataOutputStream(new FileOutputStream(outputFile));
|
|
||||||
DataInputStream in = new DataInputStream(is);
|
|
||||||
|
|
||||||
int b = -1;
|
|
||||||
byte[] data = new byte[1024];
|
|
||||||
|
|
||||||
while ((b = in.read(data)) != -1) {
|
|
||||||
out.write(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b == -1); //rejoice
|
|
||||||
|
|
||||||
//
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
in.close();
|
|
||||||
// chmod?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Log.e(TorConstants.TAG, "error copying binary", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if this is an ARMv6 device
|
|
||||||
* @return true if this is ARMv6
|
|
||||||
*/
|
|
||||||
private static boolean isARMv6() {
|
|
||||||
if (isARMv6 == -1) {
|
|
||||||
BufferedReader r = null;
|
|
||||||
try {
|
|
||||||
isARMv6 = 0;
|
|
||||||
r = new BufferedReader(new FileReader("/proc/cpuinfo"));
|
|
||||||
for (String line = r.readLine(); line != null; line = r.readLine()) {
|
|
||||||
if (line.startsWith("Processor") && line.contains("ARMv6")) {
|
|
||||||
isARMv6 = 1;
|
|
||||||
break;
|
|
||||||
} else if (line.startsWith("CPU architecture") && (line.contains("6TE") || line.contains("5TE"))) {
|
|
||||||
isARMv6 = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
} finally {
|
|
||||||
if (r != null) try {r.close();} catch (Exception ex) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (isARMv6 == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies a raw resource file, given its ID to the given location
|
|
||||||
* @param ctx context
|
|
||||||
* @param resid resource id
|
|
||||||
* @param file destination file
|
|
||||||
* @param mode file permissions (E.g.: "755")
|
|
||||||
* @throws IOException on error
|
|
||||||
* @throws InterruptedException when interrupted
|
|
||||||
*/
|
|
||||||
private static void copyRawFile(Context ctx, int resid, File file, String mode, boolean isZipd) throws IOException, InterruptedException
|
|
||||||
{
|
|
||||||
final String abspath = file.getAbsolutePath();
|
|
||||||
// Write the iptables binary
|
|
||||||
final FileOutputStream out = new FileOutputStream(file);
|
|
||||||
InputStream is = ctx.getResources().openRawResource(resid);
|
|
||||||
|
|
||||||
if (isZipd)
|
|
||||||
{
|
|
||||||
ZipInputStream zis = new ZipInputStream(is);
|
|
||||||
ZipEntry ze = zis.getNextEntry();
|
|
||||||
is = zis;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte buf[] = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = is.read(buf)) > 0) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
is.close();
|
|
||||||
// Change the permissions
|
|
||||||
Runtime.getRuntime().exec("chmod "+mode+" "+abspath).waitFor();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Asserts that the binary files are installed in the bin directory.
|
|
||||||
* @param ctx context
|
|
||||||
* @param showErrors indicates if errors should be alerted
|
|
||||||
* @return false if the binary files could not be installed
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
public static boolean assertIpTablesBinaries(Context ctx, boolean showErrors) throws Exception {
|
|
||||||
boolean changed = false;
|
|
||||||
|
|
||||||
// Check iptables_g1
|
|
||||||
File file = new File(ctx.getDir("bin",0), "iptables");
|
|
||||||
copyRawFile(ctx, R.raw.iptables, file, CHMOD_EXEC, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -87,6 +87,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
private File filePrivoxy;
|
private File filePrivoxy;
|
||||||
private File fileObfsProxy;
|
private File fileObfsProxy;
|
||||||
|
private File fileXtables;
|
||||||
|
|
||||||
private File fileTorRc;
|
private File fileTorRc;
|
||||||
|
|
||||||
private TorTransProxy mTransProxy;
|
private TorTransProxy mTransProxy;
|
||||||
|
@ -389,30 +391,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
public void reloadConfig ()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (conn == null)
|
|
||||||
{
|
|
||||||
initControlConnection ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn != null)
|
|
||||||
{
|
|
||||||
conn.signal("RELOAD");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.d(TAG,"Unable to reload configuration",e);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String getHiddenServiceHostname ()
|
private String getHiddenServiceHostname ()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -467,16 +445,27 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
if (!fileTorLink.exists()||(fileTorOrig.length()!=fileTorLink.length()))
|
if (!fileTorLink.exists()||(fileTorOrig.length()!=fileTorLink.length()))
|
||||||
{
|
{
|
||||||
String[] cmd = { SHELL_CMD_CP + ' ' + fileTorOrig.getAbsolutePath() + ' ' + fileTorLink.getAbsolutePath() };
|
log = new StringBuilder();
|
||||||
|
String[] cmd = { SHELL_CMD_RM + ' ' + fileTorLink.getAbsolutePath() };
|
||||||
errCode = TorServiceUtils.doShellCommand(cmd,log, false, true);
|
errCode = TorServiceUtils.doShellCommand(cmd,log, false, true);
|
||||||
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
|
|
||||||
|
log = new StringBuilder();
|
||||||
|
String[] cmd1 = { SHELL_CMD_CP + ' ' + fileTorOrig.getAbsolutePath() + ' ' + fileTorLink.getAbsolutePath() };
|
||||||
|
errCode = TorServiceUtils.doShellCommand(cmd1,log, false, true);
|
||||||
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
}
|
}
|
||||||
enableBinExec(fileTorLink);
|
enableBinExec(fileTorLink);
|
||||||
|
|
||||||
log = new StringBuilder();
|
|
||||||
File filePrivoxyLink = new File(appBinHome,"privoxy");
|
File filePrivoxyLink = new File(appBinHome,"privoxy");
|
||||||
if (!filePrivoxyLink.exists()||(filePrivoxy.length()!=filePrivoxyLink.length()))
|
if (!filePrivoxyLink.exists()||(filePrivoxy.length()!=filePrivoxyLink.length()))
|
||||||
{
|
{
|
||||||
|
log = new StringBuilder();
|
||||||
|
String[] cmd = { SHELL_CMD_RM + ' ' + filePrivoxyLink.getAbsolutePath() };
|
||||||
|
errCode = TorServiceUtils.doShellCommand(cmd,log, false, true);
|
||||||
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
|
|
||||||
|
log = new StringBuilder();
|
||||||
String[] cmd1 = { SHELL_CMD_CP + ' ' + filePrivoxy.getAbsolutePath() + ' ' + filePrivoxyLink.getAbsolutePath() };
|
String[] cmd1 = { SHELL_CMD_CP + ' ' + filePrivoxy.getAbsolutePath() + ' ' + filePrivoxyLink.getAbsolutePath() };
|
||||||
errCode = TorServiceUtils.doShellCommand(cmd1,log, false, true);
|
errCode = TorServiceUtils.doShellCommand(cmd1,log, false, true);
|
||||||
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
|
@ -484,10 +473,17 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
filePrivoxy = filePrivoxyLink;
|
filePrivoxy = filePrivoxyLink;
|
||||||
enableBinExec(filePrivoxy);
|
enableBinExec(filePrivoxy);
|
||||||
|
|
||||||
log = new StringBuilder();
|
|
||||||
File fileObfsProxyLink = new File(appBinHome,"obfsproxy");
|
File fileObfsProxyLink = new File(appBinHome,"obfsproxy");
|
||||||
if (!fileObfsProxyLink.exists()||(fileObfsProxy.length()!=fileObfsProxyLink.length()))
|
if (!fileObfsProxyLink.exists()||(fileObfsProxy.length()!=fileObfsProxyLink.length()))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
log = new StringBuilder();
|
||||||
|
String[] cmd1 = { SHELL_CMD_RM + ' ' + fileObfsProxyLink.getAbsolutePath() };
|
||||||
|
errCode = TorServiceUtils.doShellCommand(cmd1,log, false, true);
|
||||||
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
|
|
||||||
|
|
||||||
|
log = new StringBuilder();
|
||||||
String[] cmd2 = { SHELL_CMD_CP + ' ' + fileObfsProxy.getAbsolutePath() + ' ' + fileObfsProxyLink.getAbsolutePath() };
|
String[] cmd2 = { SHELL_CMD_CP + ' ' + fileObfsProxy.getAbsolutePath() + ' ' + fileObfsProxyLink.getAbsolutePath() };
|
||||||
errCode = TorServiceUtils.doShellCommand(cmd2,log, false, true);
|
errCode = TorServiceUtils.doShellCommand(cmd2,log, false, true);
|
||||||
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
|
@ -495,6 +491,23 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
fileObfsProxy = fileObfsProxyLink;
|
fileObfsProxy = fileObfsProxyLink;
|
||||||
enableBinExec(fileObfsProxy);
|
enableBinExec(fileObfsProxy);
|
||||||
|
|
||||||
|
|
||||||
|
File fileXtablesLink = new File(appBinHome,"xtables");
|
||||||
|
if (!fileXtablesLink.exists()||(fileXtables.length()!=fileXtablesLink.length()))
|
||||||
|
{
|
||||||
|
log = new StringBuilder();
|
||||||
|
String[] cmd1 = { SHELL_CMD_RM + ' ' + fileXtablesLink.getAbsolutePath() };
|
||||||
|
errCode = TorServiceUtils.doShellCommand(cmd1,log, false, true);
|
||||||
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
|
|
||||||
|
log = new StringBuilder();
|
||||||
|
String[] cmd2 = { SHELL_CMD_CP + ' ' + fileXtables.getAbsolutePath() + ' ' + fileXtablesLink.getAbsolutePath() };
|
||||||
|
errCode = TorServiceUtils.doShellCommand(cmd2,log, false, true);
|
||||||
|
logNotice("link CP err=" + errCode + " out: " + log.toString());
|
||||||
|
}
|
||||||
|
fileXtables = fileXtablesLink;
|
||||||
|
enableBinExec(fileXtables);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -517,6 +530,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
enableBinExec(filePrivoxy);
|
enableBinExec(filePrivoxy);
|
||||||
enableBinExec(fileObfsProxy);
|
enableBinExec(fileObfsProxy);
|
||||||
|
enableBinExec(fileXtables);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,11 +657,15 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
|
|
||||||
if (!fileTorRc.exists())
|
if (!fileTorRc.exists())
|
||||||
{
|
{
|
||||||
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome);
|
TorResourceInstaller installer = new TorResourceInstaller(this, appBinHome);
|
||||||
boolean success = installer.installResources();
|
boolean success = installer.installResources();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileXtables = new File(appLibsHome, IPTABLES_BINARY_ASSET_KEY);
|
||||||
|
if (fileXtables.exists())
|
||||||
|
logNotice("Xtables binary exists: " + fileXtables.getAbsolutePath());
|
||||||
|
|
||||||
initTorPathLinkAndPerms();
|
initTorPathLinkAndPerms();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -717,7 +735,10 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
{
|
{
|
||||||
|
|
||||||
if (mTransProxy == null)
|
if (mTransProxy == null)
|
||||||
|
{
|
||||||
mTransProxy = new TorTransProxy(this);
|
mTransProxy = new TorTransProxy(this);
|
||||||
|
mTransProxy.setXTables(fileXtables);
|
||||||
|
}
|
||||||
|
|
||||||
logMessage ("Transparent Proxying: enabling...");
|
logMessage ("Transparent Proxying: enabling...");
|
||||||
|
|
||||||
|
@ -1697,7 +1718,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
|
||||||
{
|
{
|
||||||
if ((!fileGeoIP.exists()))
|
if ((!fileGeoIP.exists()))
|
||||||
{
|
{
|
||||||
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome);
|
TorResourceInstaller installer = new TorResourceInstaller(this, appBinHome);
|
||||||
boolean success = installer.installGeoIP();
|
boolean success = installer.installGeoIP();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,16 @@ public class TorTransProxy implements TorServiceConstants {
|
||||||
private boolean useSystemIpTables = false;
|
private boolean useSystemIpTables = false;
|
||||||
private String mSysIptables = null;
|
private String mSysIptables = null;
|
||||||
private TorService mTorService = null;
|
private TorService mTorService = null;
|
||||||
|
private File mFileXtables = null;
|
||||||
|
|
||||||
public TorTransProxy (TorService torService)
|
public TorTransProxy (TorService torService)
|
||||||
{
|
{
|
||||||
mTorService = torService;
|
mTorService = torService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TorTransProxy ()
|
public void setXTables (File fileXTables)
|
||||||
{
|
{
|
||||||
|
mFileXtables = fileXTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIpTablesPath (Context context)
|
public String getIpTablesPath (Context context)
|
||||||
|
@ -41,9 +43,7 @@ public class TorTransProxy implements TorServiceConstants {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//use the bundled version
|
ipTablesPath = mFileXtables.getAbsolutePath();
|
||||||
File appLibsHome = new File(context.getApplicationInfo().nativeLibraryDir);
|
|
||||||
ipTablesPath = new File(appLibsHome,IPTABLES_BINARY_ASSET_KEY).getAbsolutePath();
|
|
||||||
ipTablesPath += " iptables"; //append subcommand since we are using xtables now
|
ipTablesPath += " iptables"; //append subcommand since we are using xtables now
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue