improve tor service event handling and display
This commit is contained in:
parent
ebc046e92d
commit
9f61afcdef
|
@ -0,0 +1,328 @@
|
||||||
|
package org.torproject.android.service;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.torproject.android.control.ConfigEntry;
|
||||||
|
import org.torproject.android.control.EventHandler;
|
||||||
|
import org.torproject.android.control.TorControlConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by n8fr8 on 9/25/16.
|
||||||
|
*/
|
||||||
|
public class TorEventHandler implements EventHandler, TorServiceConstants {
|
||||||
|
|
||||||
|
private TorService mService;
|
||||||
|
|
||||||
|
|
||||||
|
private long lastRead = -1;
|
||||||
|
private long lastWritten = -1;
|
||||||
|
private long mTotalTrafficWritten = 0;
|
||||||
|
private long mTotalTrafficRead = 0;
|
||||||
|
|
||||||
|
private NumberFormat mNumberFormat = null;
|
||||||
|
|
||||||
|
|
||||||
|
private HashMap<String,Node> hmBuiltNodes = new HashMap<String,Node>();
|
||||||
|
|
||||||
|
public class Node
|
||||||
|
{
|
||||||
|
String status;
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
String ipAddress;
|
||||||
|
String country;
|
||||||
|
String organization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String,Node> getNodes ()
|
||||||
|
{
|
||||||
|
return hmBuiltNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TorEventHandler (TorService service)
|
||||||
|
{
|
||||||
|
mService = service;
|
||||||
|
mNumberFormat = NumberFormat.getInstance(Locale.getDefault()); //localized numbers!
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void message(String severity, String msg) {
|
||||||
|
mService.logNotice(severity + ": " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void newDescriptors(List<String> orList) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void orConnStatus(String status, String orName) {
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("orConnStatus (");
|
||||||
|
sb.append(parseNodeName(orName) );
|
||||||
|
sb.append("): ");
|
||||||
|
sb.append(status);
|
||||||
|
|
||||||
|
mService.debug(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamStatus(String status, String streamID, String target) {
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("StreamStatus (");
|
||||||
|
sb.append((streamID));
|
||||||
|
sb.append("): ");
|
||||||
|
sb.append(status);
|
||||||
|
|
||||||
|
mService.logNotice(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unrecognized(String type, String msg) {
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Message (");
|
||||||
|
sb.append(type);
|
||||||
|
sb.append("): ");
|
||||||
|
sb.append(msg);
|
||||||
|
|
||||||
|
mService.logNotice(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bandwidthUsed(long read, long written) {
|
||||||
|
|
||||||
|
if (read != lastRead || written != lastWritten)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(formatCount(read));
|
||||||
|
sb.append(" \u2193");
|
||||||
|
sb.append(" / ");
|
||||||
|
sb.append(formatCount(written));
|
||||||
|
sb.append(" \u2191");
|
||||||
|
|
||||||
|
int iconId = R.drawable.ic_stat_tor;
|
||||||
|
|
||||||
|
if (read > 0 || written > 0)
|
||||||
|
iconId = R.drawable.ic_stat_tor_xfer;
|
||||||
|
|
||||||
|
if (mService.hasConnectivity() && Prefs.expandedNotifications())
|
||||||
|
mService.showToolbarNotification(sb.toString(), mService.getNotifyId(), iconId);
|
||||||
|
|
||||||
|
mTotalTrafficWritten += written;
|
||||||
|
mTotalTrafficRead += read;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastWritten = written;
|
||||||
|
lastRead = read;
|
||||||
|
|
||||||
|
mService.sendCallbackBandwidth(lastWritten, lastRead, mTotalTrafficWritten, mTotalTrafficRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatCount(long count) {
|
||||||
|
// Converts the supplied argument into a string.
|
||||||
|
|
||||||
|
// Under 2Mb, returns "xxx.xKb"
|
||||||
|
// Over 2Mb, returns "xxx.xxMb"
|
||||||
|
if (mNumberFormat != null)
|
||||||
|
if (count < 1e6)
|
||||||
|
return mNumberFormat.format(Math.round((float)((int)(count*10/1024))/10)) + "kbps";
|
||||||
|
else
|
||||||
|
return mNumberFormat.format(Math.round((float)((int)(count*100/1024/1024))/100)) + "mbps";
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
|
||||||
|
//return count+" kB";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void circuitStatus(String status, String circID, String path) {
|
||||||
|
|
||||||
|
/* once the first circuit is complete, then announce that Orbot is on*/
|
||||||
|
if (mService.getCurrentStatus() == STATUS_STARTING && TextUtils.equals(status, "BUILT"))
|
||||||
|
mService.sendCallbackStatus(STATUS_ON);
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Circuit (");
|
||||||
|
sb.append((circID));
|
||||||
|
sb.append(") ");
|
||||||
|
sb.append(status);
|
||||||
|
sb.append(": ");
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer(path,",");
|
||||||
|
Node node = null;
|
||||||
|
|
||||||
|
while (st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
String nodePath = st.nextToken();
|
||||||
|
node = new Node();
|
||||||
|
|
||||||
|
String[] nodeParts;
|
||||||
|
|
||||||
|
if (nodePath.contains("="))
|
||||||
|
nodeParts = nodePath.split("=");
|
||||||
|
else
|
||||||
|
nodeParts = nodePath.split("~");
|
||||||
|
|
||||||
|
if (nodeParts.length == 1)
|
||||||
|
{
|
||||||
|
node.id = nodeParts[0].substring(1);
|
||||||
|
node.name = node.id;
|
||||||
|
}
|
||||||
|
else if (nodeParts.length == 2)
|
||||||
|
{
|
||||||
|
node.id = nodeParts[0].substring(1);
|
||||||
|
node.name = nodeParts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
node.status = status;
|
||||||
|
|
||||||
|
sb.append(node.name);
|
||||||
|
|
||||||
|
if (st.hasMoreTokens())
|
||||||
|
sb.append (" > ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Prefs.useDebugLogging())
|
||||||
|
mService.debug(sb.toString());
|
||||||
|
else if(status.equals("BUILT"))
|
||||||
|
mService.logNotice(sb.toString());
|
||||||
|
else if (status.equals("CLOSED"))
|
||||||
|
mService.logNotice(sb.toString());
|
||||||
|
|
||||||
|
if (Prefs.expandedNotifications())
|
||||||
|
{
|
||||||
|
//get IP from last nodename
|
||||||
|
if(status.equals("BUILT")){
|
||||||
|
|
||||||
|
if (node.ipAddress == null)
|
||||||
|
mService.exec(new ExternalIPFetcher(node));
|
||||||
|
|
||||||
|
hmBuiltNodes.put(node.id, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.equals("CLOSED"))
|
||||||
|
{
|
||||||
|
hmBuiltNodes.remove(node.id);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ExternalIPFetcher implements Runnable {
|
||||||
|
|
||||||
|
private Node mNode;
|
||||||
|
private int MAX_ATTEMPTS = 3;
|
||||||
|
private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addresses&lookup=";
|
||||||
|
|
||||||
|
public ExternalIPFetcher (Node node)
|
||||||
|
{
|
||||||
|
mNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_ATTEMPTS; i++)
|
||||||
|
{
|
||||||
|
if (mService.getControlConnection() != null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
URLConnection conn = null;
|
||||||
|
|
||||||
|
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118));
|
||||||
|
conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
|
||||||
|
|
||||||
|
conn.setRequestProperty("Connection","Close");
|
||||||
|
conn.setConnectTimeout(60000);
|
||||||
|
conn.setReadTimeout(60000);
|
||||||
|
|
||||||
|
InputStream is = conn.getInputStream();
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||||
|
|
||||||
|
// getting JSON string from URL
|
||||||
|
|
||||||
|
StringBuffer json = new StringBuffer();
|
||||||
|
String line = null;
|
||||||
|
|
||||||
|
while ((line = reader.readLine())!=null)
|
||||||
|
json.append(line);
|
||||||
|
|
||||||
|
JSONObject jsonNodeInfo = new org.json.JSONObject(json.toString());
|
||||||
|
|
||||||
|
JSONArray jsonRelays = jsonNodeInfo.getJSONArray("relays");
|
||||||
|
|
||||||
|
if (jsonRelays.length() > 0)
|
||||||
|
{
|
||||||
|
mNode.ipAddress = jsonRelays.getJSONObject(0).getJSONArray("or_addresses").getString(0).split(":")[0];
|
||||||
|
mNode.country = jsonRelays.getJSONObject(0).getString("country_name");
|
||||||
|
mNode.organization = jsonRelays.getJSONObject(0).getString("as_name");
|
||||||
|
|
||||||
|
StringBuffer sbInfo = new StringBuffer();
|
||||||
|
sbInfo.append(mNode.ipAddress);
|
||||||
|
|
||||||
|
if (mNode.country != null)
|
||||||
|
sbInfo.append(' ').append(mNode.country);
|
||||||
|
|
||||||
|
if (mNode.organization != null)
|
||||||
|
sbInfo.append(" (").append(mNode.organization).append(')');
|
||||||
|
|
||||||
|
mService.logNotice(sbInfo.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
mService.debug ("Error getting node details from onionoo: " + e.getMessage());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseNodeName(String node)
|
||||||
|
{
|
||||||
|
if (node.indexOf('=')!=-1)
|
||||||
|
{
|
||||||
|
return (node.substring(node.indexOf("=")+1));
|
||||||
|
}
|
||||||
|
else if (node.indexOf('~')!=-1)
|
||||||
|
{
|
||||||
|
return (node.substring(node.indexOf("~")+1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,7 +77,7 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
public class TorService extends Service implements TorServiceConstants, OrbotConstants, EventHandler
|
public class TorService extends Service implements TorServiceConstants, OrbotConstants
|
||||||
{
|
{
|
||||||
|
|
||||||
private String mCurrentStatus = STATUS_OFF;
|
private String mCurrentStatus = STATUS_OFF;
|
||||||
|
@ -106,14 +106,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
|
|
||||||
private TorTransProxy mTransProxy;
|
private TorTransProxy mTransProxy;
|
||||||
|
|
||||||
private long mTotalTrafficWritten = 0;
|
private boolean mConnectivity = true;
|
||||||
private long mTotalTrafficRead = 0;
|
|
||||||
private boolean mConnectivity = true;
|
|
||||||
private int mNetworkType = -1;
|
private int mNetworkType = -1;
|
||||||
|
|
||||||
private long lastRead = -1;
|
|
||||||
private long lastWritten = -1;
|
|
||||||
|
|
||||||
private NotificationManager mNotificationManager = null;
|
private NotificationManager mNotificationManager = null;
|
||||||
private Notification.Builder mNotifyBuilder;
|
private Notification.Builder mNotifyBuilder;
|
||||||
private Notification mNotification;
|
private Notification mNotification;
|
||||||
|
@ -123,8 +118,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
|
|
||||||
private ExecutorService mExecutor = Executors.newFixedThreadPool(1);
|
private ExecutorService mExecutor = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
private NumberFormat mNumberFormat = null;
|
|
||||||
|
TorEventHandler mEventHandler;
|
||||||
|
|
||||||
// private OrbotVpnManager mVpnManager;
|
// private OrbotVpnManager mVpnManager;
|
||||||
|
|
||||||
public static File appBinHome;
|
public static File appBinHome;
|
||||||
|
@ -133,7 +129,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
public static File fileTor;
|
public static File fileTor;
|
||||||
public static File filePolipo;
|
public static File filePolipo;
|
||||||
public static File fileObfsclient;
|
public static File fileObfsclient;
|
||||||
// public static File fileMeekclient;
|
|
||||||
public static File fileXtables;
|
public static File fileXtables;
|
||||||
public static File fileTorRc;
|
public static File fileTorRc;
|
||||||
public static File filePdnsd;
|
public static File filePdnsd;
|
||||||
|
@ -198,12 +193,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
mNotificationManager.cancelAll();
|
mNotificationManager.cancelAll();
|
||||||
|
|
||||||
|
|
||||||
hmBuiltNodes.clear();
|
mEventHandler.getNodes().clear();
|
||||||
mNotificationShowing = false;
|
mNotificationShowing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private void showToolbarNotification (String notifyMsg, int notifyType, int icon)
|
protected void showToolbarNotification (String notifyMsg, int notifyType, int icon)
|
||||||
{
|
{
|
||||||
|
|
||||||
//Reusable code.
|
//Reusable code.
|
||||||
|
@ -258,12 +253,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
expandedView.setTextViewText(R.id.info, notifyMsg);
|
expandedView.setTextViewText(R.id.info, notifyMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hmBuiltNodes.size() > 0)
|
if (mEventHandler.getNodes().size() > 0)
|
||||||
{
|
{
|
||||||
Set<String> itBuiltNodes = hmBuiltNodes.keySet();
|
Set<String> itBuiltNodes = mEventHandler.getNodes().keySet();
|
||||||
for (String key : itBuiltNodes)
|
for (String key : itBuiltNodes)
|
||||||
{
|
{
|
||||||
Node node = hmBuiltNodes.get(key);
|
TorEventHandler.Node node = mEventHandler.getNodes().get(key);
|
||||||
|
|
||||||
if (node.ipAddress != null)
|
if (node.ipAddress != null)
|
||||||
{
|
{
|
||||||
|
@ -374,17 +369,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
@Override
|
|
||||||
public void onRevoke ()
|
|
||||||
{
|
|
||||||
//if (mVpnManager != null)
|
|
||||||
// mVpnManager.onRevoke();
|
|
||||||
|
|
||||||
super.onRevoke();
|
|
||||||
|
|
||||||
}**/
|
|
||||||
|
|
||||||
private void stopTor ()
|
private void stopTor ()
|
||||||
{
|
{
|
||||||
mExecutor.execute(new Runnable ()
|
mExecutor.execute(new Runnable ()
|
||||||
|
@ -515,31 +499,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try these separately in case one fails, then it can try the next
|
|
||||||
/**
|
|
||||||
File cannotKillFile = null;
|
|
||||||
try {
|
|
||||||
TorServiceUtils.killProcess(fileObfsclient);
|
|
||||||
} catch (IOException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
Log.w(OrbotConstants.TAG,"could not kill obfsclient",e);
|
|
||||||
cannotKillFile = fileObfsclient;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
TorServiceUtils.killProcess(filePolipo);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(OrbotConstants.TAG,"could not kill polipo",e);
|
|
||||||
cannotKillFile = filePolipo;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
TorServiceUtils.killProcess(fileTor);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(OrbotConstants.TAG,"could not kill tor",e);
|
|
||||||
cannotKillFile = fileTor;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestTorRereadConfig() {
|
private void requestTorRereadConfig() {
|
||||||
|
@ -557,7 +516,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logNotice (String msg)
|
protected void logNotice (String msg)
|
||||||
{
|
{
|
||||||
if (msg != null && msg.trim().length() > 0)
|
if (msg != null && msg.trim().length() > 0)
|
||||||
{
|
{
|
||||||
|
@ -584,7 +543,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
fileTorRc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY);
|
fileTorRc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY);
|
||||||
filePdnsd = new File(appBinHome, TorServiceConstants.PDNSD_ASSET_KEY);
|
filePdnsd = new File(appBinHome, TorServiceConstants.PDNSD_ASSET_KEY);
|
||||||
|
|
||||||
mNumberFormat = NumberFormat.getInstance(Locale.getDefault()); //localized numbers!
|
|
||||||
|
|
||||||
if (mNotificationManager == null)
|
if (mNotificationManager == null)
|
||||||
{
|
{
|
||||||
|
@ -627,6 +585,11 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
Log.i("TorService", "onCreate end");
|
Log.i("TorService", "onCreate end");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getCurrentStatus ()
|
||||||
|
{
|
||||||
|
return mCurrentStatus;
|
||||||
|
}
|
||||||
|
|
||||||
private void torUpgradeAndConfig() throws IOException, TimeoutException {
|
private void torUpgradeAndConfig() throws IOException, TimeoutException {
|
||||||
if (isTorUpgradeAndConfigComplete)
|
if (isTorUpgradeAndConfigComplete)
|
||||||
return;
|
return;
|
||||||
|
@ -890,7 +853,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ArrayList<TorifiedApp> apps = getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext()));
|
ArrayList<TorifiedApp> apps = TorTransProxy.getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext()));
|
||||||
|
|
||||||
code = mTransProxy.setTransparentProxyingByApp(this,apps, true);
|
code = mTransProxy.setTransparentProxyingByApp(this,apps, true);
|
||||||
}
|
}
|
||||||
|
@ -923,114 +886,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<TorifiedApp> getApps (Context context, SharedPreferences prefs)
|
|
||||||
{
|
|
||||||
|
|
||||||
String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, "");
|
|
||||||
String[] tordApps;
|
|
||||||
|
|
||||||
StringTokenizer st = new StringTokenizer(tordAppString,"|");
|
|
||||||
tordApps = new String[st.countTokens()];
|
|
||||||
int tordIdx = 0;
|
|
||||||
while (st.hasMoreTokens())
|
|
||||||
{
|
|
||||||
tordApps[tordIdx++] = st.nextToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
Arrays.sort(tordApps);
|
|
||||||
|
|
||||||
//else load the apps up
|
|
||||||
PackageManager pMgr = context.getPackageManager();
|
|
||||||
|
|
||||||
List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0);
|
|
||||||
|
|
||||||
Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator();
|
|
||||||
|
|
||||||
ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>();
|
|
||||||
|
|
||||||
ApplicationInfo aInfo = null;
|
|
||||||
|
|
||||||
int appIdx = 0;
|
|
||||||
TorifiedApp app = null;
|
|
||||||
|
|
||||||
while (itAppInfo.hasNext())
|
|
||||||
{
|
|
||||||
aInfo = itAppInfo.next();
|
|
||||||
|
|
||||||
app = new TorifiedApp();
|
|
||||||
|
|
||||||
try {
|
|
||||||
PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS);
|
|
||||||
|
|
||||||
if (pInfo != null && pInfo.requestedPermissions != null)
|
|
||||||
{
|
|
||||||
for (String permInfo:pInfo.requestedPermissions)
|
|
||||||
{
|
|
||||||
if (permInfo.equals("android.permission.INTERNET"))
|
|
||||||
{
|
|
||||||
app.setUsesInternet(true);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1)
|
|
||||||
{
|
|
||||||
//System app
|
|
||||||
app.setUsesInternet(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!app.usesInternet())
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
apps.add(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
app.setEnabled(aInfo.enabled);
|
|
||||||
app.setUid(aInfo.uid);
|
|
||||||
app.setUsername(pMgr.getNameForUid(app.getUid()));
|
|
||||||
app.setProcname(aInfo.processName);
|
|
||||||
app.setPackageName(aInfo.packageName);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
app.setName(pMgr.getApplicationLabel(aInfo).toString());
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
app.setName(aInfo.packageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//app.setIcon(pMgr.getApplicationIcon(aInfo));
|
|
||||||
|
|
||||||
// check if this application is allowed
|
|
||||||
if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) {
|
|
||||||
app.setTorified(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
app.setTorified(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
appIdx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(apps);
|
|
||||||
|
|
||||||
return apps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* activate means whether to apply the users preferences
|
* activate means whether to apply the users preferences
|
||||||
* or clear them out
|
* or clear them out
|
||||||
|
@ -1046,7 +901,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
mTransProxy = new TorTransProxy(this, fileXtables);
|
mTransProxy = new TorTransProxy(this, fileXtables);
|
||||||
|
|
||||||
mTransProxy.setTransparentProxyingAll(this, false);
|
mTransProxy.setTransparentProxyingAll(this, false);
|
||||||
ArrayList<TorifiedApp> apps = getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext()));
|
ArrayList<TorifiedApp> apps = TorTransProxy.getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext()));
|
||||||
mTransProxy.setTransparentProxyingByApp(this, apps, false);
|
mTransProxy.setTransparentProxyingByApp(this, apps, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1112,6 +967,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void exec (Runnable runn)
|
||||||
|
{
|
||||||
|
mExecutor.execute(runn);
|
||||||
|
}
|
||||||
|
|
||||||
private Process exec (String cmd, boolean wait) throws Exception
|
private Process exec (String cmd, boolean wait) throws Exception
|
||||||
{
|
{
|
||||||
Process proc = Runtime.getRuntime().exec(cmd);
|
Process proc = Runtime.getRuntime().exec(cmd);
|
||||||
|
@ -1157,6 +1018,11 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
logNotice("Polipo is running");
|
logNotice("Polipo is running");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected TorControlConnection getControlConnection ()
|
||||||
|
{
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
private int initControlConnection (int maxTries, boolean isReconnect) throws Exception, RuntimeException
|
private int initControlConnection (int maxTries, boolean isReconnect) throws Exception, RuntimeException
|
||||||
{
|
{
|
||||||
|
@ -1298,7 +1164,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
// ...
|
// ...
|
||||||
logNotice( "adding control port event handler");
|
logNotice( "adding control port event handler");
|
||||||
|
|
||||||
conn.setEventHandler(this);
|
mEventHandler = new TorEventHandler(this);
|
||||||
|
conn.setEventHandler(mEventHandler);
|
||||||
|
|
||||||
conn.setEvents(Arrays.asList(new String[]{
|
conn.setEvents(Arrays.asList(new String[]{
|
||||||
"ORCONN", "CIRC", "NOTICE", "WARN", "ERR","BW"}));
|
"ORCONN", "CIRC", "NOTICE", "WARN", "ERR","BW"}));
|
||||||
|
@ -1361,278 +1228,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void message(String severity, String msg) {
|
|
||||||
logNotice(severity + ": " + msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void newDescriptors(List<String> orList) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void orConnStatus(String status, String orName) {
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("orConnStatus (");
|
|
||||||
sb.append(parseNodeName(orName) );
|
|
||||||
sb.append("): ");
|
|
||||||
sb.append(status);
|
|
||||||
|
|
||||||
debug(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void streamStatus(String status, String streamID, String target) {
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("StreamStatus (");
|
|
||||||
sb.append((streamID));
|
|
||||||
sb.append("): ");
|
|
||||||
sb.append(status);
|
|
||||||
|
|
||||||
logNotice(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unrecognized(String type, String msg) {
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Message (");
|
|
||||||
sb.append(type);
|
|
||||||
sb.append("): ");
|
|
||||||
sb.append(msg);
|
|
||||||
|
|
||||||
logNotice(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bandwidthUsed(long read, long written) {
|
|
||||||
|
|
||||||
if (read != lastRead || written != lastWritten)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(formatCount(read));
|
|
||||||
sb.append(" \u2193");
|
|
||||||
sb.append(" / ");
|
|
||||||
sb.append(formatCount(written));
|
|
||||||
sb.append(" \u2191");
|
|
||||||
|
|
||||||
int iconId = R.drawable.ic_stat_tor;
|
|
||||||
|
|
||||||
if (read > 0 || written > 0)
|
|
||||||
iconId = R.drawable.ic_stat_tor_xfer;
|
|
||||||
|
|
||||||
if (mConnectivity && Prefs.persistNotifications())
|
|
||||||
showToolbarNotification(sb.toString(), NOTIFY_ID, iconId);
|
|
||||||
|
|
||||||
mTotalTrafficWritten += written;
|
|
||||||
mTotalTrafficRead += read;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastWritten = written;
|
|
||||||
lastRead = read;
|
|
||||||
|
|
||||||
sendCallbackBandwidth(lastWritten, lastRead, mTotalTrafficWritten, mTotalTrafficRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatCount(long count) {
|
|
||||||
// Converts the supplied argument into a string.
|
|
||||||
|
|
||||||
// Under 2Mb, returns "xxx.xKb"
|
|
||||||
// Over 2Mb, returns "xxx.xxMb"
|
|
||||||
if (mNumberFormat != null)
|
|
||||||
if (count < 1e6)
|
|
||||||
return mNumberFormat.format(Math.round((float)((int)(count*10/1024))/10)) + "kbps";
|
|
||||||
else
|
|
||||||
return mNumberFormat.format(Math.round((float)((int)(count*100/1024/1024))/100)) + "mbps";
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
|
|
||||||
//return count+" kB";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void circuitStatus(String status, String circID, String path) {
|
|
||||||
|
|
||||||
/* once the first circuit is complete, then announce that Orbot is on*/
|
|
||||||
if (mCurrentStatus == STATUS_STARTING && TextUtils.equals(status, "BUILT"))
|
|
||||||
sendCallbackStatus(STATUS_ON);
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Circuit (");
|
|
||||||
sb.append((circID));
|
|
||||||
sb.append(") ");
|
|
||||||
sb.append(status);
|
|
||||||
sb.append(": ");
|
|
||||||
|
|
||||||
StringTokenizer st = new StringTokenizer(path,",");
|
|
||||||
Node node = null;
|
|
||||||
|
|
||||||
while (st.hasMoreTokens())
|
|
||||||
{
|
|
||||||
String nodePath = st.nextToken();
|
|
||||||
node = new Node();
|
|
||||||
|
|
||||||
String[] nodeParts;
|
|
||||||
|
|
||||||
if (nodePath.contains("="))
|
|
||||||
nodeParts = nodePath.split("=");
|
|
||||||
else
|
|
||||||
nodeParts = nodePath.split("~");
|
|
||||||
|
|
||||||
if (nodeParts.length == 1)
|
|
||||||
{
|
|
||||||
node.id = nodeParts[0].substring(1);
|
|
||||||
node.name = node.id;
|
|
||||||
}
|
|
||||||
else if (nodeParts.length == 2)
|
|
||||||
{
|
|
||||||
node.id = nodeParts[0].substring(1);
|
|
||||||
node.name = nodeParts[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
node.status = status;
|
|
||||||
|
|
||||||
sb.append(node.name);
|
|
||||||
|
|
||||||
if (st.hasMoreTokens())
|
|
||||||
sb.append (" > ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Prefs.useDebugLogging())
|
|
||||||
debug(sb.toString());
|
|
||||||
else if(status.equals("BUILT"))
|
|
||||||
logNotice(sb.toString());
|
|
||||||
else if (status.equals("CLOSED"))
|
|
||||||
logNotice(sb.toString());
|
|
||||||
|
|
||||||
if (Prefs.expandedNotifications())
|
|
||||||
{
|
|
||||||
//get IP from last nodename
|
|
||||||
if(status.equals("BUILT")){
|
|
||||||
|
|
||||||
if (node.ipAddress == null)
|
|
||||||
mExecutor.execute(new ExternalIPFetcher(node));
|
|
||||||
|
|
||||||
hmBuiltNodes.put(node.id, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.equals("CLOSED"))
|
|
||||||
{
|
|
||||||
hmBuiltNodes.remove(node.id);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private HashMap<String,Node> hmBuiltNodes = new HashMap<String,Node>();
|
|
||||||
|
|
||||||
class Node
|
|
||||||
{
|
|
||||||
String status;
|
|
||||||
String id;
|
|
||||||
String name;
|
|
||||||
String ipAddress;
|
|
||||||
String country;
|
|
||||||
String organization;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ExternalIPFetcher implements Runnable {
|
|
||||||
|
|
||||||
private Node mNode;
|
|
||||||
private int MAX_ATTEMPTS = 3;
|
|
||||||
private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addresses&lookup=";
|
|
||||||
|
|
||||||
public ExternalIPFetcher (Node node)
|
|
||||||
{
|
|
||||||
mNode = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run ()
|
|
||||||
{
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_ATTEMPTS; i++)
|
|
||||||
{
|
|
||||||
if (conn != null)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
|
|
||||||
URLConnection conn = null;
|
|
||||||
|
|
||||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118));
|
|
||||||
conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
|
|
||||||
|
|
||||||
conn.setRequestProperty("Connection","Close");
|
|
||||||
conn.setConnectTimeout(60000);
|
|
||||||
conn.setReadTimeout(60000);
|
|
||||||
|
|
||||||
InputStream is = conn.getInputStream();
|
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
|
||||||
|
|
||||||
// getting JSON string from URL
|
|
||||||
|
|
||||||
StringBuffer json = new StringBuffer();
|
|
||||||
String line = null;
|
|
||||||
|
|
||||||
while ((line = reader.readLine())!=null)
|
|
||||||
json.append(line);
|
|
||||||
|
|
||||||
JSONObject jsonNodeInfo = new org.json.JSONObject(json.toString());
|
|
||||||
|
|
||||||
JSONArray jsonRelays = jsonNodeInfo.getJSONArray("relays");
|
|
||||||
|
|
||||||
if (jsonRelays.length() > 0)
|
|
||||||
{
|
|
||||||
mNode.ipAddress = jsonRelays.getJSONObject(0).getJSONArray("or_addresses").getString(0).split(":")[0];
|
|
||||||
mNode.country = jsonRelays.getJSONObject(0).getString("country_name");
|
|
||||||
mNode.organization = jsonRelays.getJSONObject(0).getString("as_name");
|
|
||||||
|
|
||||||
StringBuffer sbInfo = new StringBuffer();
|
|
||||||
sbInfo.append(mNode.ipAddress);
|
|
||||||
|
|
||||||
if (mNode.country != null)
|
|
||||||
sbInfo.append(' ').append(mNode.country);
|
|
||||||
|
|
||||||
if (mNode.organization != null)
|
|
||||||
sbInfo.append(" (").append(mNode.organization).append(')');
|
|
||||||
|
|
||||||
logNotice(sbInfo.toString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.close();
|
|
||||||
is.close();
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
debug ("Error getting node details from onionoo: " + e.getMessage());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String parseNodeName(String node)
|
|
||||||
{
|
|
||||||
if (node.indexOf('=')!=-1)
|
|
||||||
{
|
|
||||||
return (node.substring(node.indexOf("=")+1));
|
|
||||||
}
|
|
||||||
else if (node.indexOf('~')!=-1)
|
|
||||||
{
|
|
||||||
return (node.substring(node.indexOf("~")+1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processTransparentProxying() {
|
public void processTransparentProxying() {
|
||||||
try{
|
try{
|
||||||
|
@ -1835,14 +1433,14 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendCallbackBandwidth(long upload, long download, long written, long read) {
|
protected void sendCallbackBandwidth(long upload, long download, long written, long read) {
|
||||||
Intent intent = new Intent(LOCAL_ACTION_BANDWIDTH);
|
Intent intent = new Intent(LOCAL_ACTION_BANDWIDTH);
|
||||||
|
|
||||||
intent.putExtra("up",upload);
|
intent.putExtra("up",upload);
|
||||||
intent.putExtra("down",download);
|
intent.putExtra("down",download);
|
||||||
intent.putExtra("written",written);
|
intent.putExtra("written",written);
|
||||||
intent.putExtra("read",read);
|
intent.putExtra("read",read);
|
||||||
intent.putExtra(EXTRA_STATUS, mCurrentStatus);
|
intent.putExtra(EXTRA_STATUS, mCurrentStatus);
|
||||||
|
|
||||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
|
@ -1859,7 +1457,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendCallbackStatus(String currentStatus) {
|
protected void sendCallbackStatus(String currentStatus) {
|
||||||
mCurrentStatus = currentStatus;
|
mCurrentStatus = currentStatus;
|
||||||
Intent intent = getActionStatusIntent(currentStatus);
|
Intent intent = getActionStatusIntent(currentStatus);
|
||||||
// send for Orbot internals, using secure local broadcast
|
// send for Orbot internals, using secure local broadcast
|
||||||
|
@ -2401,4 +1999,14 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasConnectivity ()
|
||||||
|
{
|
||||||
|
return mConnectivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNotifyId ()
|
||||||
|
{
|
||||||
|
return NOTIFY_ID;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,17 @@ package org.torproject.android.service;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
public class TorTransProxy implements TorServiceConstants {
|
public class TorTransProxy implements TorServiceConstants {
|
||||||
|
|
||||||
|
@ -169,6 +178,114 @@ public class TorTransProxy implements TorServiceConstants {
|
||||||
script.append(" -t nat -m owner --uid-owner ");
|
script.append(" -t nat -m owner --uid-owner ");
|
||||||
script.append(tApp.getUid());
|
script.append(tApp.getUid());
|
||||||
script.append(" -F || exit\n");
|
script.append(" -F || exit\n");
|
||||||
|
public static ArrayList<TorifiedApp> getApps (Context context, SharedPreferences prefs)
|
||||||
|
{
|
||||||
|
|
||||||
|
String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, "");
|
||||||
|
String[] tordApps;
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer(tordAppString,"|");
|
||||||
|
tordApps = new String[st.countTokens()];
|
||||||
|
int tordIdx = 0;
|
||||||
|
while (st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
tordApps[tordIdx++] = st.nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
Arrays.sort(tordApps);
|
||||||
|
|
||||||
|
//else load the apps up
|
||||||
|
PackageManager pMgr = context.getPackageManager();
|
||||||
|
|
||||||
|
List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0);
|
||||||
|
|
||||||
|
Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator();
|
||||||
|
|
||||||
|
ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>();
|
||||||
|
|
||||||
|
ApplicationInfo aInfo = null;
|
||||||
|
|
||||||
|
int appIdx = 0;
|
||||||
|
TorifiedApp app = null;
|
||||||
|
|
||||||
|
while (itAppInfo.hasNext())
|
||||||
|
{
|
||||||
|
aInfo = itAppInfo.next();
|
||||||
|
|
||||||
|
app = new TorifiedApp();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS);
|
||||||
|
|
||||||
|
if (pInfo != null && pInfo.requestedPermissions != null)
|
||||||
|
{
|
||||||
|
for (String permInfo:pInfo.requestedPermissions)
|
||||||
|
{
|
||||||
|
if (permInfo.equals("android.permission.INTERNET"))
|
||||||
|
{
|
||||||
|
app.setUsesInternet(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1)
|
||||||
|
{
|
||||||
|
//System app
|
||||||
|
app.setUsesInternet(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!app.usesInternet())
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
apps.add(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
app.setEnabled(aInfo.enabled);
|
||||||
|
app.setUid(aInfo.uid);
|
||||||
|
app.setUsername(pMgr.getNameForUid(app.getUid()));
|
||||||
|
app.setProcname(aInfo.processName);
|
||||||
|
app.setPackageName(aInfo.packageName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
app.setName(pMgr.getApplicationLabel(aInfo).toString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
app.setName(aInfo.packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//app.setIcon(pMgr.getApplicationIcon(aInfo));
|
||||||
|
|
||||||
|
// check if this application is allowed
|
||||||
|
if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) {
|
||||||
|
app.setTorified(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
app.setTorified(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
appIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(apps);
|
||||||
|
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
script.append(ipTablesPath);
|
script.append(ipTablesPath);
|
||||||
script.append(" -t filter -m owner --uid-owner ");
|
script.append(" -t filter -m owner --uid-owner ");
|
||||||
|
@ -747,7 +864,115 @@ public class TorTransProxy implements TorServiceConstants {
|
||||||
// fixTransproxyLeak (context);
|
// fixTransproxyLeak (context);
|
||||||
|
|
||||||
return lastExit;
|
return lastExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ArrayList<TorifiedApp> getApps (Context context, SharedPreferences prefs)
|
||||||
|
{
|
||||||
|
|
||||||
|
String tordAppString = prefs.getString(OrbotConstants.PREFS_KEY_TORIFIED, "");
|
||||||
|
String[] tordApps;
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer(tordAppString,"|");
|
||||||
|
tordApps = new String[st.countTokens()];
|
||||||
|
int tordIdx = 0;
|
||||||
|
while (st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
tordApps[tordIdx++] = st.nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
Arrays.sort(tordApps);
|
||||||
|
|
||||||
|
//else load the apps up
|
||||||
|
PackageManager pMgr = context.getPackageManager();
|
||||||
|
|
||||||
|
List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0);
|
||||||
|
|
||||||
|
Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator();
|
||||||
|
|
||||||
|
ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>();
|
||||||
|
|
||||||
|
ApplicationInfo aInfo = null;
|
||||||
|
|
||||||
|
int appIdx = 0;
|
||||||
|
TorifiedApp app = null;
|
||||||
|
|
||||||
|
while (itAppInfo.hasNext())
|
||||||
|
{
|
||||||
|
aInfo = itAppInfo.next();
|
||||||
|
|
||||||
|
app = new TorifiedApp();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS);
|
||||||
|
|
||||||
|
if (pInfo != null && pInfo.requestedPermissions != null)
|
||||||
|
{
|
||||||
|
for (String permInfo:pInfo.requestedPermissions)
|
||||||
|
{
|
||||||
|
if (permInfo.equals("android.permission.INTERNET"))
|
||||||
|
{
|
||||||
|
app.setUsesInternet(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1)
|
||||||
|
{
|
||||||
|
//System app
|
||||||
|
app.setUsesInternet(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!app.usesInternet())
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
apps.add(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
app.setEnabled(aInfo.enabled);
|
||||||
|
app.setUid(aInfo.uid);
|
||||||
|
app.setUsername(pMgr.getNameForUid(app.getUid()));
|
||||||
|
app.setProcname(aInfo.processName);
|
||||||
|
app.setPackageName(aInfo.packageName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
app.setName(pMgr.getApplicationLabel(aInfo).toString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
app.setName(aInfo.packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//app.setIcon(pMgr.getApplicationIcon(aInfo));
|
||||||
|
|
||||||
|
// check if this application is allowed
|
||||||
|
if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) {
|
||||||
|
app.setTorified(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
app.setTorified(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
appIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(apps);
|
||||||
|
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue